每当看到图像时,它通常都是由各种元素和目标组成的。在某些情况下,可能会想要从图像中提取某个特定的对象,大家会怎么做?首先会想到的是进行crop相关的操作,这在某种程度上是可行的,但是这通常也会有一些不相关的像素会被包括在内,我确信大多情况下不希望这样。事实上,可以使用图像处理技术来获得感兴趣的物体。
图像分割是指将图像划分为其组成部分或子对象的过程。常见的技术包括边缘检测、阈值处理、基于区域的分割等。
HSV颜色空间
目标是通过HSV颜色空间来分割每个bag袋子。但是要怎么做呢?一般来说,HSV代表色调、饱和度和亮度,稍后将在分割图像时使用来自HSV颜色空间的信息。
首先通过以下代码将RGB图像转换为HSV的形式:
from skimage.io import imread, imshow
from skimage.color import rgb2hsv
import matplotlib.pyplot as plt
from PIL import Image
bags = Image.open('img_3.png')
bags_hsv = rgb2hsv(img)
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')
plt.show()
D:\anaconda\envs\yolov5\python.exe E:\yolo项目\Opencv-project-main\Opencv-project-main\CVZone\guangliu\two.py
Traceback (most recent call last):
File "E:\yolo项目\Opencv-project-main\Opencv-project-main\CVZone\guangliu\two.py", line 7, in <module>
bags_hsv = rgb2hsv(bags)
File "D:\anaconda\envs\yolov5\lib\site-packages\skimage\color\colorconv.py", line 248, in rgb2hsv
arr = _prepare_colorarray(rgb)
File "D:\anaconda\envs\yolov5\lib\site-packages\skimage\color\colorconv.py", line 145, in _prepare_colorarray
raise ValueError(msg)
ValueError: the input array must be have a shape == (.., ..,[ ..,] 3)), got (683, 932, 4)
Process finished with exit code 1
这个报错是由于rgb2hsv函数期望的输入是一个RGB图像,其形状应该是(高度, 宽度, 3),表示三个颜色通道。然而,图像似乎具有四个通道,可能是RGBA格式(RGB+Alpha,表示透明度)。
上一篇文章的解决办法依然有效:
# 将图像转换为RGB模式
img = bags.convert('RGB')
from skimage.io import imread, imshow
from skimage.color import rgb2hsv
import matplotlib.pyplot as plt
from PIL import Image
bags = Image.open('img_3.png')
# 将图像转换为RGB模式
img = bags.convert('RGB')
bags_hsv = rgb2hsv(img)
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')
plt.show()
结果:
然而,上述灰度图对我们目前还没有太多的帮助。我们需要获得每个HSV通道的强度值,以帮助指导我们稍后进行分割。为此,通过实现以下代码创建了一个彩色条:
from skimage.io import imread, imshow
from skimage.color import rgb2hsv
import matplotlib.pyplot as plt
from PIL import Image
bags = Image.open('img_3.png')
# 将图像转换为RGB模式
img = bags.convert('RGB')
bags_hsv = rgb2hsv(img)
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()
plt.show()
哇!看到右边的彩色条了吗?我们将在分割bag时参考这一点。下蒙版(参考色调通道)
上蒙版(参考色调通道)
饱和度遮罩(指透明度通道)
在选择阈值时,请注意查看彩色条。例如,如果我们正在分割蓝色袋子。合适的下掩模值和上掩模值将分别为0.6和0.7。
基于上述分析,我们来使用以下代码对蓝色bag袋进行分割,代码如下:
在这里插入代码片
D:\anaconda\envs\yolov5\python.exe E:\yolo项目\Opencv-project-main\Opencv-project-main\CVZone\guangliu\two.py
Traceback (most recent call last):
File "E:\yolo项目\Opencv-project-main\Opencv-project-main\CVZone\guangliu\two.py", line 20, in <module>
red = bags[:, :, 0] * mask
TypeError: 'PngImageFile' object is not subscriptable
Process finished with exit code 1
可以使用 numpy.asarray() 方法将 PIL Image 转换为 Numpy 数组。
from skimage.io import imread, imshow
from skimage.color import rgb2hsv
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
# 打开图像文件
bags = Image.open('img_3.png')
# 将图像转换为RGB模式
img = bags.convert('RGB')
# 将 PIL Image 转换为 Numpy 数组
bags_array = np.asarray(img)
# 将图像转换为HSV颜色空间
bags_hsv = rgb2hsv(bags_array)
# 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 saturation channel (in the colorbar)
saturation_mask = bags_hsv[:, :, 1] > 0.3
mask = upper_mask * lower_mask * saturation_mask
red = bags_array[:, :, 0] * mask
green = bags_array[:, :, 1] * mask
blue = bags_array[:, :, 2] * mask
bags_masked = np.dstack((red, green, blue))
imshow(bags_masked)
plt.show()
修改对应的掩码
# 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 saturation channel (in the colorbar)
saturation_mask = bags_hsv[:, :, 1] > 0.6
#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
#refer to hue channel (in the colorbar)
lower_mask = bags_hsv[:,:,0] > 0.3
#refer to hue channel (in the colorbar)
upper_mask = bags_hsv[:,:,0] < 0.5
#refer to transparency channel (in the colorbar)
saturation_mask = bags_hsv[:,:,1] > 0.6
HSV颜色空间在图像分割领域的用途,并通过一个具体的示例来对其进行讲解,主要通过分析HSV相应的通道上不同的阈值来对设置不同的掩码,进而对不同的对象进行分割。
通过对应颜色的阈值判断数值改变颜色。