Effacer les filtres
Effacer les filtres

Is there a variant of nlfilter for color images?

4 vues (au cours des 30 derniers jours)
Przemyslaw
Przemyslaw le 6 Déc 2023
Commenté : DGM le 12 Août 2024 à 13:11
I need to perform quite a complex operation on color image using sliding window way. Is there any variant for RGB images?

Réponse acceptée

DGM
DGM le 6 Déc 2023
Modifié(e) : DGM le 6 Déc 2023
No, there's not. As far as I'm concerned, nlfilter() is usually not worth using. It's slow, it's crippled by its lack of edge handling options and RGB support. The stupid waitbar dialog makes it unusable in the forum and elsewhere and only wastes extra time.
Nlfilter() is a convenience with compromises for when you just need to write a quick and dirty filter that you're never going to use again. If you need it more than once, just write the filter routine yourself. It can easily be more capable, and while it may still be slow, it will typically be (a bit) faster than nlfilter().
% read the image
inpict = imread('peppers.png');
% parameters
windowsize = [5 5]; % or whatever size
% pad the image to mitigate edge effects
padsize = floor(windowsize/2);
paddedimage = padarray(inpict,padsize,'replicate','both');
% process the image
s0 = size(inpict);
outpict = zeros(s0,class(inpict));
os = windowsize-1;
for m = 1:s0(1)
for n = 1:s0(2)
% you have access to all three channels here
sample = paddedimage(m:(m+os(1)),n:(n+os(2)),:); % extract this window
outpict(m,n,:) = median(sample,1:2); % apply whatever function
end
end
% show the result
imshow(outpict)
Depending on what the applied function is, you may want to use im2double() on the image prior to processing.
Maybe this is something I should add to MIMT, but it's hard to make something that's both simple and well-generalized. Ultimately, the flexible solution that covers all cases is to just write the filter routine as needed.
  1 commentaire
DGM
DGM le 12 Août 2024 à 13:11
For comparison, this is the same thing using nlfilter().
% read the image
inpict = imread('peppers.png');
% parameters
windowsize = [5 5]; % or whatever size
% pad the image to mitigate edge effects
% we still need to do this because nlfilter() can't
% do anything other than zero-padding
padsize = floor(windowsize/2);
paddedimage = padarray(inpict,padsize,'replicate','both');
% process the image
s0 = size(paddedimage,1:3);
outpict = zeros(s0,class(inpict));
F = @(x) median(x,1:2); % the applied function
for c = 1:sz0(3) % loop through channels
outpict(:,:,c) = nlfilter(paddedimage(:,:,c),windowsize,F);
end
% the explicit padding needs to be cropped
outpict = outpict(padsize(1)+1:end-padsize(1),padsize(2)+1:end-padsize(2),:);
% show the result
imshow(outpict)
Note that in order to work around the limitations of nlfilter(), we still need to pad it as before, letting nlfilter() add yet another redundant layer of zero padding on top of that. Consequently, we're internally operating on a larger image than is necessary.
As I mentioned, since this example uses nlfilter(), it can't be run on the forum. On my computer, and on MATLAB online, this example requires slightly more than 3x as much time to produce the exact same result as the manual example above. (8s/2.2s, or 26s/7.5s)

Connectez-vous pour commenter.

Plus de réponses (1)

Image Analyst
Image Analyst le 6 Déc 2023
You can use imsplit and then operate on each individual color channel. Or you could transform to LAB color space and operate only on the L channel, or you could transform to HSV color space and operate on the V channel. rgb2lab rgb2hsv
What exactly do you want to do to the image?
  2 commentaires
Przemyslaw
Przemyslaw le 6 Déc 2023
Unfortunately I need access to all the color channels as input. Then combine them in a way involving all three channels and output is also three valued vector for every pixel.
For now I think I will rework orignal matlab function to make it rgb compatible..
Image Analyst
Image Analyst le 6 Déc 2023
Why do you say "unfortunately" as if I said something wrong? You can get all the color channels like this:
[R, G, B] = imsplit(rgbImage);
You have access to them. Now do something with R, G, and B and then "combine" as you said. Maybe you combine them in some weighted fashion, or maybe you just use cat
rgbImage2 = cat(3, R, G, B);
But it depends on what you want to do as to whether tha makes sense. For example if you want to do contract enhancement, you would not want to do it on each channel independently because that would change colors. You'd want to convert to another color space and do it on the L or V channel, then convert back to RGB. For other things you might be able to stay in the RGB color space.
But you're being mysterious about exactly what you want to do so I can't give advice on your approach.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by