Recently I am writing a script to manipulate the pixel values in an image. The idea is to set the pixels that fall into the given range to a specific value. Instead of using the command "for" which loops from pixel to pixel, an image expression was utilized, for example:
Img = (Img>=thresh_Low && Img<=thresh_Up ? 0 : Img)
Here comes the question: if I would like to replace the pixel value with the average of neighbouring pixels, rather than just a fixed value such as 0 in the above case, pixel-looping seems not avoidable anymore. Does anyone know any workaround that the method of image expression can still be used here?
Thanks in advance.
Computing images expressions is much more efficient than any pixel-by-pixel operation. Even if you thereby compute some averages that are not needed will the script perform a lot faster. Therefore:
The following example illustrates this. Only the last two lines are the direct answer to your question. The condition is used to either copy the orignal or the averaged value:
Further explanations because of comments below
The averaging is done by shifting the whole image by one pixel using the
offsetcommand. This command will replace border pixels with the0value. Summing all the shifted images and dividing by the number of images therefore gives at each pixel the average value of the neighbor pixels, but the normalization in the border pixels is incorrect. The following script shows this using explicit images instead of the for-loop:To fix the issue with the borders, two strategies could be used for the normalization.
1-valued image of the same size as the source and perform the same summing steps! This makes the script from above into:Convolution()command, which correctly handles the border cases right away. Here, one would just create the average image as: