如何使用opencv或其他c ++库查找图像中(邻接)标签之间的连接关系?
Posted
技术标签:
【中文标题】如何使用opencv或其他c ++库查找图像中(邻接)标签之间的连接关系?【英文标题】:How to find connect relation between (adjacency) labels in image with opencv or other c++ library? 【发布时间】:2022-01-24 04:23:49 【问题描述】:我有一张带标签的图片,如下所示:
0 0 0 0 0 0
1 1 0 2 2 3
1 0 0 2 3 3
4 5 0 6 0 0
现在我尝试在图像中查找连接关系(邻接),例如 1 连接到 4、2 连接到 3 和 6。 0 是背景。 现在我迭代所有像素来记录连接。但我想知道是否有一个函数可以做到这一点,因为我目前的方法在大图像中效果不佳。 谢谢大家的回复!
【问题讨论】:
为了获得更有用的答案,我建议您展示您当前的实现(但请先阅读minimal reproducible example),并准确解释为什么它“在大图上效果不佳”(是太慢了)? 【参考方案1】:这是一个大问题,所以我只分享我知道的 2 种方法,您可以使用它们来解决这个问题。一种方法将使用图像处理算法,另一种方法使用图形和 DSU 的概念。
方法一(基于图像处理)
首先,获取当前图片(标注图片)的掩码图片。如果当前图像中对应的像素为 0,则此蒙版图像将包含 0 的像素值,如果当前图像中的对应像素大于 0,则它将包含 255 的像素值。 现在,在这个蒙版图像中,使用带有“RETR_EXTERNAL”标志的 OpenCV 函数“findContours”查找轮廓。 现在,如果每个轮廓,找到标记图像中存在的所有唯一像素值。
这将为您提供相互连接的一组数字。
方法 2(图表和 DSU)
利用DSU(Disjoint set union)数据结构的属性,获取相互连接的数字集合。您可以从this video 阅读有关 DSU 的信息。
迭代标记图像中的每个节点(像素)。对于每个节点,检查该节点的任何邻居是否大于0。如果找到,则将该节点的父节点设置为相邻节点。 您可以通过两种方法提高此算法的速度:
-
忽略已使用“已访问”标志数组设置其父节点的节点。此外,只找到每个节点的一个非零邻居。
使用上述视频末尾解释的折叠查找方法。
注意如何定义节点的“邻居”。您可以根据您的问题陈述使用 4 连接或 8 连接。
【讨论】:
方法1找到所有连接到背景的标签,这不是OP所要求的。方法 2 为每个标签找到一个邻居,而不是所有标签,并且可能仅对识别形成连接组件的所有标签组有用。一件事:找到大于0但与当前节点具有不同值的邻居。 感谢您的回复。方法 2 为我提供了一种加速算法的有效方法。以上是关于如何使用opencv或其他c ++库查找图像中(邻接)标签之间的连接关系?的主要内容,如果未能解决你的问题,请参考以下文章
如何创建 Haar Cascade(.xml 文件)以在 OpenCV 中使用?