为什么这个轮廓检测代码不能正常工作?

时间:2014-07-03 10:23:58

标签: matlab image-processing edge-detection

我根据this paper的第一部分编写了一个代码(关于轮廓检测)。但是,我的代码生成的图像与文中所示的图像不同。我是图像处理的新手,因此我想也许有些东西我不能完全理解。
我要写一些论文和我如何实施它,这样你就可以看出是否存在任何误解。
该报说:

  

我们建议使用局部方法来检查所选窗口n * n内的光照变化。我们通常使用3 * 3窗口,我们将图像划分为该大小的许多重叠区域。   对于这些区域中的每一个,我们计算了8像素邻域中像素强度值的平均值和标准偏差。

对于这部分,我写道:

e=imread('1.jpg');
p=rgb2gray(e);
p=im2double(p);
h=[1 1 1;
   1 1 1;
   1 1 1;]; 
h=h/9;
u=imfilter(p,h);% average filter
Size=size(e);
n=3;
e=[1 1 1;
   1 1 1;
   1 1 1;]; 
Di=stdfilt(p,e); % standard deviation

我有一个问题: 8像素邻域是什么意思?是(a)我不应该使用每个3 * 3本地窗口的中心像素,还是(b)只是本地窗口的另一个术语?

现在剩下的算法,来自论文:

  

然后,如果被检查区域的中心像素属于线条或背景,则执行决定。对于像素强度Ihigh的最大值和区域Ilow中像素强度的最小值,我们计算差值S(i,j),如:
  S(I,J)= I高-I低
  我们将它与某个阈值进行比较。我们建议在计算轮廓检测中使用的阈值T(i,j)时使用像素强度的均值和标准偏差。 T = u-k * sd(sd =标准偏差)其中k是一定值。然后轮廓检测的规则是:
  如果S(i,j)> = T(i,j),则g(i,j)= 1,如果S(i,j)<1,则g(i,j)= 0。 T(i,j)在结果中,我们获得具有检测到的轮廓的二值图像g(i,j)。此外,常数k允许调整和改变边缘检测算法的灵敏度,&#34;

我为这部分写了这段代码:

k=1;
Div=k*Di;
t=u-Div;
min=ordfilt2(p,1,ones(3,3));
max=ordfilt2(p,3*3,ones(3,3));
s=max-min;
g=zeros(Size(1),Size(2));
for I=1:Size(1)
    for J=1:Size(2)
        if(s(I,J) >= t(I, J))
            g(I, J) = 1;
        else
            g(I, J) = 0;
        end
    end
end
g=imadjust(g,[0 1],[1,0]);
imshow(g)

我不确定这两行:

 min=ordfilt2(p,1,ones(3,3));
 max=ordfilt2(p,3*3,ones(3,3);

根据论文所说,有什么我不知道的吗?或任何误解?

这是本文所示的例子:

example from paper

这就是我所拥有的:

own result

原始图片:

original

1 个答案:

答案 0 :(得分:2)

我认为你的结果看起来并不那么糟糕。关于差异:

  • 你有更多的噪音,但这可能是因为你有更高的分辨率,在你的图像上显示更多的细节。在找到轮廓之前,您可以尝试在图像上运行高斯滤镜。
  • 图像中的灰度值可能多于纸张图像中的灰度值。因此,可以使用此算法找到更多细节作为轮廓。
  • 也许只是因为k的价值不同。

但是,我认为您应该将耳朵的灰度值图像与结果进行比较。

2d中的

8像素邻域意味着你不要使用中间的像素,而是围绕它。与使用9像素相比,我无法估计其对结果的影响。

关于您的代码的评论:您可以替换

for I=1:Size(1)
    for J=1:Size(2)
        if(s(I,J) >= t(I, J))
            g(I, J) = 1;
        else
            g(I, J) = 0;
        end
    end
end

g=zeros(Size);
g(s>=t)=1;