2014-10-27 198 views
4

是否有一种算法在填充像样本图像上的填充孔方面表现良好?扩张效果不佳,因为在我最终设法连接这些曲线的末端之前,曲线变得非常厚。我想避免增加线条。感谢您的任何帮助。在形状边缘填充空隙

enter image description here

是,可以存在只是像那些孔任何字母或形状在图像中。

+2

接下来怎么办? http://en.wikipedia.org/wiki/Closing_%28morphology%29。 – Steffen 2014-10-27 11:26:21

+1

如果孔小于物体之间的间隙,则可以首先将线段与物体聚类,这样可以更容易地填充孔(例如分别为每个物体扩大)。否则请阅读“格式塔心理学” – Micka 2014-10-27 11:46:32

+0

您是否考虑过使用Hough变换完成这些线条的完成? OpenCV的确拥有Hough变换作为API的一部分:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html – rayryeng 2014-10-27 17:08:48

回答

1

我对此有点尝试。它可能需要一些调整,但它是一个想法。我的算法如下:

查找所有黑色像素都有一个黑色的相邻像素,将其着色为红色,并将其放在pixels at ends的列表中。

查看所有红色像素的列表,找到最接近的其他红色像素并在两者之间绘制直线。

顺便说一句,我只实现了第一部分 - 暂且东西为读者做;-)

#!/usr/bin/perl 
use strict; 
use warnings; 
use Image::Magick; 
use Data::Dumper; 

my $im=Image::Magick->new(); 
$im->Read('EsmKh.png'); 

my ($width,$height)=$im->Get('width','height'); 
my $out=Image::Magick->new(); 
$out->Read('EsmKh.png'); 

my @pixels; 
# Iterate over pixels 
for my $y (0..($height-1)){ 
    for my $x (0..($width-1)){ 
     my (@pixel) = split(/,/, $im->Get("pixel[$x,$y]")); 
     $pixels[$x][$y]=$pixel[0]; 
    } 
} 

# Find black pixels that have precisely 1 black neighbour 
for my $y (1..($height-2)){ 
    for my $x (1..($width-2)){ 
     next if $pixels[$x][$y]!=0; 
     my $neighbours=0; 
     for(my $i=$x-1;$i<=$x+1;$i++){ 
     for(my $j=$y-1;$j<=$y+1;$j++){ 
      $neighbours++ if $pixels[$i][$j]==0; 
     } 
     } 
     $neighbours--; # Uncount ourself ! 
     if($neighbours==1){ 
     $out->Set("pixel[$x,$y]"=>'red'); 
     } 
    } 
} 
$out->Write(filename=>'out.png'); 

结果

您必须放大右看红色像素...

enter image description here

缩放图像

enter image description here

4

另外,更简单的方法,这可能会转化成更好的OpenCV它使用卷积,而不是连续的Perl/C++代码。

基本上设置所有的黑色像素重视10,所有的白色像素重视0,然后进行卷积用下列3×3内核图像:

1 1 1 
1 10 1 
1 1 1 

现在,在的中间的黑色像素内核将提供100(10x10),而邻域中的任何其他黑色像素将提供10(10x1)。所以如果我们想要一个中央黑色像素的点只有一个相邻的黑色像素,它的值将是110(100 + 10)。所以让我们用红色为所有值为110的像素着色。这给出了这样的命令:

convert EsmKh.png -colorspace gray -fill gray\(10\) -opaque black -fill gray\(0\) -opaque white -morphology convolve '3x3: 1,1,1 1,10,1 1,1,1' -fill red -opaque gray\(110\) out.png 

与所得到的图像(您可能需要放大间隙看到红色):

enter image description here

如果你想在红色像素的名单,与txt:更换输出文件名和搜索这样的:

convert EsmKh.png -colorspace gray -fill rgb\(10,10,10\) -opaque black -fill rgb\(0,0,0\) -opaque white -morphology convolve '3x3: 1,1,1 1,10,1 1,1,1' txt: | grep "110,110,110" 

这给:

86,55: (110,110,110) #6E6E6E grey43 
459,55: (110,110,110) #6E6E6E grey43 
83,56: (110,110,110) #6E6E6E grey43 
507,59: (110,110,110) #6E6E6E grey43 
451,64: (110,110,110) #6E6E6E grey43 
82,65: (110,110,110) #6E6E6E grey43 
134,68: (110,110,110) #6E6E6E grey43 
519,75: (110,110,110) #6E6E6E grey43 
245,81: (110,110,110) #6E6E6E grey43 
80,83: (110,110,110) #6E6E6E grey43 
246,83: (110,110,110) #6E6E6E grey43 
269,84: (110,110,110) #6E6E6E grey43 
288,85: (110,110,110) #6E6E6E grey43 
315,87: (110,110,110) #6E6E6E grey43 
325,87: (110,110,110) #6E6E6E grey43 
422,104: (110,110,110) #6E6E6E grey43 
131,116: (110,110,110) #6E6E6E grey43 
524,116: (110,110,110) #6E6E6E grey43 
514,117: (110,110,110) #6E6E6E grey43 
122,118: (110,110,110) #6E6E6E grey43 
245,122: (110,110,110) #6E6E6E grey43 
76,125: (110,110,110) #6E6E6E grey43 
456,128: (110,110,110) #6E6E6E grey43 
447,129: (110,110,110) #6E6E6E grey43 
245,131: (110,110,110) #6E6E6E grey43 
355,135: (110,110,110) #6E6E6E grey43 
80,146: (110,110,110) #6E6E6E grey43 
139,151: (110,110,110) #6E6E6E grey43 
80,156: (110,110,110) #6E6E6E grey43 
354,157: (110,110,110) #6E6E6E grey43 
144,160: (110,110,110) #6E6E6E grey43 
245,173: (110,110,110) #6E6E6E grey43 
246,183: (110,110,110) #6E6E6E grey43 
76,191: (110,110,110) #6E6E6E grey43 
82,197: (110,110,110) #6E6E6E grey43 
126,200: (110,110,110) #6E6E6E grey43 
117,201: (110,110,110) #6E6E6E grey43 
245,204: (110,110,110) #6E6E6E grey43 
248,206: (110,110,110) #6E6E6E grey43 
297,209: (110,110,110) #6E6E6E grey43 
309,210: (110,110,110) #6E6E6E grey43 

现在,您可以处理红点列表,并为每个红点找到最近的其他红点并将它们用直线连接起来 - 或者在感觉非常敏锐时做一些曲线拟合。当然,可能需要一些改进,你可能希望设置最大长度的填缝线。

+0

您的解决方案的问题是,它检测字母“B”中的松散结尾,我们不需要找到一对。 – user107986 2014-11-02 17:20:30

+0

这就是我在我的回答结束时的微调建议的想法。 – 2014-11-02 18:16:22

1

获得加厚图像后,可以使用skeletonization恢复“薄”形状。我发现一个镂空的实现here

如果你想避免太多增厚(因为它扭曲图像和形状的部分合并在一起),交替使用轻度侵蚀和骨架化,直到你得到的孔填补。