图像分割
在滤波、变换、缩放等任务中,图像分割具有重要的意义。图像分割是将不同的对象划分为不同的部分,并将这些区域以明显的颜色或者记号标记出来。图像分割是使用轮廓、边界框等概念进行其他高级计算机视觉任务(例如对象分类和对象检测)的基础。良好的图像分割为我们后续的图像分类以及检测奠定了基础。
计算机视觉中三种不同的图像分割类型:
1. 颜色分割或阈值分割
2. 语义分割
3. 边缘检测
本次将介绍基于颜色的图像分割,并通过OpenCV实现。(准确性落后于DL,运行速度快于DL)
颜色分割可以用于检测身体肿瘤、从森林或海洋背景中提取野生动物的图像,或者从单一的背景图像中提取其他彩色物体。下面即是图像分割的几个典型的示例:
从上面的示例可以看出尽管OpenCV速度快,但是图像分割的结果并不是非常理想。
下面以一张鸟的图片进行介绍OpenCV对图片进行颜色分割,目标是通过对鸟进行颜色分类来提取这只鸟。
首先打入完成项目的所需包和图片
import cv2 as cv
img = cv.imread("images/bird.png")
滤波处理
使用滤波器对该图像进行预处理,对图像进行模糊操作,以减少图像中的细微差异。在OpenCV中提供了4个内置的滤波器,以满足用户对图像进行不同的滤波的需求。这种滤波器的使用方式在下面的代码中给出。但是,针对于本文中需要分割的图像,我们并不需要将4种滤波器都使用。
blur = cv.blur(img, (5, 5))
blur0 = cv.medianBlur(blur, 5)
blur1 = cv.GaussianBlur(blur0, (5, 5), 0)
blur2 = cv.bilateralFilter(blur1, 9, 75, 75)
下图是滤波模糊后的结果:
颜色空间转换(BGRtoHSV)
接下来需要将图片从BGR转换为HSV(色相饱和度值)。从BGR空间中转到HSV空间中的原因在于像素B,G和R的取值与落在物体上的光相关,因此这些值也彼此相关,无法准确描述像素。相反,HSV空间中,三者相对独立,可以准确描述像素的亮度,饱和度和色度。
hsv = cv.cvtColor(blur2, cv.COLOR_BGR2HSV
这个操作看似很小,但当我们尝试找到要提取的阈值或像素范围时,它可以使操作变得简单。
阈值分割
这里主要是确定要提取的所有像素的阈值。需要在所有像素中获取期望的像素,具体步骤如下:
low_blue = np.array([55, 0, 0]
high_blue = np.array([118, 225, 225])
mask = cv.inRange(hsv, low_blue, high_blue)
上面的代码中的mask是将所有不在描述对象范围内的其他像素进行覆盖。程序运行效果如下:
接下来、进行最后的操作将mask作为边界的图像。得出最后的实现效果:
总结
可以看出这效果总体来说还是可以的,但是细节部分还是需要改善,比如看图片可知鸟的眼睛部分被抠掉了,尾部蓝色部分也抠出来了。
通过上面的方式,我们基本可以实现基于颜色的图像分割,感兴趣的的小伙伴可以通过上面的代码和步骤进行尝试,看看能否满足自己的图像分割需求。