我们来看一个简单的需求,比如说下面这幅图像:
这是一幅公路上的行车图像,假如我们想把车道线提取出来,该怎么办呢?
我们观察,发现车道线是黄色的或者白色的。那么我们想到的是可以把行车图像中的黄色颜色和白色颜色提取出来。
我们知道,在RGB颜色模式中,白色是[255,255,255],黄色是[255,255,0]。但是行车图像中的白色和黄色可不完全是纯白色和纯黄色。因此,需要在一定的范围内选择。
- import cv2
- import numpy as np
- img = cv2.imread("lane_lines.jpg")
- # yellow and white color selection
- lower_white = np.array([200, 200, 200])
- upper_white = np.array([255, 255, 255])
-
- lower_yellow = np.array([200, 200, 0])
- upper_yellow = np.array([255, 255, 50])
-
- white = cv2.inRange(img, lower_white, upper_white)
- yellow = cv2.inRange(img, lower_yellow, upper_yellow)
-
- cv2.imshow("white", white)
- cv2.imshow("yellow", yellow)
-
- cv2.imwrite("white.png", white)
- cv2.imwrite("yellow.png", yellow)
- cv2.waitKey()
上图为提取的白色颜色,下图为提取的黄色颜色。我们可以看到。白色提取出来了,但黄色并没有提取出来。这是因为RGB颜色模型的局限性,需要R/G/G三个值协同配合才能混合成颜色,这意味着需要考虑至少2个变量的配比问题,非常的麻烦。
所以,通过RGB颜色模型进行颜色选择的难度非常大。
那有没有其它办法呢?我们知道,RGB只是颜色表达模型中的一种,虽然是最常见的一种。但还有其它颜色表达模型,例如HSV /HSL等。
我们看看HSV颜色模型。H表示色度,S表示饱和度,V表示亮度。与RGB一样,也是3个分量。但H分量是唯一与颜色本质相关的分量,只要固定了H值范围,那么表现的颜色就会基本固定。白色和黑色则主要通过调整饱和度S和亮度V来实现,很显然,白色最亮,黑色最暗。
当然,用HSV取颜色的前提是图像是用HSV表示的,用OpenCV转换下。
- img = cv2.imread("lane_lines.jpg")
- img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
- # yellow and white color selection
- lower_white = np.array([0, 0, 200])
- upper_white = np.array([180, 40, 255])
-
- lower_yellow = np.array([15, 50, 50])
- upper_yellow = np.array([35, 255, 255])
-
- white = cv2.inRange(img, lower_white, upper_white)
- yellow = cv2.inRange(img, lower_yellow, upper_yellow)
-
- cv2.imshow("white", white)
- cv2.imshow("yellow", yellow)
- cv2.waitKey()
-
上图为提取的白色颜色区域,下图为提取的黄色颜色区域,可以看到这次黄色区域被提取出来了。可以很明显的看到车道线了。当然,你也可以转换成HSL颜色空间来取颜色。
同样,如果我们在绘图时,需要随机选择颜色怎么办呢?例如绘制10种不同的曲线,随机选择10种不同的颜色进行绘制。用RGB颜色空间随机选择当然是可以的。例如R、G、B分别在[0,255]之间进行随机,但是这样得到的颜色不太友好,有时偏暗,有时外观不佳。
而在HSV颜色空间中,可以只对色度H进行随机,而饱和度S和亮度V都用最高值,这样随机得到的颜色会更加鲜艳明亮。
- import matplotlib.pyplot as plt
- num_color = 9
- height, width = 100, 100
- colors = []
- for i in range(num_color):
- hsv = np.zeros((height, width, 3), dtype=np.uint8)
- hsv[hsv >= 0] = 255
- hsv[:, :, 0] = int(i / num_color * 180)
- RGB = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
- plt.subplot(3, 3, i + 1)
- plt.imshow(RGB)
- plt.axis("off")
- plt.show()
-