目录
前言
目标
函数详解
1.更改颜色空间
2.案例代码演示
3.HSV数值转换
应用演示
运行效果
参考
前言
跟着官网学习opencv-python才是基础入门的最佳选择,下文是官网的学习记录及扩展!
目标
学习如何将图像从一个颜色空间转换为另一个颜色空间,如 BGR↔Gray,BGR↔HSV等
除此之外,我们还将创建一个应用程序来提取其中的彩色对象
涉及函数:cv.cvtColor(),cv.inRange() 等。
函数详解
1.更改颜色空间
OpenCV中提供了 150 多种颜色空间转换方法。但最广泛使用的就两种: BGR↔Gray和 BGR↔HSV。
对于颜色转换,我们使用函数 cv.cvtColor(input_image, flag),其中 flag 确定转换的类型。
对于BGR↔Gray的转换,我们使用的 flag 是 cv2.COLOR_BGR2GRAY
对于BGR↔HSV的转换,我们使用的 flag 是 cv2.COLOR_BGR2HSV
使用以下命令得到所有可用的 flag:
import cv2 as cv
flags = [i for i in dir(cv) if i.startswith('COLOR_')]
print( flags )
print( len(flags) ) # 346
对于 HSV,色调Hue范围为 [0,179],饱和度Saturation 范围为 [0,255],值Value 范围为 [0,255]。不同的软件使用不同的规格。
因此,如果要将 OpenCV 值与它们进行比较,则需要对这些范围进行规范化。
2.案例代码演示
现在我们知道如何将 BGR 图像转换为 HSV,我们可以使用它来提取彩色对象。在 HSV 中,表示颜色比在 BGR 颜色空间中更容易。在我们的应用程序中,我们将尝试提取一个蓝色对象。所以这是方法:
拍摄视频的每一帧
从 BGR 转换为 HSV 色彩空间
我们对一系列蓝色的HSV图像进行阈值设置
现在单独提取蓝色对象,我们可以在该图像上做任何我们想做的事情。
import cv2
import cv2 as cv
import numpy as np
def imageProcessing(frame):
# Convert BGR to HSV
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
# Threshold the HSV image to get only blue colors
mask = cv.inRange(hsv, lower_blue, upper_blue)
# Bitwise-AND mask and original image
res = cv.bitwise_and(frame,frame, mask= mask)
cv.imshow('frame',frame)
cv.imshow('mask',mask)
cv.imshow('res',res)
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
# open video file
cap = cv.VideoCapture('../Resources/vtest.avi')
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = None
while cap.isOpened():
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# segment blue region by hsv
imageProcessing(frame)
k = cv.waitKey(5) & 0xFF
if k == ord('q') or k == 27:
break
cap.release()
cv.destroyAllWindows()
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# segment blue region by hsv
imageProcessing(frame)
k = cv.waitKey(5) & 0xFF
if k == ord('q') or k == 27:
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
3.HSV数值转换
可以使用相同的函数cv.cvtColor(), 只需传递所需的 BGR 值,而不是传递图像。
例如,要查找 HSV 值 Green:
green = np.uint8([[[0,255,0 ]]])
print(green.shape) # (1, 1, 3) 构造只有一个像素点的3通道图像
hsv_green = cv.cvtColor(green,cv.COLOR_BGR2HSV)
print( hsv_green ) # [[[ 60 255 255]]]
现在你分别以 [H-10, 100,100] 和 [H+10, 255, 255] 作为下限和上限。
除了这种方法,您还可以使用任何图像编辑工具(如 GIMP 或任何在线转换器)来查找这些值,但不要忘记调整 HSV 范围。
应用演示
利用滑动条Trackbar实现对图像的HSV颜色分割处理,方便我们对ROI区域筛选:
import numpy as np
import cv2 as cv
def nothing(x):
pass
# Create a black image, a window
img = cv.imread('../Resources/moon.jpg')
cv.namedWindow('image')
# create trackbars for color change
cv.createTrackbar('Hmin','image',0,179,nothing)
cv.createTrackbar('Hmax','image',179,179,nothing)
cv.createTrackbar('Smin','image',0,255,nothing)
cv.createTrackbar('Smax','image',255,255,nothing)
cv.createTrackbar('Vmin','image',0,255,nothing)
cv.createTrackbar('Vmax','image',255,255,nothing)
# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing)
while(1):
# cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == 27:
break
# get current positions of four trackbars
Hmin = cv.getTrackbarPos('Hmin','image')
Hmax = cv.getTrackbarPos('Hmax', 'image')
Smin = cv.getTrackbarPos('Smin', 'image')
Smax = cv.getTrackbarPos('Smax','image')
Vmin = cv.getTrackbarPos('Vmin', 'image')
Vmax = cv.getTrackbarPos('Vmax','image')
s = cv.getTrackbarPos(switch,'image')
if s == 0:
imgHSV=cv.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([Hmin, Smin, Vmin])
upper = np.array([Hmax, Smax, Vmax])
# 获得指定颜色范围内的掩码
mask = cv2.inRange(imgHSV, lower, upper)
# 对原图图像进行按位与的操作,掩码区域保留
imgResult = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow('image', imgResult)
cv.destroyAllWindows()
运行效果
下图为代码运行效果
从夜空中分割处月亮和星星