代码参考:https://blog.csdn.net/u014264373/article/details/119486850
通过卷积神经网络预测图像的分割结果时,会发现分割外部出现了小面积的连通域。
常识告诉我们,这么小的物体一定不是我们的分割目标,因此,我们通过后处理的方法把它过滤掉,可以提高分割准确度。
这种小面积的图形,可以使用cv2.connectedComponentsWithStats的连通域统计分析方法。
函数:connectedComponentsWithStats(image, connectivity=8, cv2.CV_32S)
功能:求得最大连通域。
输入:假如image为128x128大小的图片,有7个连通域。
返回:
num_labels:连通域个数,此处为7;
labels:大小128x128,标记图,图中不同连通域使用不同的标记(当前像素是第几个轮廓),和原图宽高一致;
stats:大小7x5,每行5个数分别对应各个轮廓的x,y,width,height和面积。注意0的区域标识的是background;
centroids:大小7x2,分别对应各个轮廓的中心点。
此时可比较stats中各连通域的面积与阈值面积(此处取平均面积area_avg),保留大于阈值的面积即可。
import numpy as np
import cv2 as cv
# 加载图片
img = cv.imread('image_name.png')
# 灰度化
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 二值化
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
# 寻找连通域
num_labels, labels, stats, centroids = cv.connectedComponentsWithStats(thresh, connectivity=8)
# 计算平均面积
areas = list()
for i in range(num_labels):
areas.append(stats[i][-1])
print("轮廓%d的面积:%d" % (i, stats[i][-1]))
area_avg = np.average(areas[1:-1])
print("轮廓平均面积:", area_avg)
# 筛选超过平均面积的连通域
image_filtered = np.zeros_like(img)
for (i, label) in enumerate(np.unique(labels)):
# 如果是背景,忽略
if label == 0:
continue
if stats[i][-1] > area_avg :
image_filtered[labels == i] = 255
cv.imshow("image_filtered", image_filtered)
cv.imshow("img", img)
cv.waitKey()
cv.destroyAllWindows()
原图共有7个连通域(包括6个前景+1个背景)
过滤掉面积小于平均面积的连通域
产出不易,喜欢的话点个赞吧~~