Image processing - pixel comparison
Afficher commentaires plus anciens
Suppose there is a 5X5 filter window to traverse a image with zero padding.
My Question:
I'm trying to compare all the pixels in row-1 in 1 iteration. If pixels in 1st row are all similar, then RC for row-1 is 1.
similarly, for row-2, comparing pixels in 2nd row. If similar, then RC for that row-2 is 1.
Can anyone suggest some methodology/approach for this implement?
Even if not in one iteration, some other approach?
3 commentaires
Image Analyst
le 1 Mai 2021
What does "similar" mean to you? How similar? Perfect equality? Some value within a certain tolerance of each pixel? Did you try movmin() and movmax() to get the min and max within the window?
Archit Sethi
le 1 Mai 2021
Archit Sethi
le 2 Mai 2021
Réponses (2)
Image Analyst
le 2 Mai 2021
1 vote
For what it's worth, see my attached modified median filter demo.
1 commentaire
Archit Sethi
le 3 Mai 2021
The filter you describe doesn't make use of its height. If it's only evaluating each row within the window independently, it's a 1-D filter and only needs to be 1x5.
It's unclear what type of image you're working with. If we assume this is a binary image, then the answer is simple:
% read a test image and clean it up
inpict = im2double(imread('circles.png'));
inpict = inpict>0.1; % make it logical
anytrue = imdilate(inpict,ones(1,5));
anyfalse = imdilate(~inpict,ones(1,5));
outpict = xor(anytrue,anyfalse);

If you want to do this for a grayscale or color image, you're going to have to define some tolerance and test for equality within said tolerance. You may be able to use rangefilt() for grayscale inputs.
inpict = im2double(imread('cameraman.tif'));
inpict = medfilt2(inpict,[3 3]); % clean it up a bit
tol = 0.03;
rangemap = rangefilt(inpict,ones(1,5));
outpict = rangemap<tol;

For RGB inputs, you could use rangefilt() to generate range maps, test against the tolerance to get three logical maps, then logically combine them.
5 commentaires
Archit Sethi
le 1 Mai 2021
Archit Sethi
le 1 Mai 2021
You can do it in uint8. You'd just set your threshold accordingly.
The filter you describe in your comment to Image Analyst is certainly a 5x5 filter, but it has two outputs and doesn't really match my example. I don't see an easy way to make use of existing filter tools like rangefilt() for this.
You may be able to use nlfilter() to do it, though in my experience, it's usually significantly faster to just write a sliding window filter in m-code (believe it or not).
Archit Sethi
le 1 Mai 2021
This example uses nlfilter():
inpict = rgb2gray(imread('sources/lena.tif'));
rowpict = nlfilter(inpict,[5 5],@rowfilt);
colpict = nlfilter(inpict,[5 5],@colfilt);
imshow(cat(1,rowpict,colpict))
function out = rowfilt(in)
tol = 16;
out = all(range(in,2)<tol);
end
function out = colfilt(in)
tol = 16;
out = all(range(in,1)<tol);
end
I'm not really sure what should be done with the two outputs at this point. Either way, that's how nlfilter() can be used.
This is the same thing using a simple sliding window written with loops:
inpict = rgb2gray(imread('sources/lena.tif'));
filtsize = [5 5];
tol = 16;
s0 = size(inpict);
padsize = floor(filtsize/2);
% nlfilter() uses zero-padding, but you could replicate, etc
inpict = padarray(inpict,padsize,0,'both');
s = size(inpict);
rowpict = false(s0);
colpict = false(s0);
osm = filtsize(1)-1;
osn = filtsize(2)-1;
for n = 1:(s(2)-2*padsize(2))
for m = 1:(s(1)-2*padsize(1))
sample = inpict(m:(m+osm),n:(n+osn));
rowpict(m,n) = all(range(sample,2)<tol);
colpict(m,n) = all(range(sample,1)<tol);
end
end
imshow(cat(1,rowpict,colpict))
As much as everyone rags on writing things with loops, this is still ~3x as fast as using nlfilter()
Catégories
En savoir plus sur Image Filtering dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!