OpenCV---xx3(色彩物块识别)
利用Opencv在Python中进行颜色检测
我们将在本文章中尝试来检测和跟踪特定的颜色对象
HSV颜色空间
HSV颜色空间为(色相,饱和度,明度)颜色模型
其可以更紧密的与人的视觉感知颜色属性方式保持一致
因此使用Opencv跟踪某颜色 必须使用HSV模型来进行定义
在opencv的HSV颜色空间
H(色彩/色度) 的取值范围 为[0,179]
S(饱和度) [0,255]
V(亮度) [0,255]
颜色识别
对于某张图片 我们可以较为容易的得到其BGR值
我们要将其转为HSV模型
绿: R65 G193 B 144
红: R255 G102 B60
蓝: R54 G101 B217
将BGR转为HSV
np.uint8([[[b,g,r]]])
hsv_color = cv.cvtColor()
代码详细
import cv2 as cv
import numpy as np
# 掩膜获得函数
def mask_range(bgr_img):
"""
掩膜获得函数
:return: 三个颜色的mask b, g, r
"""
# BGR 颜色空间
hsv_img = cv.cvtColor(bgr_img, cv.COLOR_BGR2HSV)
green_color = np.uint8([[[144, 193, 65]]])
blue_color = np.uint8([[[217, 101, 54]]])
red_color = np.uint8([[[60, 102, 254]]])
# HSV 颜色空间
green_hsv = cv.cvtColor(green_color, cv.COLOR_BGR2HSV)
blue_hsv = cv.cvtColor(blue_color, cv.COLOR_BGR2HSV)
red_hsv = cv.cvtColor(red_color, cv.COLOR_BGR2HSV)
g_hue = green_hsv[0, 0, 0]
b_hue = blue_hsv[0, 0, 0]
r_hue = red_hsv[0, 0, 0]
g_bot_bound = np.array([g_hue - 10, 120, 100], dtype=np.uint8)
g_up_bound = np.array([g_hue + 10, 255, 255], dtype=np.uint8)
b_bot_bound = np.array([b_hue - 10, 120, 100], dtype=np.uint8)
b_up_bound = np.array([b_hue + 10, 255, 255], dtype=np.uint8)
r_bot_bound = np.array([r_hue - 5, 120, 100], dtype=np.uint8)
r_up_bound = np.array([r_hue + 10, 255, 255], dtype=np.uint8)
blue_mask = cv.inRange(hsv_img, b_bot_bound, b_up_bound)
green_mask = cv.inRange(hsv_img, g_bot_bound, g_up_bound)
red_mask = cv.inRange(hsv_img, r_bot_bound, r_up_bound)
return blue_mask, green_mask, red_mask
# 预处理函数
def pre_processing(first_mask):
# 先腐蚀 再膨胀 去除噪音
first_mask = cv.GaussianBlur(first_mask, (9, 9), 12, 12)
second_mask = cv.morphologyEx(first_mask, 0, (9, 9), iterations=2)
res_mask = cv.morphologyEx(second_mask, 1, (9, 9))
return res_mask
# 轮廓检测函数 找到最大的 且满足面积大于一定值的轮廓
def get_cont(res_mask):
# 仅检测最外层轮廓,最少点
cnts, hierarchy = cv.findContours(res_mask, 0, 2)
cnts_area = []
for i in cnts:
cnts_area.append(cv.contourArea(i))
res_cnts = None
if len(cnts_area) != 0:
if max(cnts_area) > 3600:
max_cnts = cnts[cnts_area.index(max(cnts_area))]
res_cnts = [max_cnts]
return res_cnts
# 拿到轮廓中心点
def get_center(img_cnts):
cnts = img_cnts[0]
mean_x = np.mean(cnts[:, 0, 0])
mean_y = np.mean(cnts[:, 0, 1])
center = (int(mean_x), int(mean_y))
return center
# 在中心点处 画出一个圈展示
def detect_color(color_mask, show_img):
process_mask = pre_processing(color_mask)
cnts = get_cont(process_mask)
if cnts is not None:
center = get_center(cnts)
cv.circle(show_img, center, 50, (255, 255, 255), 5)
cv.circle(show_img, center, 5, (0, 0, 255), 5)
cv.imshow('color_cnt', show_img)
if __name__ == '__main__':
video_obj = cv.VideoCapture(0)
mode = 'b'
# 读取摄像头
while video_obj.isOpened():
_, img = video_obj.read()
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
b_mask, g_mask, r_mask = mask_range(img)
com_list = {'r': r_mask, 'g': g_mask,
'b': b_mask}
com = cv.waitKey(1)
# 三种颜色检验
if com == ord('r'):
mode = 'r'
print('当前模式: 红色检测')
elif com == ord('g'):
mode = 'g'
print('当前模式: 绿色检测')
elif com == ord('b'):
mode = 'b'
print('当前模式: 蓝色检测')
detect_color(com_list[mode], img)
if com == ord('q'):
break
video_obj.release()
cv.destroyAllWindows()

浙公网安备 33010602011771号