抱歉,我没有正确的术语来提出这个问题,但简单来说,我有几张像这样的图片。白色区域的大小并不总是相同,但大多是矩形。颜色总是一样的。它是一个图像,我需要将图形与白色背景隔离,或者以不同的方式解释,我需要将黑色背景更改为白色...
并使它看起来像这样。
请注意,有些图形触及白色与黑色相交的边缘。
只要工具,库或编程语言完成,它就无关紧要。
答案 0 :(得分:2)
以下是使用Imagemagick对此图像起作用的一种方法。首先修剪黑色区域,然后将图像分成3个相等的部分,然后修剪它们,然后压平成白色。修剪和裁剪跟踪原始偏移,因为我不使用+ repage来移除虚拟画布。
magick original.png -fuzz 5% -trim -crop 3x1@ -trim -background white -flatten result.png
请参阅 https://www.imagemagick.org/Usage/crop/#crop_equal https://www.imagemagick.org/Usage/crop/#trim
答案 1 :(得分:2)
有趣的问题!我假设你意识到你的小白色窗户没有水平对齐?我们稍后会谈到这一点。我有一个基于" squeezebox" 或手风琴的有趣方法......
有三个部分,所以我会在每个部分下面做一个横向规则来划分它们。
第1部分
从左侧和右侧挤压您的图像(如挤压箱),直到它只有一个像素宽的列,但与原始列相同:
现在对列进行阈值处理,以便只有完全黑色的水平线保持黑色。在水平线上有窗口或任何白色像素的地方,它变成白色。然后倒转它。
现在,使用最近邻点采样拉伸色谱柱(将挤压箱扩展)恢复到原始大小:
第2部分
现在再次做同样的事情,但是将挤压箱旋转90度后。基本上,我们要将图像压缩到1像素高,阈值并取消它,然后拉伸(延伸垂直旋转的挤压箱)直到它回到原始高度:
第3部分
现在拍摄原始图像并放入一个堆叠,上面有两个黑白条纹,并在每个像素位置选择最亮的像素:
代码如下所示:
#!/bin/bash
# Get width and height
read w h < <(identify -format "%w %h" image.png)
echo $w $h
magick image.png -threshold 50% \
\( -clone 0 -resize 1x\! -threshold 1% -negate -scale ${w}x${h}\! \) \
\( -clone 0 -resize x1\! -threshold 1% -negate -scale ${w}x${h}\! \) \
-evaluate-sequence max result.png
好的,这不错,并且它并不依赖于正好有3个窗口。但是,正如我在开始时所说的那样,小白色窗户没有在它们的顶部对齐,因此你会在窗户周围看到人工制品 - 只在水平方向上,因为在垂直方向上只有一个图像,所以没有任何对齐。基本上,我建议做一点形态学使你的窗户顶部和底部的高度都小3像素,代码看起来像这样:
#!/bin/bash
# Get width and height
read w h < <(identify -format "%w %h" image.png)
echo $w $h
magick image.png -threshold 50% \
\( -clone 0 -resize 1x\! -threshold 1% -negate -scale ${w}x${h}\! -morphology dilate rectangle:7x7 \) \
\( -clone 0 -resize x1\! -threshold 1% -negate -scale ${w}x${h}\! \) \
-evaluate-sequence max result.png
将rectangle:7x7
更改为较大的数字,以修剪窗口边缘周围的更多像素。基本上它会削减顶部和底部的一半像素数。因此rectangle:7x7
会使您的窗口在顶部和底部缩小3个像素,而rectangle:15x15
会使它们缩小7个像素。以下是Anthony Thyssen关于如何使用 ImageMagick 以及特别是形态学的优秀页面link。
答案 2 :(得分:2)
这是另一种可能适用于其他图像的方法...克隆,然后将小白色窗口扩大(放大)7个像素,然后再次侵蚀它们,反转并选择最亮的像素:
convert image.png \( +clone -morphology dilate square:7x7 -morphology erode square:7x7 -negate \) -evaluate-sequence max result.png
答案 3 :(得分:2)
这是另一个想法......
convert image.png -threshold 50% \
\( +clone -morphology edgeout square:3x3 -write step1.png \
-fill red -draw 'color 0,0 floodfill' -write step2.png \
-fill black +opaque red -fill black -write step3.png \
-opaque red -write step4.png \
-morphology dilate square:3x3 -write step5.png \
\) -evaluate-sequence max result.png
以下是步骤1-5和结果。您可以从代码中删除所有-write stepX.png
部分,它们只是让您可以看到我在做什么:
Step1 - &#34;显示白色区域边缘周围的所有像素&#34;
第2步 - &#34;从左上角用红色填充,现在我们的窗口有适当的边缘,这样洪水就不会&#34 ;泄漏&#34; 进入窗口&#34;
第3步 - &#34;将所有非红色的东西变成黑色&#34;
第4步 - &#34;将红色的所有内容变为白色&#34;
第5步 - &#34;使白色形状变得更大&#34;
结果 - &#34;在每个像素位置,选择当前和原始图像中最亮的像素&#34;
答案 4 :(得分:2)
Mark的形态学方法比这更简单。因此,我建议将其作为迄今为止最好的方法。但这里有一个类似的方法(他的最后两种方法的混合)可能是有意义的。我有include + write tmpX.png来显示步骤。那些可以删除。 (使用Imagemagick 6.9.9.33的Unix语法)
convert original.png \
\( -clone 0 -morphology edgeout square:3 -negate +write tmp1.png \) \
\( -clone 0 -morphology dilate square:3 \
-morphology edge square:3 +write tmp2.png \) \
-delete 0 \
-evaluate-sequence max \
result.png
第1行:读取输入
第2行 - tmp1.png:使用形态学边缘将图像转换为黑色曲线,在白色背景上围绕它们使用黑框(如Mark的另一个例子)。
第3行和第4行 - tmp2.png:使用形态扩张(删除曲线)和边缘,在黑色背景上的白色区域周围创建一个白色轮廓框。
第6行和第7行:result.png使用tmp2.png删除tmp1.png中的黑框,逐个像素地取两个图像之间的最大值。
为了比较,这是马克的优雅方法,我简化了一点:
convert original.png \
\( +clone -morphology close square:3 -negate +write tmp1.png \) \
-evaluate-sequence max \
result.png
第1行:阅读输入
第2行: - tmp1.png:使用形态接近(与扩张和侵蚀相同)来创建一个黑盒子来替换原始中包括黑色曲线的白色区域。方形尺寸可以低至3,但不能低于此值。从曲线末端移除的越小越小。
第3行:通过逐像素计算两个图像之间的最大值,删除原始曲线以外的所有黑色。
答案 5 :(得分:1)
@Mack wrote:
这种修剪方法适用于这个特定的图像,但是什么 间距不均匀时会发生什么?有一个更好的方法吗 没有修剪和裁剪?
一种方法是将每个白色方块与背景分离成单个图像。我有一个bash unix shell脚本,multicrop2,它会做到这一点。但是对于这个图像,它会产生一个额外的大图像。例如:
magick original.png tmp.png
multicrop2 -b white tmp.png result.png
您可以放弃此处显示的最后一个。
在http://www.fmwconcepts.com/imagemagick/index.html
上查看我的脚本multicrop2目前,脚本丢失了每个输出图像的虚拟画布。但是我可以添加一个参数来保留它,这样就可以将3个好的图像平铺到白色上,这样单独的图像就可以在适当的位置合并回白色背景。
答案 6 :(得分:0)
如果你的意思是用透明度替换白色(在图像编辑器中用a.k.a.color-to-alpha),神奇的公式是:
convert original.png ( -clone 0 -fill "#a0132e" -colorize 100 ) ( -clone 0,1 -compose difference -composite -separate +channel -evaluate-sequence max -auto-level ) -delete 1 -alpha off -compose over -compose copy_opacity -composite output.png
解释here
答案 7 :(得分:0)
这里使用高斯模糊作为形态算子的解决方案略有不同。我使用了pyvips,但是很容易用魔法重做。
这个想法是,如果你用一个相当大的西格玛,然后阈值&gt; 0,您将按高斯半径展开所有白色,从而填充线条。
简洁的一点是,这可以再次使用,阈值翻转会严重侵蚀你扩张的量。只是模糊第二次相同的量,但现在做!= 255,你将拥有背景的形状!按位或与原始图像的解决方案。
import sys
import pyvips
im = pyvips.Image.new_from_file(sys.argv[1], access="sequential")
bg = im.gaussblur(2) > 0
bg = bg.gaussblur(2) != 255
im |= bg
im = im.write_to_file(sys.argv[2])
然后:
python characters.py ~/pics/characters.png x.png
使:
这个的一个很好的功能是没有泛滥,所以你可以流式传输图像。它可以处理任何大小的图像,只需要很少的记忆。
答案 8 :(得分:0)
这是使用Imagemagick的另一种相当简单的形态学方法(bottomhat)。在这种情况下,内核大小至少需要为4。见https://www.imagemagick.org/Usage/morphology/#bottom-hat
输入:
convert source.png -morphology bottomhat octagon:4 -negate result.png