计算二维平面中黑白形状的大小

Posted

技术标签:

【中文标题】计算二维平面中黑白形状的大小【英文标题】:Compute size of b/w shape in 2D Plane 【发布时间】:2014-01-20 09:27:39 【问题描述】:

我想计算图片中任意形状的黑色像素的数量。可能有多个对象,如下图所示。

我怀疑这个问题可以通过动态编程来解决,即逐行遍历像素并添加黑色像素。我只是不知道如何正确合并两个部分的大小。

我很确定有算法可以解决我的问题,但我显然使用了错误的搜索词。

您能否为我提供一个好的(快速)算法来执行此操作,如果该算法是用 c++ 编写的并且与 OpenCV 库中的 Mat 兼容,则可以加分。 ;)

这张(放大的)图片的结果类似于:15 代表左上角的对象,60 代表大斑点,...

【问题讨论】:

【参考方案1】:

我想我找到了解决方案(当然欢迎更好的解决方案!):

将大小计算集成到Connected Component Algorithm。

在 Connected Component 算法中,我们生成一个新图像,其中有标签(数字)而不是黑色像素。一个区域的所有像素都有相同的标签。

CC-Algo 的新功能是一个表格,其中存储了每个标签的像素总量。这样我就知道每个连接组件的正确大小。

Process the image from left to right, top to bottom:
1.) If the next pixel to process is white:
    do nothing
2.) If the next pixel to process is black:
    i.) If only one of its neighbors (top or left) is black, copy its label and +1 in the size table for that label.
    ii.) If both are black and have the same label, copy it and +1 in the size table for that label.
    iii.) If they have different labels Copy the label from the left. Update the equivalence table and +1 in the size table for the left label.
iv.) Otherwise, assign a new label and update the size table with that label and value 1.

• Re-label with the smallest of equivalent labels and update size table accordingly

【讨论】:

【参考方案2】:

这个问题可以通过以下方式使用洪水填充来解决:-

    保持二维布尔数组以跟踪像素是否已被访问,最初设置为 false 逐像素扫描图像。 如果像素未访问且为黑色,则对其应用泛光填充, 在填充计数期间,调用次数也会标记访问的像素,因为它们是连接的像素数。 遇到白色像素时终止填充。 Count 是包含像素的区域的大小。

Flood Fill

【讨论】:

我会测试一下,我很高兴看到 flodfill+counting 是否比 Connected Component+counting 更快。【参考方案3】:

如果我很好理解,在像您的示例这样的图像中,您希望您的算法为每个黑色形状返回 6 个值。并且,每个值都是黑色像素的数量。

我将使用的算法如下:

    反转图像的像素颜色(所以现在,您正在寻找白色像素) Find contours 在您的图像中。不要忘记只查找外部计数。 对于找到的每个轮廓: Draw each contour 在像素值为 1 的小 cv::Mat 中。然后计算此图像的 moment of order 0。 0 阶矩将是形状中的像素数。

【讨论】:

听起来很有希望,如果它比我的自制解决方案更快,我会在明天报告! 它可能比您在响应中描述的方法慢,但编码和测试会更快...而且由于时间就是金钱,也许您的经理会更喜欢我的方法(它取决于您的限制) 与处理孔洞的洪水填充相比,寻找轮廓太复杂了。

以上是关于计算二维平面中黑白形状的大小的主要内容,如果未能解决你的问题,请参考以下文章

二维码是啥?

生成二维码的三种方式

从黑白位图图像中提取路径信息

简易二维码

Java二维码的制作

二维码生成器(来源黑白猪的博客)