Take average of the nearest n pixels

조회 수: 14 (최근 30일)
Mike Rovan
Mike Rovan 2019년 10월 28일
댓글: Mike Rovan 2019년 10월 31일
I have a 512x512x100 matrix of an image. I want to replace every pixel in a certaint section of that matrix (i have a seperate 512x512x100 mask of that section to know the location) to become the average of the nearest n pixels which are not in that section. The mask of the section is different in each of the 100 images.
Thanks
  댓글 수: 3
Mike Rovan
Mike Rovan 2019년 10월 29일
I want to average the nearest n 2D neighbors in the same slice seperately for each of the 100 slices
Image Analyst
Image Analyst 2019년 10월 30일
What is n = 2? Which 2 of the 4 closest neighbors do you pick?
So what you need to do is to make up a circular mask for each radius using strel('disk', r, 0) and note how many pixels are in that mask. Then pick the next largest n. So for a radius of 1, if you don't include the pixel itself, if you picked n=3, you can't get that (unless you somehow pick 3 out of the 4) but you can get 4. You can make up a look up table of n vs radius, or just loop until the number of pixels is equal to greater than your desired n.
Then just call conv2() on each slice with that kernel. Trivial, but let us know if you can't figure it out.

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2019년 10월 28일
If you have the Statistics Toolbox, you could use knnsearch,
  댓글 수: 8
Matt J
Matt J 2019년 10월 31일
편집: Matt J 2019년 10월 31일
Because the averaging requested by the OP is not shift-invariant. For every target pixel inside a non-sliding mask, he wants the average of its n nearest neighbors outside the mask. Depending on the shape of the mask and the position of the target pixel relative to its boundaries, those n pixels can form a very weird, shift-variant set.
Mike Rovan
Mike Rovan 2019년 10월 31일
Matt, thank you for mentioning this. Yes I realized that and tweaked the code to convert the 3D matrix to a cell array of the size of the 3rd dimension and performed what you mentioned individually through a for loop. Thanks.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Image Analyst
Image Analyst 2019년 10월 29일
That is called "masking".
% Get the mean value not in the "section" (i.e., mask which is a logical image)
meanValue = array3d(~mask);
% Replace values in the section with the mean value outside the section:
array3d(mask) = meanValue;
  댓글 수: 2
Mike Rovan
Mike Rovan 2019년 10월 29일
Thanks for answering! I don't think this would quite work for my situation though. Lets look at a single 512x512 slice instead of the 3D image. Using meanValue = array3d(~mask); creates a 262088x1 array. If I were to take the mean value of all those values, it would result in a constant value in the mask area after using array3d(mask) = meanValue; I wanted to however replace every value in the mask area seperately to the value of the average of the nearest 2 pixels which are outside the mask area. So it would have to loop through every pixel in the mask area, find the nearest 2 non-mask area pixels, take its mean and replace that pixel in the mask area with that value. And just to add, the mask is also a 512x512. Your help would be much appreciated!
Image Analyst
Image Analyst 2019년 10월 29일
When you said you "have a seperate 512x512x100 mask of that section" I thought you had a 3-D mask the same size as your image where the mask was true inside the "section" (what everybody else calls "mask").
Does your mask actually move with the pixel, like it's a 5-by-5-by-5 volumetric mask centered about the pixel of interest but taking a "shell" of pixels with a thickness of 2 pixels, and having some radius, and the mask marches along so that it visits every pixel in the image? If so, you can make a small kernel, like the 5x5x5 mask or whatever, and use convn() to get the local average at each pixel. Is that what you want to do?

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

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

Start Hunting!

Translated by