我正在尝试在OpenCV中寻找与Matlab的Bwareaopen函数类似或等效的功能。
在MatLab中,Bwareaopen(image,P)从二进制图像中删除所有连接组件(对象),这些对象少于P个像素。
在我的单通道图像中,我想简单地删除不属于更大区域的小区域。有没有什么简单的方法来解决这个问题?
CBlobResult
对二值图像进行连通区域标记,然后调用Filter
按照你的条件排除斑块。虽然没有这样的功能,但您可以按照以下步骤进行操作: 1)查找轮廓 2)查找轮廓面积 3)过滤所有面积小于阈值的外部轮廓 4)创建新的黑色图像 5)在其上绘制剩余轮廓 6)使用原始图像进行遮罩处理
我曾经遇到同样的问题,并编写了一个使用connectedComponentsWithStats()函数的功能:
def bwareaopen(img, min_size, connectivity=8):
"""Remove small objects from binary image (approximation of
bwareaopen in Matlab for 2D images).
Args:
img: a binary image (dtype=uint8) to remove small objects from
min_size: minimum size (in pixels) for an object to remain in the image
connectivity: Pixel connectivity; either 4 (connected via edges) or 8 (connected via edges and corners).
Returns:
the binary image with small objects removed
"""
# Find all connected components (called here "labels")
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(
img, connectivity=connectivity)
# check size of all connected components (area in pixels)
for i in range(num_labels):
label_size = stats[i, cv2.CC_STAT_AREA]
# remove connected components smaller than min_size
if label_size < min_size:
img[labels == i] = 0
return img
关于connectedComponentsWithStats()的澄清,请参见:
如何使用OpenCV删除小的连接对象
https://www.programcreek.com/python/example/89340/cv2.connectedComponentsWithStats
https://python.hotexamples.com/de/examples/cv2/-/connectedComponentsWithStats/python-connectedcomponentswithstats-function-examples.html
与您的问题最接近的OpenCV解决方案是形态学闭合或开放。
假设您的图像中有需要去除的白色区域。您可以使用形态学开放。开放是侵蚀+膨胀,按顺序执行。侵蚀是指缩小图像中的白色区域。膨胀是(相反的)其中图像中的白色区域被扩大。当您执行开放操作时,您的小白色区域会被侵蚀直到消失。较大的白色特征不会消失,但将从边界侵蚀。随后的膨胀步骤恢复它们的原始大小。然而,由于在侵蚀步骤中消失了小元素,因此它们在膨胀后的最终图像中不会出现。
例如,考虑这个image,我们想要删除小的白色区域,但保留3个大的白色椭圆形。运行以下代码可删除白色区域并显示干净的图像
import cv2
im = cv2.imread('sample.png')
clean = cv2.morphologyEx(im, cv2.MORPH_OPEN, np.ones((10, 10)))
cv2.imshwo("Clean image", clean)
干净的图像输出应该是 像这样。
上面的命令使用了大小为10的方形块作为内核。 您可以修改此以满足您的要求。 您甚至可以使用函数getStructuringElement()生成更高级的内核。
请注意,如果您的图像是反转的,即背景为白色噪声的黑色,您只需要使用形态学闭运算(cv2.MORPH_CLOSE方法)而不是开运算。 这将颠倒操作顺序-首先侵蚀图像,然后扩张。
.cpp
和.h
文件添加到您的项目中,#include
相应的头文件,然后就可以从那里开始了。 - tzaman