如何去除图片中的小平行线?

3

在二值化后,我有一张黑白图像。然后我得到了下面这张图像:

http://ifotos.pl/zobacz/ipng_xhnxhrh.png/

如何使用OpenCV去除长曲线旁边的小平行线?可以通过删除所有小对象来消除它们,但我只想删除小的平行线。


1
你能在二值化之前发布图像吗?通过二值化,您会丢失信息。 - Dr. belisarius
6个回答

2
这看起来像是Canny伪影(或某种环绕伪影)。有几种方法可以消除它们。
一种经验但不太计算密集的方法是定位所有小特征,并将它们与由[+/-]X,[+/-]Y偏移的相同图像叠加。如果该特征与移动后的图像完全重合,即白色特征中的所有像素也在移动后的图像中都是白色,则可能存在伪影。
要评估特征的“小”,可以使用基本的泛洪填充。这种方法很便宜,因为您可以使用指针模拟移位,而无需真正分配四个移位图像。它容易产生误报,因为您确实具有小的平行线,并且在伪影非常大时容易产生误报。
另一种方法是使用不同阈值两次对原始图像进行海报化。虽然“真实”线条将保持在一起,但环绕伪像将具有不同的强度。此时,您需要评估图像差异,并将所有距离给定阈值远的特征视为“伪影”。这需要更多的计算,并产生更好的结果,但取决于您的原始图像的工作流程是什么。
重新评估工作流程(更改边缘检测阶段)可能完全避免创建伪影。

2
使用cvBlobslib库检测白色斑点作为斑块... cvBlobslib库提供了一些函数,可以找出斑块的不同特征,如面积和椭圆度...所以如果您只想要平行于长曲线的较小斑块...那么..

  1. 基于斑块覆盖的面积或周长(即斑块的轮廓长度),获取长曲线...
  2. 在拟合椭圆后获取长曲线的椭圆度或主轴方向(cvBlobslib库会为您完成..!!)...
  3. 过滤所有那些区域小于阈值且与长曲线具有相同方向的斑块....

希望这可能有效..


1
这里是利用平行线增加边缘密度的步骤。
1)在灰度图像上应用自适应阈值,以获得许多边缘。
2)进行3x3(或实验但较小的)形态学操作来侵蚀。
3)使用“逻辑非”获取边缘密度。
4)应用类似于3x3或5x5的“膨胀”。它将扩大边缘以合并并形成区域。
5)现在进行7x7(或实验以获得比上次膨胀更高的结果)形态学操作。它将删除大部分不需要的区域、长线和小杂散区域。
输出是去除区域的掩码。您可以在原始图像上应用轮廓检测,并删除与掩码匹配位置的轮廓对象,以进行高精度去除。 或者,如果您不需要高精度结果,只需与掩码的“非”进行“与”运算即可。

1

如果您事先知道您的线条方向,您可以使用适合您需求的自定义结构元素进行形态学闭运算。

请参见wikipedia上的morphomat。

请参见documentation上的opencv。


是的,我可以使用形态学,但那会改变所有对象,但我只想在这些并行对象上执行。 - user1666649
将形态学操作限制在靠近主对角线的 ROI 区域内。 - remi

1
也许与其他人说的类似,但用更简单的话来说:由于小线条的粗细似乎大约是长线条的一半,如果您不真正关心保留长线条的方式,您可以多次应用一个简单的算法“使线条变细”,直到小线条消失。您需要做的是逐像素扫描图像,并在检测到黑色像素上方、下方、左侧或右侧的白色像素时,在向量中存储其坐标。遍历整个图像后,将向量中指定坐标的所有像素设为黑色。您可以经验性地定义一些阈值来确定此算法的迭代次数。

0

为什么不这样做:

  1. 找到长曲线(使用findContours并按大小过滤)。
  2. 找到小曲线。
  3. 对于每个长曲线,计算每个小曲线和长曲线之间的每个点的最小距离。
  4. 计算这些最小距离的平均值和标准差。
  5. 拒绝那些平均最小距离太大或者最小距离的标准差太大的小曲线。

如果您首先将图像骨架化,则结果可能会更好(更快)。

祝您好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接