是否有一种算法在填充像样本图像上的填充孔方面表现良好?扩张效果不佳,因为在我最终设法连接这些曲线的末端之前,曲线变得非常厚。我想避免增加线条。感谢您的任何帮助。在形状边缘填充空隙
是,可以存在只是像那些孔任何字母或形状在图像中。
是否有一种算法在填充像样本图像上的填充孔方面表现良好?扩张效果不佳,因为在我最终设法连接这些曲线的末端之前,曲线变得非常厚。我想避免增加线条。感谢您的任何帮助。在形状边缘填充空隙
是,可以存在只是像那些孔任何字母或形状在图像中。
我对此有点尝试。它可能需要一些调整,但它是一个想法。我的算法如下:
查找所有黑色像素都有一个黑色的相邻像素,将其着色为红色,并将其放在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');
结果
您必须放大右看红色像素...
缩放图像
另外,更简单的方法,这可能会转化成更好的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
与所得到的图像(您可能需要放大间隙看到红色):
如果你想在红色像素的名单,与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
现在,您可以处理红点列表,并为每个红点找到最近的其他红点并将它们用直线连接起来 - 或者在感觉非常敏锐时做一些曲线拟合。当然,可能需要一些改进,你可能希望设置最大长度的填缝线。
您的解决方案的问题是,它检测字母“B”中的松散结尾,我们不需要找到一对。 – user107986 2014-11-02 17:20:30
这就是我在我的回答结束时的微调建议的想法。 – 2014-11-02 18:16:22
获得加厚图像后,可以使用skeletonization恢复“薄”形状。我发现一个镂空的实现here。
如果你想避免太多增厚(因为它扭曲图像和形状的部分合并在一起),交替使用轻度侵蚀和骨架化,直到你得到的孔填补。
接下来怎么办? http://en.wikipedia.org/wiki/Closing_%28morphology%29。 – Steffen 2014-10-27 11:26:21
如果孔小于物体之间的间隙,则可以首先将线段与物体聚类,这样可以更容易地填充孔(例如分别为每个物体扩大)。否则请阅读“格式塔心理学” – Micka 2014-10-27 11:46:32
您是否考虑过使用Hough变换完成这些线条的完成? OpenCV的确拥有Hough变换作为API的一部分:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html – rayryeng 2014-10-27 17:08:48