python模仿skimage包的函数去除边缘大面积噪点

python模仿skimage包中的remove_small_objects()函数实现去除边缘大面积噪点

图片难免会有噪声,python的skimage包提供了名为morphology的子模块,可以通过调用该模块的remove_small_objects()进行图片去噪。具体使用方法请查看:

图像处理中媲美matlab的python包——scikit-image(skimage)包的用法详解

但是,在实际情况中,我们往往也会遇到需要去除的噪点和图像本身前景的连通域大小相同的情况,比如·这样:

这里写图片描述

对于上图来说,希望保留中心完整的鱼,但是对噪点连通域的阈值大小很难把握,稍有不慎就会把需要保留的完整鱼的图像一并删掉。除此之外,甚至还会有中心鱼的连通域小于需要去除的鱼的连通域大小的情况,增加了噪点的去除难度。

但是,可能因为这个需求还是有些小众,skimage包并没有提供这样的函数,这样就需要自己实现一个,实现过程借鉴了remove_small_objects()的源码,利用与中心坐标的距离作为是否删除该连通域的条件,具体实现如下:

#这里以输入大小为160*160的图像为例
def remove_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))
        # center= (80,80)
        for k in range(num):
            if k == 0:
                temp_centroid = jj[0].centroid  # 注意这是个元组
                save_index = 1
            else:
            #以下求距离的时候有些复杂,应该可以调用求距离函数
                tp1 = ((temp_centroid[0] - 80) ** 2) + ((temp_centroid[1] - 80) ** 2)#需要保留的连通域
                tp2 = ((jj[k].centroid[0] - 80) ** 2) + ((jj[k].centroid[1] - 80) ** 2)#下一个连通域
                if  tp1 > tp2 and jj[k].area > 200:
                    temp_centroid = jj[k].centroid  # 注意这是个元组
                    save_index = k+1
        del_array[save_index] = 1
        del_mask = del_array[labels]
        out = img * del_mask
        is_del = True
    return out ,is_del

猜你喜欢

转载自blog.csdn.net/u013044310/article/details/80274843