不同材质的图像分割问题


15

嗨,简历/模式识别社区,

关于图像的分割,我遇到了一个严重的问题。场景是炉子里的气氛,使我发疯。而且我需要在短时间内(<10秒)而不是仅在一种特殊情况下检测不同材料(玻璃,陶瓷,Al,Ir ...)的物体轮廓。我还需要代码的连续像素行中的轮廓。因此,还需要使用链代码或所谓的边界/轮廓跟随,因此开孔不好。在背景中会不时出现非线性噪声,大约是灰尘,颗粒或其他一些东西。

欢迎使用Matlab或OpenCV建议。

为了更加清楚,我发布了目标的另一个图像和一个半透明的对象,还需要对其进行检测。还需要注意其他示例。 例子1 例子2 例子3 例子4

正如您在图像#1中看到的那样,图像的右侧部分和恒星的外轮廓附近(即物体)存在粒子。而且总体对比度不是很好。对象本身位于地下,与轮廓检测无关。图像#2显示了半透明的物体,这也是可能的。

我想找到该物体的轮廓/周长,就像在下一个屏幕(红线)上一样。两个矩形(黄色)标记了起点(左侧)和终点(右侧)。蓝线是可忽略的。 例子2

起初我以为我可以只用过滤器解决那种肮脏的气氛。但是经过大量的投入时间,我才意识到,为了提高前景和背景的对比度,我必须大幅度消除或减少噪音。我尝试了很多方法,例如直方图均衡,自适应Otsu均衡,线性滤波器(例如高斯),非线性滤波器(中值,扩散),活动轮廓,k均值,Fuzzy-c-means以及纯Canny边缘检测结合形态运算符。

  • 坎尼:粒子和大气正在造成孔洞,但是我需要物体的完整轮廓。仍然以形态算子的闭合,扩张还不够好。由于滞后作用,Canny仍然是我研究过的所有方法中最好的结果。
  • 活动轮廓线:它们也可以在边缘/渐变上工作,在对象内部初始化后它们的行为完全疯狂,这可能是由于边缘贴图导致“开放”对象引起的。据我所知,轮廓必须闭合。尝试了不同的衍生产品(GVF / VFC /经典蛇)。
  • k均值:由于有雾的背景,结果包括炉内气氛。对于模糊C均值也是如此。由于将对象与背景分离,我选择了两个群集。簇越多,结果越弱。
  • 直方图/ Otsu:由于灰度强度非常接近(恕我直言!),它会将对象与背景合并。尝试使用本地和全局方法。
  • 滤镜:尤其是GLPF或其他LPF会弄脏边缘,效果不是很好,甚至不会减少有雾的气氛。
  • 非线性滤镜保留边缘。它们中的大多数都花很长时间计算大图像。现在使用快速双边过滤器。结果见下文。

因此,没有一种方法足以满足后处理步骤的需要,因为对象段的获得结果与现有算法的竞争性较差。该现有算法非常本地化,因此适用于这种非常特殊的情况。

所以我问你,如果我完全错过了什么...我不知道如何加工以及如何获得良好的轮廓结果而又没有间隙或孔。 CCD和物理环境?提前致谢!

到目前为止的最后一种方法(经过一整夜的MO实验):

  • 双边过滤器(保留边缘,但平滑均匀区域)
  • Canny(Sigma = 2,Threshold = [0.04 0.08])
  • 形态运算(MO): bwareopenclosingremovebridge
  • bwlabel仅选择轮廓的周长,以消除不必要的噪音。尚无更新的屏幕截图,但适用于明星。玻璃杯有一个与外部轮廓相连的内部轮廓,也可以在下面的屏幕截图中看到。

因此,恐怕我需要一种特殊的算法来遍历外部轮廓。这将是对邻居的一些顺时针/逆时针查找。如果存在拐角,则可以切换顺时针/逆时针的步骤。如果有间隙,请增加半径并再次查看。如果存在以下两个或两个以上的观点,请选择与前一个观点相同的观点。您认为轮廓跟随算法有意义吗?

玻璃边缘 星


您是否尝试过自适应阈值?您似乎没有提到它。我认为OTSU在消除噪声后应该可以以某种方式工作,但自适应阈值可能更好。
Rui Marques 2012年

嗨,瑞,我尝试使用此Matlab扩展进行自适应阈值处理:自适应阈值下面是使用窗口参数的结果:第1 次尝试 2次尝试第3次尝试如您所见,随着参数的增加,中间部分从白色变为黑色(很好,恕我直言),但背景的其余部分也变成了黑色,这是不好的。
mchlfchr 2012年

