fast interp on 1 dimension of 3d matrix
46 views (last 30 days)
Show older comments
- Assume a Matrix A which is (M X N X P) array.
I want to upsample one dimension of the matrix, for example: upsample the third dimension by factor of 2.
Currently I'm using loops to make it happen:
B = zeros(M, N, 2 * P);
for ii = 1 : M
for jj = 1 : N
B(ii, jj, :) = interp(double(A(ii, jj, :)), 2);
end
end
Is there any way to do so which doesn't include any use of loops?
3 Comments
Bruno Luong
on 20 Sep 2023
Edited: Bruno Luong
on 20 Sep 2023
@Stephen23 My comment is directed to your code with linspace, obviously violate the rule of integer upsampling https://en.wikipedia.org/wiki/Upsampling
Expansion: Create a sequence, , comprising the original samples,.
OP does not specify the size, he just allocate (wrongly) the size. He obviously want to use interp with upsampling integer factor
B(ii, jj, :) = interp(double(A(ii, jj, :)), 2)
Accepted Answer
Stephen23
on 18 Dec 2018
Edited: Stephen23
on 18 Dec 2018
Use interp3 or interpn:
>> A = randi(9,5,7,3)
A(:,:,1) =
3 3 5 3 8 1 2
8 7 3 4 9 9 2
3 5 7 8 6 4 9
2 9 1 7 3 6 6
2 5 8 9 7 9 2
A(:,:,2) =
3 6 9 5 3 5 4
6 8 1 6 9 5 8
8 5 5 9 4 2 9
7 6 5 2 7 6 4
8 4 2 6 1 6 4
A(:,:,3) =
5 2 1 9 9 8 1
9 8 5 5 8 8 2
9 6 2 1 8 9 4
5 1 4 9 7 4 2
1 1 4 8 9 8 8
>> S = size(A);
>> Z = interpn(A,1:S(1),1:S(2),1:0.5:S(3)) % halve the step size
Z(:,:,1) =
3.0 3.0 5.0 3.0 8.0 1.0 2.0
8.0 7.0 3.0 4.0 9.0 9.0 2.0
3.0 5.0 7.0 8.0 6.0 4.0 9.0
2.0 9.0 1.0 7.0 3.0 6.0 6.0
2.0 5.0 8.0 9.0 7.0 9.0 2.0
Z(:,:,2) =
3.0 4.5 7.0 4.0 5.5 3.0 3.0
7.0 7.5 2.0 5.0 9.0 7.0 5.0
5.5 5.0 6.0 8.5 5.0 3.0 9.0
4.5 7.5 3.0 4.5 5.0 6.0 5.0
5.0 4.5 5.0 7.5 4.0 7.5 3.0
Z(:,:,3) =
3.0 6.0 9.0 5.0 3.0 5.0 4.0
6.0 8.0 1.0 6.0 9.0 5.0 8.0
8.0 5.0 5.0 9.0 4.0 2.0 9.0
7.0 6.0 5.0 2.0 7.0 6.0 4.0
8.0 4.0 2.0 6.0 1.0 6.0 4.0
Z(:,:,4) =
4.0 4.0 5.0 7.0 6.0 6.5 2.5
7.5 8.0 3.0 5.5 8.5 6.5 5.0
8.5 5.5 3.5 5.0 6.0 5.5 6.5
6.0 3.5 4.5 5.5 7.0 5.0 3.0
4.5 2.5 3.0 7.0 5.0 7.0 6.0
Z(:,:,5) =
5.0 2.0 1.0 9.0 9.0 8.0 1.0
9.0 8.0 5.0 5.0 8.0 8.0 2.0
9.0 6.0 2.0 1.0 8.0 9.0 4.0
5.0 1.0 4.0 9.0 7.0 4.0 2.0
1.0 1.0 4.0 8.0 9.0 8.0 8.0
Generate the required indices either using the colon operator (as shown, e.g. to halve the step size) or linspace (e.g. to double the number of points):
Z = interpn(A,1:S(1),1:S(2),linspace(1,S(3),2*S(3))) % double the number of points
Z(:,:,1) =
3.0 3.0 5.0 3.0 8.0 1.0 2.0
8.0 7.0 3.0 4.0 9.0 9.0 2.0
3.0 5.0 7.0 8.0 6.0 4.0 9.0
2.0 9.0 1.0 7.0 3.0 6.0 6.0
2.0 5.0 8.0 9.0 7.0 9.0 2.0
Z(:,:,2) =
3.0 4.2 6.6 3.8 6.0 2.6 2.8
7.2 7.4 2.2 4.8 9.0 7.4 4.4
5.0 5.0 6.2 8.4 5.2 3.2 9.0
4.0 7.8 2.6 5.0 4.6 6.0 5.2
4.4 4.6 5.6 7.8 4.6 7.8 2.8
Z(:,:,3) =
3.0 5.4 8.2 4.6 4.0 4.2 3.6
6.4 7.8 1.4 5.6 9.0 5.8 6.8
7.0 5.0 5.4 8.8 4.4 2.4 9.0
6.0 6.6 4.2 3.0 6.2 6.0 4.4
6.8 4.2 3.2 6.6 2.2 6.6 3.6
Z(:,:,4) =
3.4 5.2 7.4 5.8 4.2 5.6 3.4
6.6 8.0 1.8 5.8 8.8 5.6 6.8
8.2 5.2 4.4 7.4 4.8 3.4 8.0
6.6 5.0 4.8 3.4 7.0 5.6 3.6
6.6 3.4 2.4 6.4 2.6 6.4 4.8
Z(:,:,5) =
4.2 3.6 4.2 7.4 6.6 6.8 2.2
7.8 8.0 3.4 5.4 8.4 6.8 4.4
8.6 5.6 3.2 4.2 6.4 6.2 6.0
5.8 3.0 4.4 6.2 7.0 4.8 2.8
3.8 2.2 3.2 7.2 5.8 7.2 6.4
Z(:,:,6) =
5.0 2.0 1.0 9.0 9.0 8.0 1.0
9.0 8.0 5.0 5.0 8.0 8.0 2.0
9.0 6.0 2.0 1.0 8.0 9.0 4.0
5.0 1.0 4.0 9.0 7.0 4.0 2.0
1.0 1.0 4.0 8.0 9.0 8.0 8.0
21 Comments
Bruno Luong
on 18 Dec 2018
Edited: Bruno Luong
on 18 Dec 2018
The difference between
Z = interp1(A,linspace(1,S(1),2*S(1)))
and your original INTERP code is that the INTERP1 is not integer-upsampling.
INTERP do integer upsampling and must extrapolate on the right side with (q-1) points where q is up-sampling factor (2 in your example).
It carried out but padding one 0 and filter the padded data, so the extrapolation signal dies out on the right side and can introduce some oscilation.
The difference, though subtle, might be important or not depending on your ultimate goal.
More Answers (3)
Bruno Luong
on 18 Dec 2018
Edited: Bruno Luong
on 18 Dec 2018
[m,n,p] = size(A);
B = reshape(A,[m*n p]).';
Br = resample(B,2,1); % 2 is upsampling factor
Ar = reshape(Br.',m,n,[]);
0 Comments
Matt J
on 18 Dec 2018
B = imresizen(A,[1,1,2]);
3 Comments
Matt J
on 18 Dec 2018
By default, it uses linear interpolation, but you can specify any interpolation method that griddedInterpolant implements, e.g.,
B = imresizen(A,[1,1,2],'pchip');
See Also
Categories
Find more on Interpolation of 2-D Selections in 3-D Grids in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!