使用ImageMagick在图像中查找形状

4
我有两张源图片: 第一张源图片 第二张源图片 它们看起来相同,但实际上它们稍微有所偏移。 因此我创建了一张差异图像,其中每个图像的差异都以颜色编码显示(绿色和红色)。 差异图像 我是这样创建它的:
convert first.png second.png                      \
   \( -clone 0,1 -compose difference -composite   \
      -threshold 0 \)                             \
   \( -clone 0 -clone 2 -compose minus -composite \
      -threshold 0 -fill green1 -opaque white     \
      -channel rgba -fill none -opaque black \)   \
   \( -clone 1 -clone 2 -compose minus -composite \
      -threshold 0 -fill red -opaque white        \
      -channel rgba -fill none -opaque black \)   \
   \( -clone 0,1 -evaluate-sequence mean \)       \
   -delete 0-2      \
   -reverse         \
   -background none \
   -compose over    \
   -flatten         \
    multicolor_difference.png

如此建议:

http://www.imagemagick.org/discourse-server/viewtopic.php?t=26105

现在,我想要不同绿色和红色矩形的位置,以便我有一个可以在代码中使用的形状列表。

如果我将图像转换为文本

# ImageMagick pixel enumeration: 2880,1370,255,srgb
0,0: (0,255,0)  #00FF00  lime
1,0: (0,255,0)  #00FF00  lime
2,0: (255,255,255)  #FFFFFF  white
3,0: (255,255,255)  #FFFFFF  white

如果需要遍历每个像素并检查颜色是否为绿色或红色,这显然会影响性能。在图像中搜索特定形状是否有更好的方法?即使只是检查某种颜色的出现也会大大提高性能。输出应该是文本形式,以便我可以在代码中解释它。

因此,总的来说,我希望以文本形式描述两个图像之间的差异。在最好的情况下,每个矩形只有大约10个输出。

1个回答

2
我不确定我理解你的问题,但我想我可以接近回答!
我可能会单独生成你的绿色和红色文件,但让我们从你拥有的开始。如果你将你的红色和青柠差异文件转换为黑白PBM文件,你可以将它传递给potrace,它会将其转换为向量化的SVG文件,然后你可以解析它:
convert difference.png    \
   -fill black            \
   +opaque lime           \
   -colorspace gray       \
   -threshold 1% pbm:- | potrace - -s -o green.svg

这会产生以下结果:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="2880.000000pt" height="1370.000000pt" viewBox="0 0 2880.000000 1370.000000"
 preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.12, written by Peter Selinger 2001-2015
</metadata>
<g transform="translate(0.000000,1370.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M20 6875 l0 -6826 25 -24 24 -25 14366 0 14365 0 0 6850 0 6850
-14390 0 -14390 0 0 -6825z m7280 4505 l0 -160 7110 0 7110 0 0 -1180 0 -1180
-7110 0 -7110 0 0 -160 0 -160 4290 0 4290 0 0 -1780 0 -1780 2820 0 2820 0 0
-120 0 -120 -2830 0 -2830 0 0 1450 0 1450 -4270 0 -4270 0 0 -1320 0 -1320
4260 0 4260 0 0 -120 0 -120 -4270 0 -4270 0 0 1810 c0 1200 3 1810 10 1810 6
0 10 -37 10 -90 l0 -90 4270 0 4270 0 0 160 0 160 -4270 0 -4270 0 0 -60 c0
-53 -2 -60 -20 -60 -20 0 -20 7 -20 1570 0 1040 3 1570 10 1570 6 0 10 -60 10
-160z m8240 -4440 l0 -380 -3950 0 -3950 0 0 380 0 380 3950 0 3950 0 0 -380z
m-2260 -1160 l0 -460 -1700 0 -1700 0 0 460 0 460 1700 0 1700 0 0 -460z
m15505 -5759 c-3 -6 -11 -11 -16 -11 -5 0 -4 6 3 14 14 16 24 13 13 -3z"/>
<path d="M7400 10040 l0 -1080 7010 0 7010 0 0 1080 0 1080 -7010 0 -7010 0 0
-1080z"/>
<path d="M7420 7920 l0 -180 4170 0 4170 0 0 180 0 180 -4170 0 -4170 0 0
-180z"/>
<path d="M7680 6940 l0 -340 3910 0 3910 0 0 340 0 340 -3910 0 -3910 0 0
-340z"/>
<path d="M9980 5780 l0 -360 1600 0 1600 0 0 360 0 360 -1600 0 -1600 0 0
-360z"/>
</g>
</svg>

这是一个非常好的解决方案。它只需要不到一秒钟的时间来处理!现在很棒的事情是,我可以使用一个xml解析器并了解矩形的尺寸。非常感谢 :-) 有一个问题:难道不能使用imagemagick将渲染后的图像转换为svg吗?这样我就不需要任何额外的依赖(虽然它的效果非常好)。 - Schnodderbalken
我认为ImageMagick转换只是将图像嵌入SVG文件中,因此它并不像potrace创建的那样是真正的矢量化图像。 - Mark Setchell
我明白了。我会把这个问题保持开放几天,以防出现新的想法。如果没有什么革命性的回答被发布,那么你的答案就会被接受 :) - Schnodderbalken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接