How to find image haze in MATLAB?

I want to calculate the haze of an image for each block. This is done by finding the value for the dark channel, which is used to represent the degree of turbidity. This concept is taken from Kaiming He's doc on Single Image Removal Using Dark Do Channel .

The dark channel value for each block is determined as follows:

where I^c (x',y')

denotes the intensity at the pixel location (x',y')

in the color channel c

(one of the red, green, or blue color channel), and omega(x,y)

denotes the neighborhood of the pixel location (x',y')

,

I'm not sure how to translate this equation in MATLAB?

+3


source to share


2 answers


If I understand correctly what this equation poses, you are essentially extracting pixelblocks centered at each (x,y)

in the image, you are determining the minimum value in that pixelblock for the red, green, and blue channels. This results in 3 values, where each value is the minimum in the pixelblock for each channel. Of these 3 values, you choose the least of them, and this is the final result for the location (x,y)

in the image.

We can do this very easily with ordfilt2

. What it does ordfilt2

is that it applies the statistics filter in order to your image. You tell the mask which pixels should be analyzed in your area, it collects these neighboring pixels that are considered valid and sorts their intensities. Then you choose the pixel rank you want at the end. Lower rank means lower value, while higher rank means more value. In our case, the mask will be set to all booleans true

and is the size of the neighborhood that you want to analyze. Since you want the minimum, you should choose a rank 1 result.

You will apply this to each red, green, and blue channel, then for each spatial location, choose the minimum of three. So, assuming your image was saved in im

, and you wanted to apply an image to it m x n

, do something like this:

%// Find minimum intensity for each location for each channel
out_red = ordfilt2(im(:,:,1), 1, true(m, n));
out_green = ordfilt2(im(:,:,2), 1, true(m, n));
out_blue = ordfilt2(im(:,:,3), 1, true(m, n));

%// Create a new colour image that has these all stacked
out = cat(3, out_red, out_green, out_blue);

%// Find dark channel image
out_dark = min(out, [], 3);

      

out_dark

will contain the dark channel image you desire. The key to figuring out what you want is in the last two lines of code. out

contains the minimum values ​​for each spatial location in the red, green, and blue channels, all of which are combined in the third dimension to create a 3D matrix . After that I apply the operation min

and look at the third dimension to finally select which of the red, green and blue channels for each pixel location will give the output value.

In the example, if I use onion.png

that is part of the MATLAB system path, and specify a 5 x 5 neighborhood (or m = 5, n = 5

), this is what the original image looks like, as well as the dark channel the result:

enter image description here



enter image description here


Sidenote

If you're an image processing purist, finding the minimum value for pixel neighborhoods in a grayscale image is like finding grayscale morphological erosion . You can treat each red, green, or blue channel as its own grayscale image. So we could just replace ordfilt2

with imerode

and use the rectangle structuring element to create the pixel neighborhood that you want to use to apply to your image. You can do this via strel

MATLAB and specify a flag 'rectangle'

.

So the equivalent code using morphology would be:

%// Find minimum intensity for each location for each channel
se = strel('rectangle', [m n]);
out_red = imerode(im(:,:,1), se);
out_green = imerode(im(:,:,2), se);
out_blue = imerode(im(:,:,3), se);

%// Create a new colour image that has these all stacked
out = cat(3, out_red, out_green, out_blue);

%// Find dark channel image
out_dark = min(out, [], 3);

      

You should get the same results as using ordfilt2

. I haven't done any tests, but I highly suspect using imerode

is faster than using ordfilt2

... at least on higher resolution images. MATLAB has highly optimized morphology routines and is specifically for images, whereas it is ordfilt2

designed for more general 2D signals.

+8


source


Or you can use the Visibility Index to see how hazy the image is. It turns out that someone wrote nice code for it . The lower the metric, the higher the haze in the image.



This metric can also be used as a pre-processor to automatically tune debase parameters.

+1


source







All Articles