3
您是否尝试过一些基本的图像缩小技术?例如减去一个平场校正以消除右上角的变暗现象(en.wikipedia.org/wiki/Flat-field_correction)。同样,如果粒子是静态的,它们将立即被移除。然后,您可以使用任何想要的边缘检测方法...
PhilMacKay 2012年

嗨,菲尔,据我所知,据我所知,有一系列照片是在物体进入熔炉之前拍摄的。因此这里是校准的一种。我星期一将与负责CCD和环境的物理学家交谈。但是,感谢您的建议,我会尝试一下!
mchlfchr 2012年

您添加的第二张图片看起来完全不同。您可以发布所有可能的图片吗?
Andrey Rubshtein 2012年

Answers:


2

您可以尝试以下方法:


嗨,奥利,关于稀疏方法:您能具体说明我应该使用该代码的哪些方法吗?我对该部分的了解不是很深,我在文档中没有找到有关降噪或模糊的有用信息……谢谢。
mchlfchr

1
你可以找到一个“易于使用”的版本,有:lear.inrialpes.fr/people/mairal/denoise_ICCV09.tar.gz
OLI

抱歉再次抱怨;-) ...您也有win32源码吗?再次感谢你!
mchlfchr 2012年

我很害怕我不……
oli

2

我认为您太早放弃了阈值技术。看看您的直方图,它显然是三峰的:( 我手动删除了图像右侧的白列,我认为它们不属于图像的一部分-请在运行代码之前获取此图像

在此处输入图片说明

看一下第一组中的所有值:

在此处输入图片说明

为了找到在三峰直方图模式,可以使用K-means聚类K=3上强度。以下Matlab代码可找到th1=67在您的代码上。这个想法是假设您有3组,并在每组上计算加权质心。然后,将每个强度级别分配给它自己的群集。当加权质心停止移动时,您将停止。这是在图像上找到两个阈值的结果,如直方图所示。

在此处输入图片说明

function [th1,th2]=SegmentHistTo3()
    im = imread('http://i.stack.imgur.com/U2sc5.png');
    h = imhist(im(:,:,1)); %# Calculate histogram

    th1new = round(256/3); %# Initial thresholds
    th2new = round(256*2/3);
    th1 = 0;
    th2 = 0;

    while (th1~=th1new) || (th2~=th2new) %# While the centroids keep on moving
        th1 = th1new;
        th2 = th2new;

        wa1 = WeightedAverage(h,1,th1);  %# Calculate 3 weighted averages
        wa2 = WeightedAverage(h,th1+1,th2);
        wa3 = WeightedAverage(h,th2,numel(h));

        th1new = round( (wa1+wa2)/2 );  %# The thresholds are middle points between the averages
        th2new = round( (wa2+wa3)/2 );
    end

    figure; hist( double( reshape(im(:,:,1),1,[]) ),256);
    hold on;
    plot( [th1 th1],[0 max(h)],'r','LineWidth',2);
    plot( [th2 th2],[0 max(h)],'r','LineWidth',2);

    figure;imshow( im(:,:,1)<th1);
end

function wa = WeightedAverage(region,th1,th2)    
    regionNonEmpty(th1:th2) = region(th1:th2);
    wa = sum( regionNonEmpty .* (1:numel(regionNonEmpty))) / sum(regionNonEmpty);    
end

之后解决问题是小菜一碟,只需执行一些简单的形态操作即可,例如打开。


1
嗨,安德烈,但是我应该如何概括您提到的阈值?我得到了几种情况,不仅是一种情况,我仍然需要自动化。而且Otsu Thresholding(在matlab中起作用)没有给我带来很好的效果。还有其他提示吗?亲切的问候
mchlfchr 2012年

再次嗨,谢谢,到目前为止,但是代码不起作用。出现空白图形屏幕。使用我的原始数据(位图)和您上面发布的PNG进行了尝试。同时我正在调试...
mchlfchr 2012年

@mchlfchr,您有图像处理工具箱吗?如果您不这样做,则可以更改imhisthist
Andrey Rubshtein 2012年

@mchlfchr,请查看更新的版本
Andrey Rubshtein 2012年

Andrey,如果我插入原始位图文件,结果将与我在原始帖子中提到的一样。关于分辨率可能正在发生这种情况吗?源图像为576x768像素和灰度(256)。如果我将您的函数与原始图像一起使用,则结果如下:i.imgur.com/UXALJ.png函数的直方图-i.imgur.com/7RiPP.png感谢您的帮助!问候
mchlfchr 2012年

1

如以上所建议的,阈值处理对于该图像是非常有效的,该图像基本上是二进制的,除了恒定的阈值不会因为照明不均匀而起作用。您需要自适应阈值。

我的建议是通过在明亮区域中采样少量值,使用简单模型(可能是平面[3 DOF]或四半径[6 DOF])进行背景重建。最好是使用较小的ROI来平均掉噪声。然后通过减去(或除以)背景值来校正阴影。

如果不能进行人机交互,则可以通过先直接进行Otsu并考虑均匀地位于阈值以下的ROI(低方差)来自动搜索背景区域。在第一次背景重建之后,您可以通过将此过程应用于经过平面校正的图像来进行改进。

整个过程可以在不到一秒的时间内执行完。


您好Yves,首选自动处理。DOF方面很有趣,但是我不确定Otsu方法,因为Otsu本身运行不佳。我是否想正确地选择图像的随机区域,然后对所有拾取区域的平均值求阈值?亲切的问候
mchlfchr 2012年

1

我认为最好的方法是使用活动轮廓。如果您不清楚活动轮廓是什么,请在youtube http://www.youtube.com/watch?v=ijNe7f3QVdA上观看此视频

基本上,您需要进行初始化分割,这将改善形状。我的建议是针对本文中讨论的一种方法,并使用主动轮廓作为第二步,即。作为改进步骤。

这是活动轮廓的实现,您可以使用 http://www.mathworks.com/matlabcentral/fileexchange/19567


欢迎使用dsp.se :)感谢您的贡献,您提供了一个不错的答案。如果您想使它变得更好,我想为以下一些问题提供答案会很有趣:为什么您认为这是最好的方法(例如,您在使用技术方面有个人经验)?您认为哪些建议的方法与您的建议结合使用会很好?请对该技术进行简短说明,或者,如果您有时间,请在提供的示例图像上尝试使用该技术提供实验结果。并在dsp上玩得开心!
penelope 2012年

