从图像中提取满足特定条件的形状
Extracting Shapes that meet a certain criteria from an Image
假设我有一张图像,我想从中提取某些形状。此图像有过多的形状,但我只关心填充有对角线的形状。这样的图像可能如下所示:
因为我只关心其中有对角线的形状,所以我尝试使用此图像生成如下所示的形状:
目前,我正在尝试用卷积来做到这一点。
我首先将图像与这个矩阵进行卷积:
]
生成的图像如下所示:
这在提取我正在寻找的信息方面做得相当好,但现在我想让它看起来像我理想的最终图像。
我当前流程的下一步是对图像进行模糊处理,在对图像进行模糊处理后,我使用阈值获得如下所示的结果。
这与我想要的非常接近,但我有点卡住了。
你们知道这个问题的更好解决方案吗?最终目标是编写一个软件,可以拍摄任何具有此类特征的图像,并以这种方式提取它们。
感谢您的宝贵时间!
您能否不只是对结果进行后处理以平均像素邻域并设置一个阈值,在该阈值下邻域中的所有像素都将被分配为黑色或白色?通过使用大小为边缘 "sawtooth" 伪影周期的正方形邻域,您将通过填充 "valleys" 并消除 "peaks".
来平滑边缘
好问题。我将直接从命令行尝试使用 ImageMagick - 它安装在大多数 Linux 发行版上,可用于 OSX 和 Windows。它绑定了 C++、C#、.Net、Python、Perl、PHP 等
我会选择 Hit and Miss 风格的形态学,像这样的对角内核:
convert tetris.png -negate \
-morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" result.png
完成后,您可能需要一种方法来定位斜线区域。一种方法是将所有像素 "squidge" 放入一个像素宽的列中 - 想象一下同时向两侧按下直到图片只是一个细列。你也可以垂直做同样的事情——想象在图像的顶部放置一个重物,直到它被压扁到只有一个像素高。像这样:
convert tetris.png -negate -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" -resize 1x2200! -scale 25x2200! -normalize tall.png
convert tetris.png -negate -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" -resize 3400x1! -scale 3400x25! -normalize wide.png
上面的最后一个 -scale
只是为了让它足够宽以供查看 - 你真的不需要它。
然后您可以要求以文本格式输出,并查找颜色从黑色变为灰色或白色的位置,这就是形状边缘的坐标。像这样:
convert tetris.png -negate -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" -resize 1x2199! -normalize -alpha off -depth 8 txt:
# ImageMagick pixel enumeration: 1,2199,255,gray
0,0: (0,0,0) #000000 gray(0)
0,1: (0,0,0) #000000 gray(0)
0,2: (0,0,0) #000000 gray(0)
0,3: (0,0,0) #000000 gray(0)
0,4: (0,0,0) #000000 gray(0)
...
...
0,184: (0,0,0) #000000 gray(0)
0,185: (0,0,0) #000000 gray(0)
0,186: (0,0,0) #000000 gray(0)
0,187: (257,257,257) #010101 gray(1)
0,188: (3855,3855,3855) #0F0F0F gray(15) <= Transition from black = start of shape
0,189: (3855,3855,3855) #0F0F0F gray(15)
0,190: (3855,3855,3855) #0F0F0F gray(15)
0,191: (3855,3855,3855) #0F0F0F gray(15)
0,192: (3855,3855,3855) #0F0F0F gray(15)
0,193: (3855,3855,3855) #0F0F0F gray(15)
0,194: (3855,3855,3855) #0F0F0F gray(15)
0,195: (3855,3855,3855) #0F0F0F gray(15)
0,196: (3855,3855,3855) #0F0F0F gray(15)
0,197: (3855,3855,3855) #0F0F0F gray(15)
0,198: (3855,3855,3855) #0F0F0F gray(15)
0,199: (3855,3855,3855) #0F0F0F gray(15)
0,200: (3855,3855,3855) #0F0F0F gray(15)
0,201: (3855,3855,3855) #0F0F0F gray(15)
0,202: (3855,3855,3855) #0F0F0F gray(15)
...
....
0,324: (3855,3855,3855) #0F0F0F gray(15)
0,325: (3855,3855,3855) #0F0F0F gray(15)
0,326: (3855,3855,3855) #0F0F0F gray(15)
0,327: (4883,4883,4883) #131313 gray(19)
0,328: (19789,19789,19789) #4D4D4D gray(77) <= Fatter part of shape
0,329: (20817,20817,20817) #515151 gray(81)
0,330: (20817,20817,20817) #515151 gray(81)
0,331: (20817,20817,20817) #515151 gray(81)
所以你可以看到你的形状从 188 像素开始,到 328 像素的脂肪部分。
此外,连通分量分析(也称为 Blob 分析),在您的原始图像上是这样的:
convert tetris.png \
-define connected-components:verbose=true \
-define connected-components:area-threshold=100000 \
-connected-components 8 -auto-level output.png
输出
Objects (id: bounding-box centroid area mean-color):
0: 3399x2199+0+0 1774.2,1149.3 5390079 srgba(255,255,255,1)
7: 2045x1180+405+187 1475.1,930.4 1681486 srgba(255,255,255,1)
40: 546x334+1753+1661 2025.5,1827.5 182364 srgba(255,255,255,1)
6: 2057x1192+399+181 1580.7,839.8 117980 srgba(0,0,0,1)
5: 702x146+621+149 971.5,221.5 102492 srgba(255,255,255,1)
如果我在第二行输出的方框内绘制,你可以看到:
convert tetris.png -stroke red -fill none -draw "rectangle 405,187 2450,1367" x.png
您可能会查看红色边界框的区域(1681486 像素),and/or 它的形状 (2045x1180) 以考虑其比例以及它们是否与您寻找的图案框的形状和大小相匹配,即它是或不是方形。
假设我有一张图像,我想从中提取某些形状。此图像有过多的形状,但我只关心填充有对角线的形状。这样的图像可能如下所示:
因为我只关心其中有对角线的形状,所以我尝试使用此图像生成如下所示的形状:
目前,我正在尝试用卷积来做到这一点。
我首先将图像与这个矩阵进行卷积:
生成的图像如下所示:
我当前流程的下一步是对图像进行模糊处理,在对图像进行模糊处理后,我使用阈值获得如下所示的结果。
这与我想要的非常接近,但我有点卡住了。 你们知道这个问题的更好解决方案吗?最终目标是编写一个软件,可以拍摄任何具有此类特征的图像,并以这种方式提取它们。
感谢您的宝贵时间!
您能否不只是对结果进行后处理以平均像素邻域并设置一个阈值,在该阈值下邻域中的所有像素都将被分配为黑色或白色?通过使用大小为边缘 "sawtooth" 伪影周期的正方形邻域,您将通过填充 "valleys" 并消除 "peaks".
来平滑边缘好问题。我将直接从命令行尝试使用 ImageMagick - 它安装在大多数 Linux 发行版上,可用于 OSX 和 Windows。它绑定了 C++、C#、.Net、Python、Perl、PHP 等
我会选择 Hit and Miss 风格的形态学,像这样的对角内核:
convert tetris.png -negate \
-morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" result.png
完成后,您可能需要一种方法来定位斜线区域。一种方法是将所有像素 "squidge" 放入一个像素宽的列中 - 想象一下同时向两侧按下直到图片只是一个细列。你也可以垂直做同样的事情——想象在图像的顶部放置一个重物,直到它被压扁到只有一个像素高。像这样:
convert tetris.png -negate -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" -resize 1x2200! -scale 25x2200! -normalize tall.png
convert tetris.png -negate -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" -resize 3400x1! -scale 3400x25! -normalize wide.png
上面的最后一个 -scale
只是为了让它足够宽以供查看 - 你真的不需要它。
然后您可以要求以文本格式输出,并查找颜色从黑色变为灰色或白色的位置,这就是形状边缘的坐标。像这样:
convert tetris.png -negate -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" -resize 1x2199! -normalize -alpha off -depth 8 txt:
# ImageMagick pixel enumeration: 1,2199,255,gray
0,0: (0,0,0) #000000 gray(0)
0,1: (0,0,0) #000000 gray(0)
0,2: (0,0,0) #000000 gray(0)
0,3: (0,0,0) #000000 gray(0)
0,4: (0,0,0) #000000 gray(0)
...
...
0,184: (0,0,0) #000000 gray(0)
0,185: (0,0,0) #000000 gray(0)
0,186: (0,0,0) #000000 gray(0)
0,187: (257,257,257) #010101 gray(1)
0,188: (3855,3855,3855) #0F0F0F gray(15) <= Transition from black = start of shape
0,189: (3855,3855,3855) #0F0F0F gray(15)
0,190: (3855,3855,3855) #0F0F0F gray(15)
0,191: (3855,3855,3855) #0F0F0F gray(15)
0,192: (3855,3855,3855) #0F0F0F gray(15)
0,193: (3855,3855,3855) #0F0F0F gray(15)
0,194: (3855,3855,3855) #0F0F0F gray(15)
0,195: (3855,3855,3855) #0F0F0F gray(15)
0,196: (3855,3855,3855) #0F0F0F gray(15)
0,197: (3855,3855,3855) #0F0F0F gray(15)
0,198: (3855,3855,3855) #0F0F0F gray(15)
0,199: (3855,3855,3855) #0F0F0F gray(15)
0,200: (3855,3855,3855) #0F0F0F gray(15)
0,201: (3855,3855,3855) #0F0F0F gray(15)
0,202: (3855,3855,3855) #0F0F0F gray(15)
...
....
0,324: (3855,3855,3855) #0F0F0F gray(15)
0,325: (3855,3855,3855) #0F0F0F gray(15)
0,326: (3855,3855,3855) #0F0F0F gray(15)
0,327: (4883,4883,4883) #131313 gray(19)
0,328: (19789,19789,19789) #4D4D4D gray(77) <= Fatter part of shape
0,329: (20817,20817,20817) #515151 gray(81)
0,330: (20817,20817,20817) #515151 gray(81)
0,331: (20817,20817,20817) #515151 gray(81)
所以你可以看到你的形状从 188 像素开始,到 328 像素的脂肪部分。
此外,连通分量分析(也称为 Blob 分析),在您的原始图像上是这样的:
convert tetris.png \
-define connected-components:verbose=true \
-define connected-components:area-threshold=100000 \
-connected-components 8 -auto-level output.png
输出
Objects (id: bounding-box centroid area mean-color):
0: 3399x2199+0+0 1774.2,1149.3 5390079 srgba(255,255,255,1)
7: 2045x1180+405+187 1475.1,930.4 1681486 srgba(255,255,255,1)
40: 546x334+1753+1661 2025.5,1827.5 182364 srgba(255,255,255,1)
6: 2057x1192+399+181 1580.7,839.8 117980 srgba(0,0,0,1)
5: 702x146+621+149 971.5,221.5 102492 srgba(255,255,255,1)
如果我在第二行输出的方框内绘制,你可以看到:
convert tetris.png -stroke red -fill none -draw "rectangle 405,187 2450,1367" x.png
您可能会查看红色边界框的区域(1681486 像素),and/or 它的形状 (2045x1180) 以考虑其比例以及它们是否与您寻找的图案框的形状和大小相匹配,即它是或不是方形。