从映像中提取满足特定条件的形状 [英] Extracting Shapes that meet a certain criteria from an Image
问题描述
假设我有一个图像,我想从中提取某些形状。这个图像有很多形状,但我只关心填充对角线的形状。这样的图片可能如下所示:
由于我只关心在其中有对角线的形状,我想使用此图片生成一个如下所示:
目前,我试图用卷积来做到这一点。
我开始卷积图像与这个矩阵:
]
它产生一个看起来像的图像像这样:
这是一个相当不错的工作,提取我正在寻找的信息,但现在我想让它看起来像我理想的最终形象。
我当前过程的下一步是模糊图像,在模糊图像后,我使用一个阈值来获得这样的结果。
这非常接近我想要的,有点卡住。
你们知道更好的解决这个问题吗?最终目标是编写一个软件,它会采取任何具有这样的功能的图像,并提取这样的方式。
感谢您的时间! p>
很好的问题。我将尝试使用ImageMagick直接从命令行 - 它安装在大多数Linux发行版,可用于OSX和Windows。它有C ++,C#,.Net,Python,Perl,PHP等的绑定。
我会去一个具有如下的对角内核:
convert tetris.png -negate \
-morphology hit-and-miss 3x3:1,0,0 0,1,0 0,0,1result.png
一旦你有了这一点,你可能需要一种方法来找到斜线阴影区域。一种方法是将所有像素squidge集成到单个像素宽的列中 - 设想同时按在两侧,直到图片只是一个细列。你也可以做垂直的同样的事情 - 想象一个沉重的重量在图像的顶部,直到它扁平,只有一个像素高。像这样:
convert tetris.png -negate -morphology hit-and-miss3x3:1,0,0 0,1,0 0,0,1-resize 1x2200!规模25x2200! -normalize tall.png
convert tetris.png -negate -morphology hit-and-miss3x3:1,0,0 0,1,0 0,0,1-resize 3400x1!规模3400x25! -normalize wide.png
最后 -scale
然后你可以要求文本格式的输出,然后寻找在哪里颜色从黑色变为灰色或白色,这是形状边缘的坐标。像这样:
convert tetris.png -negate -morphology hit-and-miss3x3:1,0,0 0, 1,0 0,0,1-resize 1x2199! -normalize -alpha off -depth 8 txt:
#ImageMagick像素枚举:1,2199,255,灰色
0,0:(0,0,0)#000000灰色)
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灰色(0)
0,187:(257,257,257)#010101灰色(1)
0,188:(3855,3855,3855)#0F0F0F灰色(15)<=从黑色转变=
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灰色(15)
...
....
0,324:(3855,3855,3855)#0F0F0F灰色
0,325:(3855,3855,3855)#0F0F0F gray(15)
0,326:(3855,3855,3855)#0F0F0F gray(15)
0,327:(4883,4883,4883 )#131313灰色(19)
0,328:(19789,19789,19789)#4D4D4D灰色(77)<=形状的部分
0,329:(20817,20817,20817)#515151灰色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
输出
对象(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)
如果我在第二行输出框中绘制, / p>
convert tetris.png -stroke red -fill none -drawrectangle 405,187 2450,1367x.png
您可以查看红色边界框(1681486像素)和/或其形状(2045x1180)的区域,以考虑其比例,以及它们是否匹配您寻求的图案框的形状和大小,即它是如何是平方的,不是。
Let's say I have an image that I want to extract certain shapes from. This image has a plethora of shapes, but I'm only concerned about the shapes that are filled with diagonal lines. Such an image could look like this:
Since I only care about shapes that have diagonal lines in them, I'm trying to use this image to generate one that looks like this:
Currently, I'm attempting to do this with convolution. I start by convolving the image with this matrix: ]
Which produces an image that looks like this: This does a fairly good job of extracting the information i'm looking for, but now I want to make it look like my ideal final image.
The next step in my current process is to blur the image, and after blurring the image I use a threshold to obtain a result that looks like this.
This is very close to what I want, but I'm a little stuck. Do you guys know a better solution to this problem? The end goal is to write a piece of software that will take any image that has features like this, and extract them in this way.
Thanks for your time!
解决方案Great question. I'll have a try with ImageMagick straight from the command line - it's installed on most Linux distros and available for OSX and Windows. It has bindings for C++, C#, .Net, Python, Perl, PHP etc.
I would go for a Hit and Miss style morphology with a diagonal kernel like this:
convert tetris.png -negate \ -morphology hit-and-miss "3x3: 1,0,0 0,1,0 0,0,1" result.png
Once you have that, you may need a method to locate the diagonally hatched area. One method is to "squidge" all the pixels into a single pixel wide column - imagine pressing in on both sides at once till the picture is just a thin column. You can also do the same thing vertically - imagine putting a heavy weight on the top of the image till it squashes flat to just one pixel tall. Like this:
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
The last
-scale
above is just to make it wide enough to see - you don't need that really.You can then ask for the output in text format, and look for where the colour changes from black to a shade of grey, or white, and that is the coordinate of the edge of your shape. Like this:
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)
So you can see that your shape starts at pixel 188, and gets to the fat part at pixel 328.
Also, a Connected Component Analysis (also called Blob Analysis), on your original image like this:
convert tetris.png \ -define connected-components:verbose=true \ -define connected-components:area-threshold=100000 \ -connected-components 8 -auto-level output.png
Output
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)
If I draw in the box on the second line of output, you can see it:
convert tetris.png -stroke red -fill none -draw "rectangle 405,187 2450,1367" x.png
You might look at the area of the red bounding box (1681486 pixels), and/or its shape (2045x1180) to think about its proportions and whether they match the shape and size of your sought patterned box, i.e. how square it is or isn't.
这篇关于从映像中提取满足特定条件的形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!