Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Region with different brightness

I have an image divided in different regions similar to each other, but one of them has a different brightness, and I have to find out which of these regions have different brightness.

I'm using OpenCV library in my C++ program. I converted my image from RGB to HSV space colour. Then I measured a global mean for each region, but it doesn't seem to be so robust as I thought.

The following image shows an example:

Any suggestion?

like image 473
user5780012 Avatar asked Mar 13 '23 15:03

user5780012


2 Answers

Sorry, the answer is using Matlab, but the approach should be easy to implement in C++.

Estimate Luminance Channel and normalize between 0 and 1, you can use gray channel, saturation channel from HSV, or anything that can represent brightness:

L = mat2gray(mean(image, 3));

Luminance Channel

Apply a Median Filter to remove noise and the black artifacts from your image:

L_blur = medfilt2(L, [10 10]);

Median Filter

Calculate Threshold Value Using Otsu's Thresholding and apply to the image. This will make possible splitting your histogram in two parts separating the brighter and darker area:

mask = L_blur > graythresh(L_blur);

Binary Mask

Then use the generated binary mask to segment the image using a simple element wise multiplication:

output = uint8(repmat(mask, [1 1 3])) .* image;

Final Output

That's it.

like image 98
Eliezer Bernart Avatar answered Mar 23 '23 04:03

Eliezer Bernart


This is the port in OpenCV of the great answer of @Eliezer, just for completeness.

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
    Mat3b img = imread("path_to_image");

    // Estimate Luminance Channel

    Mat1b L(img.rows, img.cols, uchar(0));
    for (int r = 0; r < img.rows; ++r)
    {
        for (int c = 0; c < img.cols; ++c)
        {
            Vec3b v = img(r,c);
            L(r, c) = saturate_cast<uchar>((float(v[0]) + float(v[1]) + float(v[2])) / 3.f);
        }
    }

    // Apply a Median Filter
    Mat1b L_blur;
    medianBlur(L, L_blur, 11);

    // Use OTSU threshold
    Mat1b mask;
    threshold(L_blur, mask, 0, 255, THRESH_BINARY | THRESH_OTSU);

    // Segment image
    Mat3b output(img.rows, img.cols, Vec3b(0,0,0));
    img.copyTo(output, mask);


    imshow("Result", output);
    waitKey();

    return 0;
}

Result:

enter image description here

like image 38
Miki Avatar answered Mar 23 '23 04:03

Miki