@mkuse,您可能已读过初始文章,所以我已经尝试了主动轮廓,并结合了降噪和边缘贴图。结果很差,并且对于大图像来说运行时间很差。
mchlfchr 2012年

您如何看待降噪技术。:你可以在这里找到这些摘要lnmiitdip.files.wordpress.com/2011/12/...
mkuse

1
@mkuse,我已经在最初的帖子中提到了您在PPT文件中发布的机制。为了更清楚地说明,我编辑了最初的帖子,使用了哪种过滤器。
mchlfchr 2012年

0

您清楚地知道自己要做什么,但是您没有提到使用阈值,特别是您是否尝试过使用Otsu应用全局阈值来计算正确的水平,然后找到轮廓并选择最大的?

[编辑以澄清]

全局阈值显然由于图像上可见的纹理而无法工作。

我快速浏览了一下,发现如果将图像分成6个块(2行,每列3列,大小相等),然后对每个图像使用Otsu进行阈值处理,然后重新组装,则在清理图像方面做得很出色图片。

在恒星的右上方仍然有一些较小的伪影。

在我看来,由于对象具有直线边界,您可能需要考虑使用Hough变换来提取这些边缘,将它们相交以定位顶点,然后将结果用作对象轮廓。


嗨,戴夫(Dave),我尝试了大津(Otsu),但它带来的效果是右上层背景与对象合并在一起,这是绝对不能接受的。
mchlfchr 2012年

嗨,Dave,Hough不是一个选择,因为运行时要求,据我对HT的了解,它对于大型图像非常耗时。
mchlfchr 2012年

0

轮廓线总是直线还是已知曲线?

如果是这样,那么我将尝试使用霍夫变换来获得线的方程式,然后从线和itersections重新创建countours,而不是尝试使边缘上的每个像素都正确


1
正如我已经提到的:我需要附近的实时方法。据我所知,HT非常耗时。另一方面是,我不知道曲线和直线并不总是直线。轮廓取决于炉子中的材料(更多信息,请参见我的原产地)。
mchlfchr 2012年

对于直线来说,速度非常快,如果您大致知道直线的位置(例如,从前一帧开始),则只能搜索该参数空间
Martin Beckett 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.