Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Low contrast image segmentation

I have problem with low contrast image segmentation. Task is to find surface defects. They are visible (defects are always dark areas) but the contrast of image is very low. Below two samples.

12

I have tried enhance contrast and then tresholding:

Mat tmp1 = imread("C:\\framesRoi\\311.bmp",0);
stretchContrast(tmp1);
threshold(tmp1,tmp1,75,255,THRESH_BINARY);

where stretch contrast impl:

int minValue = 255, maxValue = 0;
const int l = sourceImg.cols * sourceImg.rows * sourceImg.channels();
if(sourceImg.isContinuous())
{
    uchar* ptr = sourceImg.ptr<uchar>(0);
    for(int i = 0; i < l; ++i)
    {
        if(ptr[i] < minValue)
        {
            minValue = ptr[i];
        }
        if(ptr[i] > maxValue)
        {
            maxValue = ptr[i];
        }
    }
}
cout<<"min: "<<minValue<<";"<<"max value: "<<maxValue<<endl;

const int  magicThreshold = 10;
if(sourceImg.isContinuous())
{
    uchar* ptr = sourceImg.ptr<uchar>(0);
    for(int i = 0; i < l; ++i)
    {
        ptr[i] = 255 * (ptr[i]-minValue)/(maxValue - minValue);
    }
}

But this approach failed. There are many false detections and not all defects are detected: 3

Here is zip with test frames: https://dl.dropboxusercontent.com/u/47015140/testFrames.rar

like image 386
krzych Avatar asked Dec 03 '14 21:12

krzych


People also ask

What is low contrast in image processing?

Essentially, what this means is that if less than 35% of the range of brightness occupies the full range of the data type, then the image is considered low contrast. To make this a concrete example, consider that an image in OpenCV is represented by an unsigned 8-bit integer that has a range of values [0, 255].

What is the best image segmentation method?

Edge-based segmentation is one of the most popular implementations of segmentation in image processing. It focuses on identifying the edges of different objects in an image.

How image is segmented based on color?

It can be explained as follows: given a color image I, let us consider the of pixels, where , , and is the th color component in the used color space. The segmentation is defined as an array , , assigning a label to each pixel of the image, indicating if it belongs to the background or the foreground.


2 Answers

Try clustering the image by gray level using a clustering method such as kmeans. Below I've used kmeans directly on the images without any gray level transformations (using 3 clusters gave me better results). You should be able to improve results by clustering a preprocessed image using methods outlined in the comments.

enter image description hereenter image description here

Shape of the clusters may slightly vary due to the randomness of kmeans.

Now if you take connected components of the clustered image and calculate the average gray level of those regions, the defects should have a lower average than the other regions.

I did clustering part in Matlab.

im = imread('r2SOV.png');%Uy1Fq r2SOV
gr = im;
size = size(gr);

% perform closing using a 5x5 circular structuring element
sel = strel('disk', 2, 4);
mcl = imclose(gr, sel);
% cluster gray levels using kmeans: using 3 clusters
x = double(mcl(:));
idx = kmeans(x, 3);
cl = reshape(idx, size);

figure, imshow(label2rgb(cl))
like image 137
dhanushka Avatar answered Oct 18 '22 13:10

dhanushka


As people said in your comment, you can change the brightness in a negative way and push up the contrast.

Moreover, the sharpen filter is also very useful for your case. You can do this in OpenCV.

like image 24
Alto Avatar answered Oct 18 '22 12:10

Alto