基于连通域标记的目标数字分割 |
您所在的位置:网站首页 › 连通域分析算法 › 基于连通域标记的目标数字分割 |
1 引言
最近使用传统方法应用于实际生活中的问题,受到了大家一致的关注。 嗯嗯,应该是一致的关注。 那么我们今天来研究一个新的好玩的方向,就是基于二值图像进行连通域标记和分析,从而解决数字分割的问题。 问题描述: 从下图左侧图像中,分割出数字1的图像,如右侧所示: 这里我们直接读取灰度图像,需要注意的是需要将其转化为float型数据. 这是因为我们后面有些操作可能会将像素值超过[0,255]范围, 代码如下: image = cv2.imread(image_file, cv2.IMREAD_GRAYSCALE) image = image.astype(np.float32)结果如下: 这里我们使用一些滤波器(低通滤波器,保留低频噪声,滤除高频噪声). 以下为opencv中常用的去噪函数: ksize = 5 # Some odd integer blurred_image = cv2.blur(image, (ksize, ksize)) # Mean blur blurred_image = cv2.GaussianBlur(image, (ksize, ksize), 0) blurred_image = cv2.medianBlur(image, ksize) blurred_image = cv2.biliteralFilter(imag, 9, 75, 75) # Read the docs这里经过尝试,我们选用高斯滤波器,kernel size = 5 ,代码如下: nr_image = cv2.GaussianBlur(image, (5, 5), 0)结果如下: 我们发现上图中,光照不均匀,有的区域偏亮,有的区域偏暗,这里我们采用大 kernel size的滤波器来生成背景图. 经过尝试发现使用 kernel size=21的高斯滤波器依然工作良好. 相应代码如下: background = cv2.GaussianBlur(nr_image, (21, 21), 0)结果如下: 直接使用减法,原图减去背景取可以得到前景图,但是前景图的像素值均接近于0,这里采用归一化在缩放的方式将结果重新映射回去. 代码如下: br_image = nr_image - background br_image = 255*(br_image - np.min(br_image)) / (np.max(br_image) - np.min(br_image)) br_image = br_image.astype(np.uint8)结果如下:
为了获取合适的阈值,这里我们首先查看上图图像的灰度直方图,然后从中选择合适的阈值. 灰度直方图如下: 观察上图,直方图中间有一个大的尖峰,可以看作大部分为背景的像素点数. 我们感兴趣的前景物体相比背景更暗,所以我们选择保留该阈值下的像素点,同时我们需要将图像由 bool 型转换为 int 型方便后续使用.代码如下: threshold = 149 thr_image = (br_image lower_threshold, stats[:, 4] |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |