OpenCV对视频或摄像头中物体颜色识别并框选并统一使用绿色边界框显示。对识别物体内部的颜色边缘轮廓在窗口中的边框旁打印上颜色对应的英文字母的代码
本文介绍了基于OpenCV的颜色识别方法,通过HSV色彩空间对物体颜色进行检测和框选。首先定义了常见颜色(红、绿、蓝、黄、橙、紫)在HSV空间的范围参数,红色需要特殊处理两个色相区域。系统流程包括:BGR转HSV、颜色掩膜创建、形态学去噪、轮廓查找等步骤,最终用绿色矩形框选物体并标注颜色首字母。程序支持视频文件或摄像头实时处理,通过调整HSV阈值可适应不同光照条件。该方法实现了对物体颜色的准确识别
本文将介绍OpenCV对物体颜色识别并框选出来准确对颜色进行较大范围框选,统一使用绿色边界框显示。识别物体内部的颜色边缘轮廓,以白色为边缘,对物体的框选更加细致。并在窗口中的边框旁打印上颜色对应的英文字母的代码(本文以视频为例。如需摄像头实时识别可将程序中 cap = cv2.VideoCapture("111.mp4")改为 cap = cv2.VideoCapture("0"))。
这是原视频: 
这是经处理后的视频:

OpenCV对物体颜色识别
1.首先要对颜色范围做一些了解这是颜色识别的重中之重,下面是一些常用颜色:
(1)红色(Red): 由于红色位于色相环的两端(0°和360°附近),所以有两个范围: 低值范围:H:0-10(对应0°-20°) 或者 高值范围:H:170-180(对应340°-360°)
(2)绿色(Green): 绿色的色相大约在120°(普通HSV),对应OpenCV的60,实际范围可能在36-70(即普通HSV的72°-140°)之间,但核心绿色在60左右。
(3)蓝色(Blue): 蓝色的色相在240°(普通HSV),对应OpenCV的120,实际范围在100-130(普通HSV200°-260°)之间。
(4)黄色(Yellow): 黄色的色相在60°(普通HSV),对应OpenCV的30,实际范围在26-35(普通HSV52°-70°)之间。
(5)橙色(Orange,即橘黄色): 橙色的色相在30°(普通HSV)附近,对应OpenCV的15,实际范围在11-25(普通HSV22°-50°)之间。
(6)紫色(Purple): 紫色的色相大约在270°(普通HSV),对应OpenCV的135,实际范围在131-160(普通HSV262°-320°)之间,但注意不要与红色或蓝色重叠。
但是,由于实际应用中的光照和物体差异,这些范围可能需要调整。因此,根据搜索结果的描述,结合OpenCV的实际情况,可以给出如下范围:
注意:下面给出的范围是OpenCV中的数值(H:0-180, S:0-255, V:0-255),并且是每个颜色的大致范围。
通常,饱和度(S)和明度(V)的下限可以设为50-100以上以避免太暗或太灰的区域,上限为255。但是具体的上下限可以根据实际图像调整。
以下是一个表格总结:
| 颜色 | H(色相) 范围 | S(饱和度) 范围 | V(明度) 范围 | 应用说明 |
|---|---|---|---|---|
| 红色 | [0, 10] 或[170, 180] |
100-255 | 50-255 | 需检测两个区间(色环两端) |
| 蓝色 | [100, 130] |
100-255 | 50-255 | 稳定区域 |
| 绿色 | [35, 80] |
80-255 | 40-255 | 较宽范围(包含浅绿到深绿) |
| 黄色 | [20, 35] |
100-255 | 120-255 | 明度要求较高 |
| 橘黄色 | [5, 20] |
150-255 | 100-255 | 高饱和度区域 |
| 紫色 | [125, 160] |
100-255 | 50-200 | 避免亮度过高(可能偏粉) |
接下来进入主题:
(1)载入opencv,载入库,对识别物体颜色进行范围定义。(注:红色有两个范围: 低值范围:H:0-10(对应0°-20°) 或者 高值范围:H:170-180(对应340°-360°)),并对识别时框选颜色英文字母进行设置。
import cv2
import numpy as np #载入opencv载入库
# 颜色范围定义 (HSV格式)
color_ranges = {
'red': ([0, 120, 70], [10, 255, 255]),
'red2': ([170, 120, 70], [180, 255, 255]), # 红色在HSV中有两部分
'green': ([40, 40, 40], [80, 255, 255]),
'blue': ([90, 50, 50], [130, 255, 255]),
'yellow': ([20, 100, 100], [40, 255, 255]),
'orange': ([10, 100, 100], [20, 255, 255]),
'purple': ([130, 40, 40], [170, 255, 255])
}
# 颜色对应的字母和显示颜色
color_info = {
'red': ('R', (0, 0, 255)),
'green': ('G', (0, 255, 0)),
'blue': ('B', (255, 0, 0)),
'yellow': ('Y', (0, 255, 255)),
'orange': ('O', (0, 165, 255)),
'purple': ('P', (128, 0, 128))}
(2)将图像从BGR色彩空间转换到HSV色彩空间。
- frame`: 输入的图像(OpenCV默认以BGR格式读取)。
- `cv2.cvtColor()`: OpenCV的色彩空间转换函数。
- `cv2.COLOR_BGR2HSV`: 转换标志,指定从BGR到HSV的转换。
def detect_colors(frame):
# 转换为HSV颜色空间
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
(3)对每种颜色进行处理:
创建掩膜将颜色范围的下限值转换为OpenCV可识别的无符号8位整数数组 Python列表 → OpenCV兼容数组
去除噪声将二值化掩膜(mask)进行形态学开运算处理,作用是去除噪声斑点+平滑物体边界,让颜色检测结果更准确。
# 对每种颜色进行处理
for color_name, (lower, upper) in color_ranges.items():
# 创建颜色掩膜
lower = np.array(lower, dtype=np.uint8) #将颜色范围的下限值转换为OpenCV
可识别的无符号8位整数数组 Python列表 → OpenCV兼容数组
upper = np.array(upper, dtype=np.uint8)
mask = cv2.inRange(hsv, lower, upper)
# 如果处理红色,需要合并两个红色范围
if color_name == 'red':
lower2 = np.array(color_ranges['red2'][0], dtype=np.uint8)
upper2 = np.array(color_ranges['red2'][1], dtype=np.uint8)
mask2 = cv2.inRange(hsv, lower2, upper2)
mask = cv2.bitwise_or(mask, mask2)
color_name = 'red' # 统一使用red作为键
# 形态学操作去除噪声
kernel = np.ones((5, 5), np.uint8)
#二值化掩膜(mask)进行形态学开运算处理,作用是去除噪声斑点+平滑物体边界,让颜色检测结果更准确。
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
(4)创建查找轮廓并对边界框进行设置:
# 查找轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 为每个轮廓绘制边界框和边缘
for cnt in contours:
# 忽略小面积区域
if cv2.contourArea(cnt) < 500:
continue
# 获取大致边界框 (绿色)
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 获取更精确的边缘 (白色)
epsilon = 0.02 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
cv2.drawContours(frame, [approx], -1, (255, 255, 255), 1)
# 显示颜色字母 (使用原始颜色名称,不包括red2)
if color_name in color_info:
letter, text_color = color_info[color_name]
cv2.putText(frame, letter, (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color, 2)
return frame
(5)读取视频文件对之前设置进行绘制并展示出来:
本文以视频为例。如需摄像头实时识别可将程序中 cap = cv2.VideoCapture("111.mp4")改为 cap = cv2.VideoCapture("0")
# 主程序
def main():
# 可以选择摄像头或视频文件
cap = cv2.VideoCapture("111.mp4") # 0表示默认摄像头,视频:支持常见格式如 .mp4, .avi,需确保路径正确且文件存在。
while True:
ret, frame = cap.read()
if not ret:
break
# 检测并绘制颜色
result = detect_colors(frame)
# 显示结果
cv2.imshow('Color Detection', result)
# 按q退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
本文用的是vscode配置python开发环境编写opencv。通过将视频转换为 HSV、定义红色蓝黄橘黄紫色的范围、查找轮廓,框选显现颜色首写字母并展示出来,这种方法对于计算机视觉中的颜色识别任务非常强大。
这是完整代码:
import cv2
import numpy as np
# 颜色范围定义 (HSV格式)
color_ranges = {
'red': ([0, 120, 70], [10, 255, 255]),
'red2': ([170, 120, 70], [180, 255, 255]), # 红色在HSV中有两部分
'green': ([40, 40, 40], [80, 255, 255]),
'blue': ([90, 50, 50], [130, 255, 255]),
'yellow': ([20, 100, 100], [40, 255, 255]),
'orange': ([10, 100, 100], [20, 255, 255]),
'purple': ([130, 40, 40], [170, 255, 255])
}
# 颜色对应的字母和显示颜色
color_info = {
'red': ('R', (0, 0, 255)),
'green': ('G', (0, 255, 0)),
'blue': ('B', (255, 0, 0)),
'yellow': ('Y', (0, 255, 255)),
'orange': ('O', (0, 165, 255)),
'purple': ('P', (128, 0, 128))
}
def detect_colors(frame):
# 转换为HSV颜色空间
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 对每种颜色进行处理
for color_name, (lower, upper) in color_ranges.items():
# 创建颜色掩膜
lower = np.array(lower, dtype=np.uint8) #将颜色范围的下限值转换为
#OpenCV可识别的无符号8位整数数组 Python列表 → OpenCV兼容数组
upper = np.array(upper, dtype=np.uint8)
mask = cv2.inRange(hsv, lower, upper)
# 如果处理红色,需要合并两个红色范围
if color_name == 'red':
lower2 = np.array(color_ranges['red2'][0], dtype=np.uint8)
upper2 = np.array(color_ranges['red2'][1], dtype=np.uint8)
mask2 = cv2.inRange(hsv, lower2, upper2)
mask = cv2.bitwise_or(mask, mask2)
color_name = 'red' # 统一使用red作为键
# 形态学操作去除噪声
kernel = np.ones((5, 5), np.uint8)
#二值化掩膜(mask)进行形态学开运算处理,
# 作用是去除噪声斑点+平滑物体边界,让颜色检测结果更准确。
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# 查找轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 为每个轮廓绘制边界框和边缘
for cnt in contours:
# 忽略小面积区域
if cv2.contourArea(cnt) < 500:
continue
# 获取大致边界框 (绿色)
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 获取更精确的边缘 (白色)
epsilon = 0.02 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
cv2.drawContours(frame, [approx], -1, (255, 255, 255), 1)
# 显示颜色字母 (使用原始颜色名称,不包括red2)
if color_name in color_info:
letter, text_color = color_info[color_name]
cv2.putText(frame, letter, (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color, 2)
return frame
# 主程序
def main():
# 可以选择摄像头或视频文件
cap = cv2.VideoCapture("111.mp4") # 0表示默认摄像头,视频:支持常见格式如 .mp4, .avi,需确保路径正确且文件存在。
while True:
ret, frame = cap.read()
if not ret:
break
# 检测并绘制颜色
result = detect_colors(frame)
# 显示结果
cv2.imshow('Color Detection', result)
# 按q退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
感谢阅读观看!!
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)