1. 引言
每当我们看到图像时,它通常都是由各种元素和目标组成的。在某些情况下,我们可能会想要从图像中提取某个特定的对象,大家会怎么做?首先我们会想到的是进行crop
相关的操作,这在某种程度上是可行的,但是这通常也会有一些不相关的像素会被包括在内,我确信大多情况下我们不希望这样。事实上,我们可以使用图像处理技术来获得感兴趣的物体。
闲话少说,我们直接使用Python
来进行图像分割。
2. 图像分割概念
图像分割是指将图像划分为其组成部分或子对象的过程。常见的技术包括边缘检测、阈值处理、基于区域的分割等。在本文中,让我们专注于通过HSV颜色空间使用彩色图像分割来分割我们的图像。
在此之前,我们需要安装以下库,然后再进行相关的操作。
from skimage.io import imread, imshow
from skimage.color import rgb2hsv
from matplotlib.pyplot as plt
同时我们使用的测试图像如下:
3. HSV颜色空间
我们的目标是通过HSV
颜色空间来分割每个bag
袋子。但是要怎么做呢?一般来说,HSV
代表色调、饱和度和亮度,我们稍后将在分割图像时使用来自HSV
颜色空间的信息。
但在分割过程之前,让我们首先通过以下代码将RGB
图像转换为HSV
的形式:
bags_hsv = rgb2hsv(bags)
fig, ax = plt.subplots(1, 3, figsize=(12,4))
ax[0].imshow(bags_hsv[:,:,0], cmap='gray')
ax[0].set_title('Hue')
ax[1].imshow(bags_hsv[:,:,1], cmap='gray')
ax[1].set_title('Saturation')
ax[2].imshow(bags_hsv[:,:,2], cmap='gray')
ax[2].set_title('Value');
结果如下:
然而,上述灰度图对我们目前还没有太多的帮助。我们需要获得每个HSV
通道的强度值,以帮助指导我们稍后进行分割。为此,通过实现以下代码创建了一个彩色条:
fig, ax = plt.subplots(1, 3, figsize=(15, 5))
ax[0].imshow(bags_hsv[:,:,0],cmap='hsv')
ax[0].set_title('hue')
ax[1].imshow(bags_hsv[:,:,1],cmap='hsv')
ax[1].set_title('transparency')
ax[2].imshow(bags_hsv[:,:,2],cmap='hsv')
ax[2].set_title('value')
fig.colorbar(imshow(bags_hsv[:,:,0],cmap='hsv'))
fig.tight_layout()
结果如下:
4. 挑选阈值
哇!看到右边的彩色条了吗?我们将在分割bag
时参考这一点。在实现代码之前,让我们首先设置掩码的阈值:
- 下蒙版(参考色调通道)
- 上蒙版(参考色调通道)
- 饱和度遮罩(指透明度通道)
在选择阈值时,请注意查看彩色条。例如,如果我们正在分割蓝色袋子。合适的下掩模值和上掩模值将分别为0.6和0.7。因此,换句话说,它只会得到蓝色像素值,而忽略其余的值。
5. 分割蓝色目标
基于上述分析,我们来使用以下代码对蓝色bag
袋进行分割,代码如下:
#refer to hue channel (in the colorbar)
lower_mask = bags_hsv[:,:,0] > 0.6
#refer to hue channel (in the colorbar)
upper_mask = bags_hsv[:,:,0] < 0.7
#refer to transparency channel (in the colorbar)
saturation_mask = bags_hsv[:,:,1] > 0.3 mask = upper_mask*lower_mask*saturation_mask
red = bags[:,:,0]*mask
green = bags[:,:,1]*mask
blue = bags[:,:,2]*mask
bags_masked = np.dstack((red,green,blue))
imshow(bags_masked)
结果如下:
哇,是不是看上去很完美!
6. 分割黄色目标
有了上述经验,我们接着来分割黄色目标,只需要修改对应的掩码即可,代码如下:
#refer to hue channel (in the colorbar)
lower_mask = bags_hsv[:,:,0] > 0.1
#refer to hue channel (in the colorbar)
upper_mask = bags_hsv[:,:,0] < 0.2
#refer to transparency channel (in the colorbar)
saturation_mask = bags_hsv[:,:,1] > 0.6 mask = upper_mask*lower_mask*saturation_mask
red = bags[:,:,0]*mask
green = bags[:,:,1]*mask
blue = bags[:,:,2]*mask
bags_masked = np.dstack((red,green,blue))
imshow(bags_masked)
结果如下:
7. 分割橙色目标
更进一步,我们修改阈值来分割橙色目标,代码如下:
#refer to hue channel (in the colorbar)
lower_mask = bags_hsv[:,:,0] > 0.0
#refer to hue channel (in the colorbar)
upper_mask = bags_hsv[:,:,0] < 0.09
#refer to transparency channel (in the colorbar)
saturation_mask = bags_hsv[:,:,1] > 0.4 mask = upper_mask*lower_mask*saturation_mask
red = bags[:,:,0]*mask
green = bags[:,:,1]*mask
blue = bags[:,:,2]*mask
bags_masked = np.dstack((red,green,blue))
imshow(bags_masked)
结果如下:
8. 分割绿色目标
最后,我们修改阈值来分割剩下的绿色目标,代码如下:
#refer to hue channel (in the colorbar)
lower_mask = bags_hsv[:,:,0] > 0.0
#refer to hue channel (in the colorbar)
upper_mask = bags_hsv[:,:,0] < 0.09
#refer to transparency channel (in the colorbar)
saturation_mask = bags_hsv[:,:,1] > 0.4 mask = upper_mask*lower_mask*saturation_mask
red = bags[:,:,0]*mask
green = bags[:,:,1]*mask
blue = bags[:,:,2]*mask
bags_masked = np.dstack((red,green,blue))
imshow(bags_masked)
结果如下:
9. 结论
本文通过介绍HSV颜色空间在图像分割领域的用途,并通过一个具体的示例来对其进行讲解,主要通过分析HSV相应的通道上不同的阈值来对设置不同的掩码,进而对不同的对象进行分割,并给出了相应的代码实现。
您学废了嘛?