matlab中图像的自主缝检测

时间:2016-12-19 11:50:32

标签: matlab image-processing computational-geometry image-segmentation

我正在尝试检测焊接图像中的接缝以进行自动焊接过程。 enter image description here 我想在原始图像中找到检测到的线条(所需图像中的红线)的像素位置。

我使用了以下代码,最后从图像中删除了噪音,以达到下面的结果。

clc,clear,clf;
im = imread('https://i.stack.imgur.com/UJcKA.png');
imshow(im);title('Original image'); pause(0.5);
sim = edge(im, 'sobel');
imshow(sim);title('after Sobel'); pause(0.5);
mask = im > 5;
se = strel('square', 5);
mask_s = imerode(mask, se);
mask(mask_s) = false;
mask = imdilate(mask, se);
sim(mask) = false;
imshow(sim);title('after mask');pause(0.5);
sim= medfilt2(sim);
imshow(sim);title('after noise removal')

enter image description here

不幸的是,图像中没有任何东西能够完美地找到接缝。

任何帮助都将不胜感激。

Download原始图片。

2 个答案:

答案 0 :(得分:3)

您需要使滤镜对噪音更具鲁棒性。这可以通过给予它更大的支持来实现:

filter = [ones(2,9);zeros(1,9);-ones(2,9)];
msk = imerode(im > 0, ones(11));  % only object pixels, discarding BG
fim =imfilter(im,filter); 
robust = bwmorph((fim>0.75).*msk,'skel',inf); % get only strong pixels

健壮的面具看起来像:

enter image description here

正如您所看到的,接缝线被很好地检测到,我们只需将其选为最大的连接组件:

st = regionprops(bwlabel(robust,8), 'Area', 'PixelList');
[ma mxi] = max([st.Area]); % select the region with the largest area

现在我们可以将一个多边形(第二度)拟合到似乎:

pp=polyfit(st(mxi).PixelList(:,1), st(mxi).PixelList(:,2), 2);

这就是图像:

imshow(im, 'border','tight');hold on;
xx=1:size(im,2);plot(xx,polyval(pp,xx)+2,'r');

enter image description here

请注意由于滤镜宽度导致的+2 Y偏移。

PS,
您可能会发现this thread相关。

答案 1 :(得分:3)

Shai给出了一个很好的答案,但我想补充一点关于为什么你的噪音过滤不起作用的背景。

为什么中值过滤不起作用

Wikipedia表明中值滤波会在保留边缘的同时消除噪音,这就是您可能选择使用它的原因。但是,在你的情况下几乎肯定不会起作用,这就是原因:

中位数过滤在图像上滑动窗口。在每个区域中,它将中心像素替换为周围窗口的中值。 medfilt2默认使用3x3窗口。让我们看一下您线附近的3x3区块,

Location of window

围绕[212 157]的3x3区块看起来像这样

 [0 0 0
  1 1 1
  0 0 0]

中值为0!因此,即使我们处于线段的中间,像素也会被过滤掉。

中值过滤的替代方法

Shai的去除噪声的方法改为找到最大的连接像素组并忽略较小的像素组。如果您还想从图像中删除这些小组,Matlab会提供一个过滤器bwareaopen,用于从二进制图像中删除小对象。

例如,如果您更换行

sim= medfilt2(sim);

sim= bwareaopen(sim, 4);

结果好多了

after noise removal

替代边缘检测器

最后一点,Shai使用水平渐变滤镜来查找图像中的水平边缘。它很有效,因为你的边缘是水平的。如果边缘不总是水平的,则可能需要使用另一种边缘检测方法。在您的原始代码中,您使用Sobel,但Matlab提供了许多选项,如果您调整其阈值,所有这些选项都会表现得更好。例如,在下图中,我使用四个不同的边缘检测器突出显示了代码选择的像素(使用bwareaopen修改)。

Detector comparison