Python OpenCV使用连通组件寻找连通区域并过滤噪声

话不多说,cv2下的连通区域函数:cv2.connectedComponentsWithStats 网上大部分都是C++教程
这里使用连通区域函数筛选出3个最大区域,然后顺手利用得到的二值化图像做腐蚀-膨胀去除毛边
注意传入的image必须是灰度图

import cv2
import numpy as np
from collections import Counter

    def postprocess(self, img):
        # 先搞成灰度图
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img_ = np.array(img.copy(), dtype=np.int8)
        connectivity = 4
        # 连通组件
        num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(img_, connectivity, cv2.CV_8U)
        # labels就是由连通区域编号组成的mask 尺寸与原图对应
        labels = np.array(labels, dtype=np.float)
        # 统计各个连通区域的元素个数并排序,这里我希望得到的图像只包括三个及以下区域,于是most_common(3)
        maxnum = Counter(labels.flatten()).most_common(3)
        maxnum = sorted([x[0] for x in maxnum])
        # 制作一个包括背景和最大n个连通区域组成的Mask
        background = np.zeros_like(labels)
        if len(maxnum) == 1:
            pass
        elif len(maxnum) == 2:
            background[labels == maxnum[1]] = 1
        else:
            background[labels == maxnum[1]] = 1
            background[labels == maxnum[2]] = 1
        #  img[background == 0] = 0 就可以得到筛选连通区域之后的图像

        # 接下来使用腐蚀-膨胀去除连通区域的毛边
        K_SIZE = 10
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (K_SIZE, K_SIZE))
        background = cv2.morphologyEx(background, cv2.MORPH_OPEN, kernel)
        background = cv2.morphologyEx(background, cv2.MORPH_CLOSE, kernel)

        img[background == 0] = 0
        #  返回灰度图
        return img

你可能感兴趣的:(Python OpenCV使用连通组件寻找连通区域并过滤噪声)