在计算机视觉领域,颜色识别是一项基础且应用广泛的技术,无论是工业质检、智能安防还是机器人视觉导航,都能看到它的身影。本文将基于Python和OpenCV库,分享两种实用的颜色识别实现方式------实时识别画面核心区域主颜色、提取画面中指定颜色的区域,帮助大家快速掌握颜色识别的核心思路。
一、核心原理:HSV色彩空间
RGB是我们最熟悉的色彩空间,但它的颜色分布并不均匀,且易受亮度影响。而HSV(色相Hue、饱和度Saturation、明度Value)色彩空间更贴合人眼对颜色的感知,是颜色识别的首选:
• 色相(H):范围0-179,代表颜色的种类(如红色、绿色);
• 饱和度(S):范围0-255,代表颜色的鲜艳程度;
• 明度(V):范围0-255,代表颜色的明暗程度。
我们只需为目标颜色定义H、S、V的范围,就能精准筛选出对应颜色区域。
二、实现1:实时识别画面核心区域主颜色
该方案会实时读取摄像头画面,聚焦画面中心的矩形区域,统计该区域的色相范围,从而判断主颜色(支持红、黄、绿、蓝识别)。
1. 完整代码
python
import cv2
def get_color(img):
# 存储核心区域的色相值
H = []
color_name = None
# 统一调整画面尺寸,方便后续定位核心区域
img = cv2.resize(img, (640, 480))
# 转换为HSV色彩空间
HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 绘制核心识别区域的矩形框(280,180)到(360,260)
cv2.rectangle(img, (280, 180), (360, 260), (0, 255, 0), 2)
# 遍历核心区域的每个像素,收集色相值
for i in range(280, 360):
for j in range(180, 260):
H.append(HSV[j, i][0])
# 计算色相的最大/最小值,判断颜色
H_min = min(H)
H_max = max(H)
# 红色的色相范围分为两段:0-10 和 156-179
if (H_min >= 0 and H_max <= 10) or (H_min >= 156 and H_max <= 179):
color_name = 'red'
elif H_min >= 26 and H_max <= 34: # 黄色色相范围
color_name = 'yellow'
elif H_min >= 35 and H_max <= 77: # 绿色色相范围
color_name = 'green'
elif H_min >= 100 and H_max <= 124: # 蓝色色相范围
color_name = 'blue'
print(f"核心区域主颜色:{color_name}")
return img, color_name
# 打开摄像头(0为默认摄像头)
cap = cv2.VideoCapture(0)
# 实时读取画面
while True:
_, frame = cap.read()
img, cal = get_color(frame)
# 显示处理后的画面
cv2.imshow('Color Recognition', img)
# 按ESC键退出
if cv2.waitKey(1) == 27:
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
2. 代码解析
-
cv2.resize:统一画面尺寸为640x480,避免不同摄像头分辨率导致核心区域位置偏移;
-
cv2.cvtColor:将BGR格式(OpenCV默认读取格式)的画面转换为HSV;
-
cv2.rectangle:绘制绿色矩形框,直观显示核心识别区域;
-
遍历核心区域像素:收集每个像素的色相值(HSV[j,i][0]);
-
色相范围判断:根据预定义的红、黄、绿、蓝色相范围,确定核心区域主颜色。
3. 运行效果
运行代码后,摄像头画面会弹出,中心有绿色矩形框,控制台会实时打印框内的主颜色,按ESC键退出。
三、实现2:提取画面中指定颜色的区域
该方案可筛选出画面中所有指定颜色的区域(以棕色为例),通过掩码(mask)实现颜色过滤,最终输出仅保留目标颜色的画面。
1. 完整代码
python
import cv2
import numpy as np
# 打开摄像头
cap = cv2.VideoCapture(0)
while True:
try:
ret, frame3 = cap.read()
# 转换为HSV色彩空间
hsv_image = cv2.cvtColor(frame3, cv2.COLOR_BGR2HSV)
# 定义棕色的HSV范围(可根据实际需求调整)
lower_brown = np.array([35, 43, 46]) # 最小范围
upper_brown = np.array([77, 255, 255]) # 最大范围
# 创建掩码:符合范围的像素设为255(白色),否则为0(黑色)
mask = cv2.inRange(hsv_image, lower_brown, upper_brown)
# 按位与运算:仅保留掩码中白色区域的原画面颜色
result = cv2.bitwise_and(frame3, frame3, mask=mask)
# 显示掩码、原画面、过滤后的画面
cv2.imshow('mask', mask)
cv2.imshow('Original Image', frame3)
cv2.imshow('Color Filter Result', result)
# 按ESC键退出
if cv2.waitKey(1) == 27:
break
except:
pass
# 释放资源
cap.release()
cv2.destroyAllWindows()
2. 代码解析
-
cv2.inRange:根据定义的HSV范围生成掩码,是颜色筛选的核心函数;
-
cv2.bitwise_and:将原画面与掩码做按位与运算,只有掩码为白色的区域会保留原画面颜色,其余区域为黑色;
-
多窗口显示:方便对比掩码(黑白轮廓)、原画面、过滤后的效果。
3. 自定义颜色范围
若需识别其他颜色,只需调整lower_xxx和upper_xxx的数值,以下是常见颜色的HSV参考范围:
• 红色:lower=np.array([0,43,46]),upper=np.array([10,255,255]) 或 lower=np.array([156,43,46]),upper=np.array([179,255,255]);
• 绿色:lower=np.array([35,43,46]),upper=np.array([77,255,255]);
• 蓝色:lower=np.array([100,43,46]),upper=np.array([124,255,255]);
• 黄色:lower=np.array([26,43,46]),upper=np.array([34,255,255])。
四、扩展与优化
-
降噪处理:实际场景中画面可能有噪点,可在颜色筛选前添加高斯模糊:
frame3 = cv2.GaussianBlur(frame3, (5, 5), 0) -
多颜色同时识别:定义多个颜色范围,生成多个掩码后合并;
-
颜色校准:不同光线、摄像头会导致颜色偏差,可增加手动校准环节,动态调整HSV范围;
-
识别结果可视化:在画面上标注识别到的颜色名称,提升交互性。
五、总结
本文基于OpenCV实现了两种实用的颜色识别方案,核心是利用HSV色彩空间的特性,通过定义颜色范围或统计色相分布实现颜色识别。这些基础方案可灵活扩展到更多场景,比如:
• 智能分拣:识别物料颜色并控制机械臂分拣;
• 交通灯识别:辅助自动驾驶识别交通灯颜色;
• 互动投影:识别指定颜色的物体位置并触发交互。