Interpolate matrix to same size matrix

11 views (last 30 days)
John Yi
John Yi on 27 Oct 2016
Edited: John Yi on 31 Oct 2016
Hello, I have a matrix of mostly zeros
X =
0 0 0 0 0 0 0 0 0 0
0 10 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 7 0 0
0 0 0 0 0 0 0 0 10 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 9 8 0 0 0 0
I'd like to keep the non-zero values, but have them spread out to its neighbors in a gradual fashion. The method I use does not really matter, just as long as it creates a gradual peak in a surf plot. Ideally, I would like to be able to change how gradually it spreads (the sigma in a gaussian filter for example). When I used gaussian filters, the value of the original value changes.
Y =
0.1134 0.8382 0.1134 0 0 0 0 0 0 0
0.8382 6.1935 0.8382 0 0 0 0.0794 0.5867 0.0794 0
0.1134 0.8382 0.1134 0 0 0 0.5867 4.4489 1.4249 0.1134
0 0 0 0 0 0 0.0794 1.4249 6.2729 0.8382
0 0 0 0 0 0 0 0.1134 0.8382 0.1134
0 0 0 0.1021 0.8451 0.7726 0.0907 0 0 0
0 0 0 0.8565 7.0898 6.4818 0.7613 0 0 0
This is essentially what I want, but with the original value remaining the same. I tried also interp2 which works well also but the matrix dimensions change. Please let me know if you have a solution. Thanks a lot!

Answers (3)

Jan
Jan on 27 Oct 2016
Edited: Jan on 27 Oct 2016
You can simply overwrite the non-zero values afterwards:
Y(X ~= 0) = X(X ~= 0);

Jos (10584)
Jos (10584) on 27 Oct 2016
You could simply replace the lower values with the original ones?
A = ... % original matrix with zeros
B = ... smoothed version of A
tf = A~=0 ;
B(tf) = A(tf)
  1 Comment
John Yi
John Yi on 27 Oct 2016
I tried this, but if I overwrite, then the surrounding values are already too small. So in a surf plot, it will look like a very pointy peak and then a gradual decline. I'd like the gradual decline to start from the top.

Sign in to comment.


Image Analyst
Image Analyst on 27 Oct 2016
You can use imresize() or conv2() depending on exactly what you want to do.
  3 Comments
Image Analyst
Image Analyst on 27 Oct 2016
No. You can blur the points with conv2, but this will reduce the center point. If you just replace the center point afterwards, you'll have a big spike on a low blurry hump, like you said. The only way is to blur each region independently and then normalize it. You can find each independent region with bwlabel. So then you'd loop over each region, blurring and normalizing and adding to an accumulation image. Like
[labeledRegions, numRegions] = bwlabel(yourMatrix, 4);
for r = 1 : numRegions
binaryImage = ismember(yourMatrix, r);
thisRegion = binaryImage .* yourMatrix;
% Now blur this region with imgausfilt()
blurredMatrix = imgaussfilt(....You do this...........
% Get the max original value
maxOriginalValue = max(yourMatrix(binaryImage));
% Get the blurred max
maxBlurred = max(blurredMatrix(:));
% Scale it
blurredMatrix = blurredMatrix * maxOriginalValue / maxBlurred;
% Assign it to our final image.
finalImage(binaryImage) = blurredMatrix(binaryImage);
end
This is untested, just off the top of my head so you may need to do debugging.
John Yi
John Yi on 31 Oct 2016
Edited: John Yi on 31 Oct 2016
Thanks a lot for your help. So I played around with it and I've gotten it to work just fine. Values that are next to each other are not scaled correctly, because they are recognized as one region collectively with bwlabel. If you have a solution for this please do let me know!
% %yourMatrix = X (my matrix of values)
finalImage=zeros(7,10);%dimensions of whatever matrix I'm using
[labeledRegions, numRegions] = bwlabel(yourMatrix, 4);
for r = 1 : numRegions
binaryImage = ismember(labeledRegions, r);
thisRegion = binaryImage.*yourMatrix;
% Now blur this region with imgausfilt()
blurredMatrix = imgaussfilt(thisRegion, 7);
% Get the max original value
maxOriginalValue = max(yourMatrix(binaryImage));
% Get the blurred max
maxBlurred = max(blurredMatrix(binaryImage));
% Scale it
blurredMatrix = blurredMatrix * maxOriginalValue / maxBlurred;
% Assign it to our final image. take the average of the values within
% the submatrix and the finalImage
[labeledRegions2, numRegions2] = bwlabel(blurredMatrix, 4);
binaryImage2 = ismember(labeledRegions2, 1);
A = (finalImage(binaryImage2) + blurredMatrix(binaryImage2))/2;
submatrix = reshape(A, max(sum(binaryImage2)), max(sum(binaryImage2')));
finalImage(binaryImage2) = submatrix;
end
before averaging
after averaging
It's not perfect, but It's kind of what I'm going for and my real data will not have so many values on top of each other in any case.
thanks!

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!