Подтвердить что ты не робот

Низкоконтрастная сегментация изображения

У меня проблема с сегментацией с низким контрастом. Задача - найти дефекты поверхности. Они видны (дефекты всегда темные области), но контраст изображения очень низок. Ниже двух образцов.

12

Я попробовал усилить контраст, а затем trsholding:

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

где контрастность растяжения:

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);
    }
}

Но этот подход не удался. Существует много ложных срабатываний, и не все дефекты обнаружены: 3

Вот zip с тестовыми кадрами: https://dl.dropboxusercontent.com/u/47015140/testFrames.rar

4b9b3361

Ответ 1

Попробуйте скопировать изображение на уровень серого с помощью метода кластеризации, такого как kmeans. Ниже я использовал kmeans непосредственно на изображениях без каких-либо преобразований уровня серого (использование 3 кластеров дало мне лучшие результаты). Вы должны иметь возможность улучшить результаты путем кластеризации предварительно обработанного изображения с использованием методов, изложенных в комментариях.

enter image description hereenter image description here

Форма кластеров может незначительно меняться из-за случайности километров.

Теперь, если вы берете связанные компоненты кластерного изображения и вычисляете средний уровень серы в этих регионах, дефекты должны иметь более низкую среднюю, чем другие регионы.

Я сделал кластеризацию в 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))

Ответ 2

Как говорится в вашем комментарии, вы можете изменить яркость негативным образом и увеличить контраст.

Кроме того, sharpen filter также очень полезен для вашего случая. Вы можете сделать этот в OpenCV.

Ответ 3

Я думаю, вы должны попробовать adaptiveThreshold функцию с большим окном.

#include "opencv2/opencv.hpp"
using namespace cv;
int main(int argc,char** argv )
{

    Mat im = imread("c:/data/img1.png",0);
    cv::namedWindow("ctrl");
    int win=62;
    int th=2100;
    cv::createTrackbar( "win", "ctrl", &win, 500);
    cv::createTrackbar( "th", "ctrl", &th, 10000);
    while(true)
    {
        Mat thresh;
        medianBlur(im,thresh,15);//helps smooth out smaller noises, which you could also remove by size instead of this way
        adaptiveThreshold(thresh,thresh,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,win*2+1,(    th/1000.));
        imshow("thresh",thresh);
        if(waitKey(1)==27)
            exit(0);
    }
}

все результаты здесь (http://www.datafilehost.com/d/99e3d86c). Вы также можете взглянуть на imagej, который реализует кучу автопороговых алгоритмов, Я думаю, что вам нужно что-то, что учитывает локальную информацию об изображении.

enter image description hereenter image description here