图片难免会有噪声,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= np.array([80,80])
for k in range(num):
if k == 0:
temp_centroid = np.array(jj[0].centroid,dtype=float) #将元组转换成array
save_index = 1
else:
k_centroid = np.array(jj[k].centroid, dtype=float) # 将元组转换成array
#计算距离
tp1 = np.sqrt(np.sum(np.square(temp_centroid-center)))
tp2 = np.sqrt(np.sum(np.square(k_centroid - center)))
if tp1 > tp2 and jj[k].area > 200:
temp_centroid = 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