最近更新于 2022-05-16 13:24

颜色分割一般用于在单一背景的图像中提取彩色图像。

这里我随意拍的一张图片用于演示

打开本地图片,OpenCV 中图像通道顺序为 BGR,而 Matplotlib 中使用的是 RGB,所以要显示图片这里要转换一下。当然不转换也能显示,只是显示出来的颜色和原图不一样。

import cv2  # opencv-python==4.5.5
import matplotlib.pyplot as plt

bgr_img = cv2.imread('image.png')
rgb_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2RGB)
plt.imshow(rgb_img)

接着需要使用滤波器对图像进行模糊处理,减少图像中的细微差异。选下面一种就行。

blur = cv2.blur(bgr_img, (5,5))  # 均值滤波
blur = cv2.medianBlur(bgr_img, 5)  # 中值滤波
blur = cv2.GaussianBlur(bgr_img, (5,5), 0)  # 高斯滤波
blur = cv2.bilateralFilter(bgr_img, 9, 75, 75)  # 双边滤波

这里可以将模糊处理后的图像由 BGR 转为 HSV(H 色度 S 饱和度 V 亮度),可以更好的进行颜色分割。

hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

然后进行颜色分割,计算出掩码图像。根据图像背景和要分割的东西不同,这里分割的阈值范围也不同,需要进行一定的尝试。

注:mask 本身应该是黑白图像,这里的色彩是 Matplotlib 显示图片的因素。

import numpy as np

low_blue = np.array([105,0,0])
high_blue = np.array([200, 255, 255])
mask = cv2.inRange(hsv, low_blue, high_blue)

最后进行与运算,将 mask 作为背景图像

res = cv2.bitwise_and(bgr_img, bgr_img, mask=mask)
rgb_img = cv2.cvtColor(res, cv2.COLOR_BGR2RGB)
plt.imshow(rgb_img)