从背景中隔离数字

时间:2018-01-14 16:08:58

标签: python imagemagick image-manipulation

抱歉,我没有正确的术语来提出这个问题,但简单来说,我有几张像这样的图片。白色区域的大小并不总是相同,但大多是矩形。颜色总是一样的。它是一个图像,我需要将图形与白色背景隔离,或者以不同的方式解释,我需要将黑色背景更改为白色...

enter image description here

并使它看起来像这样。

enter image description here

请注意,有些图形触及白色与黑色相交的边缘。

只要工具,库或编程语言完成,它就无关紧要。

9 个答案:

答案 0 :(得分:2)

以下是使用Imagemagick对此图像起作用的一种方法。首先修剪黑色区域,然后将图像分成3个相等的部分,然后修剪它们,然后压平成白色。修剪和裁剪跟踪原始偏移,因为我不使用+ repage来移除虚拟画布。

magick original.png -fuzz 5% -trim -crop 3x1@ -trim -background white -flatten result.png

enter image description here

请参阅 https://www.imagemagick.org/Usage/crop/#crop_equal https://www.imagemagick.org/Usage/crop/#trim

答案 1 :(得分:2)

有趣的问题!我假设你意识到你的小白色窗户没有水平对齐?我们稍后会谈到这一点。我有一个基于" squeezebox" 或手风琴的有趣方法......

enter image description here

有三个部分,所以我会在每个部分下面做一个横向规则来划分它们。

第1部分

从左侧和右侧挤压您的图像(如挤压箱),直到它只有一个像素宽的列,但与原始列相同:

enter image description here

现在对列进行阈值处理,以便只有完全黑色的水平线保持黑色。在水平线上有窗口或任何白色像素的地方,它变成白色。然后倒转它。

enter image description here

现在,使用最近邻点采样拉伸色谱柱(将挤压箱扩展)恢复到原始大小:

enter image description here

第2部分

现在再次做同样的事情,但是将挤压箱旋转90度后。基本上,我们要将图像压缩到1像素高,阈值并取消它,然后拉伸(延伸垂直旋转的挤压箱)直到它回到原始高度:

enter image description here

第3部分

现在拍摄原始图像并放入一个堆叠,上面有两个黑白条纹,并在每个像素位置选择最亮的像素:

enter image description here

enter image description here

enter image description here

代码如下所示:

#!/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

enter image description here

好的,这不错,并且它并不依赖于正好有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

enter image description here

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

enter image description here

答案 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;

enter image description here

第2步 - &#34;从左上角用红色填充,现在我们的窗口有适当的边缘,这样洪水就不会&#34 ;泄漏&#34; 进入窗口&#34;

enter image description here

第3步 - &#34;将所有非红色的东西变成黑色&#34;

enter image description here

第4步 - &#34;将红色的所有内容变为白色&#34;

enter image description here

第5步 - &#34;使白色形状变得更大&#34;

enter image description here

结果 - &#34;在每个像素位置,选择当前和原始图像中最亮的像素&#34;

enter image description here

答案 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行:读取输入

enter image description here

第2行 - tmp1.png:使用形态学边缘将图像转换为黑色曲线,在白色背景上围绕它们使用黑框(如Mark的另一个例子)。

enter image description here

第3行和第4行 - tmp2.png:使用形态扩张(删除曲线)和边缘,在黑色背景上的白色区域周围创建一个白色轮廓框。

enter image description here

第6行和第7行:result.png使用tmp2.png删除tmp1.png中的黑框,逐个像素地取两个图像之间的最大值。

enter image description here

为了比较,这是马克的优雅方法,我简化了一点:

convert original.png \
\( +clone -morphology close square:3 -negate +write tmp1.png \) \
-evaluate-sequence max \
result.png

第1行:阅读输入

enter image description here

第2行: - tmp1.png:使用形态接近(与扩张和侵蚀相同)来创建一个黑盒子来替换原始中包括黑色曲线的白色区域。方形尺寸可以低至3,但不能低于此值。从曲线末端移除的越小越小。

enter image description here

第3行:通过逐像素计算两个图像之间的最大值,删除原始曲线以外的所有黑色。

enter image description here

答案 5 :(得分:1)

@Mack wrote:

  

这种修剪方法适用于这个特定的图像,但是什么   间距不均匀时会发生什么?有一个更好的方法吗   没有修剪和裁剪?

一种方法是将每个白色方块与背景分离成单个图像。我有一个bash unix shell脚本,multicrop2,它会做到这一点。但是对于这个图像,它会产生一个额外的大图像。例如:

magick original.png tmp.png
multicrop2 -b white tmp.png result.png

enter image description here

enter image description here

enter image description here

enter image description here

您可以放弃此处显示的最后一个。

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

使:

result image

这个的一个很好的功能是没有泛滥,所以你可以流式传输图像。它可以处理任何大小的图像,只需要很少的记忆。

答案 8 :(得分:0)

这是使用Imagemagick的另一种相当简单的形态学方法(bottomhat)。在这种情况下,内核大小至少需要为4。见https://www.imagemagick.org/Usage/morphology/#bottom-hat

输入:

enter image description here

convert source.png -morphology bottomhat octagon:4 -negate result.png

enter image description here