skimage包的小优化(2):模仿remove_small_objects()函数保留图片中连通域最大的区域

python模仿remove_small_objects()函数保留图片中连通域最大的区域

skimage包的morphology子模块中,提供了一个remove_small_objects()函数,可以通过自己设定的连通域面积阈值有效去掉图片中的噪点,但是在具体使用过程中会发现:这个函数使用起来还有诸多的不便,好在这个函数的源代码并不长,在在skimage包的小优化(1):模仿remove_small_objects()函数去除图片边缘不感兴趣区域
中,我就是通过模仿remove_small_objects()的源代码,实现了判断连通域与中心坐标的位置远近来去除图片边缘大面积噪声。很好地解决了去掉图片边缘不感兴趣区域的问题。

但是最近在使用过程中,我有发现了另外一个问题:在使用remove_small_objects()函数的时候,必须要指定一个连通域的面积阈值(这个函数的具体使用方法见:scikit-image(skimage)包的用法详解),而很多时候我们根本不知道这个阈值到底要设为多少。而有时候,我们如果已经知道图片中只有那块连通域面积最大的区域是我们想要的,那么,只需要保留这块区域,其他的都当作噪点删掉即可,没必要非要确定一个面积阈值。

具体实现如下:

##输入:一张二值图像,无须指定面积阈值,
##输出:会返回保留了面积最大的连通域的图像
def save_max_objects(img):
    labels = measure.label(img)  # 返回打上标签的img数组
    jj = measure.regionprops(labels)  # 找出连通域的各种属性。  注意,这里jj找出的连通域不包括背景连通域
    # is_del = False
    if len(jj) == 1:
        out = img
        # is_del = False
    else:
        # 通过与质心之间的距离进行判断
        num = labels.max()  #连通域的个数
        del_array = np.array([0] * (num + 1))#生成一个与连通域个数相同的空数组来记录需要删除的区域(从0开始,所以个数要加1)
        for k in range(num):#TODO:这里如果遇到全黑的图像的话会报错
            if k == 0:
                initial_area = jj[0].area
                save_index = 1  # 初始保留第一个连通域
            else:
                k_area = jj[k].area  # 将元组转换成array

                if initial_area < k_area:
                    initial_area = k_area
                    save_index = k + 1

        del_array[save_index] = 1
        del_mask = del_array[labels]
        out = img * del_mask
        # is_del = True
    return out
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值