【问题标题】:Low contrast image segmentation低对比度图像分割
【发布时间】:2015-02-01 14:46:56
【问题描述】:

我遇到了低对比度图像分割的问题。 任务是发现表面缺陷。它们是可见的(缺陷总是暗区),但图像的对比度非常低。 下面是两个示例。

我尝试过增强对比度,然后设置阈值:

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

其中拉伸对比 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);
    }
}

但是这种方法失败了。有许多错误检测,并非所有缺陷都被检测到:

这里是带有测试帧的 zip:https://dl.dropboxusercontent.com/u/47015140/testFrames.rar

【问题讨论】:

  • 当您根据图像内容进行对比度拉伸时,您会失去选择有用阈值所需的上下文。
  • @MarkRansom : 那我该怎么做呢?
  • 如果你知道缺陷总是很暗,你可以在不改变对比度的情况下调整亮度,使亮区保持一致。您可以使用最大值来做到这一点,尽管使用 90% 左右的百分位数会不太容易受到噪音的影响。
  • 简单的加法/减法。
  • 您是否尝试过其他对比度增强技术?伽马校正呢?直方图均衡化?

标签: c++ opencv image-processing computer-vision


【解决方案1】:

尝试使用 kmeans 等聚类方法按灰度级对图像进行聚类。下面我直接在图像上使用了 kmeans,没有任何灰度转换(使用 3 个集群给了我更好的结果)。您应该能够通过使用 cmets 中概述的方法对预处理图像进行聚类来改进结果。

由于 kmeans 的随机性,簇的形状可能略有不同。

现在,如果您获取聚类图像的连通分量并计算这些区域的平均灰度级,则缺陷的平均值应该低于其他区域。

我在 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 中做this

【讨论】:

    【解决方案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。我认为您需要的是考虑到本地图像信息的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      相关资源
      最近更新 更多