文章目录
- 一:简介
- 二:框选区域选择颜色方案
- 三、算法实现步骤
- 3.1 按鼠标事件截取图像
- 3.2将图像模糊后转化为hsv并求均值
- 3.3 判断hsv处于何种颜色
- 四:整体代码实现
- 五,效果:
一:简介
在计算机视觉领域,颜色检测是一项非常实用的技术。通过颜色检测,我们可以轻松识别图像中的特定颜色区域,从而实现目标追踪、物体识别等功能。本文将带你了解如何使用OpenCV库进行颜色检测。
二:框选区域选择颜色方案
在图像处理过程中,首先通过读取鼠标事件从图像中截取用户感兴趣的特定区域,然后对该区域进行模糊处理以排除噪声和边缘干扰。接下来,将处理后的模糊区域转换到HSV颜色空间,并计算其HSV均值。最后,将计算得到的HSV均值与预设的颜色判断表进行比较,从而确定该区域所属的具体颜色类别。
三、算法实现步骤
3.1 按鼠标事件截取图像
代码如下(示例):
# 导入OpenCV库
import cv2
# 鼠标回调函数,用于处理鼠标事件
def mouse_callback(event, x, y, flags, param):
global start_point, end_point, drawing
# 当鼠标左键按下时,开始绘制矩形
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True # 标记开始绘制
start_point = (x, y) # 记录起始点
# 当鼠标移动时,更新矩形终点
elif event == cv2.EVENT_MOUSEMOVE:
if drawing: # 如果正在绘制,则更新终点
end_point = (x, y)
# 当鼠标左键释放时,结束绘制矩形
elif event == cv2.EVENT_LBUTTONUP:
drawing = False # 标记结束绘制
end_point = (x, y) # 记录终点
# 在原图上绘制矩形
cv2.rectangle(img, start_point, end_point, (0, 255, 0), 2)
# 当鼠标右键按下时,显示截取的图像区域
elif event == cv2.EVENT_RBUTTONDOWN:
# 获取矩形的起始和结束坐标
x1, y1 = start_point
x2, y2 = end_point
# 确保坐标顺序正确
x1, x2 = min(x1, x2), max(x1, x2)
y1, y2 = min(y1, y2), max(y1, y2)
# 从原图中截取选定区域
crop_img = img[y1:y2, x1:x2]
# 显示截取的图像
cv2.imshow('Cropped Image', crop_img)
# 初始化全局变量,用于存储矩形起始点、终点和绘制状态
start_point = (0, 0)
end_point = (0, 0)
drawing = False
# 读取图像文件,路径需要根据实际情况修改
img = cv2.imread(r'F:\traditional_vison\11.jpg')
# 创建一个窗口用于显示图像
cv2.namedWindow('Image')
# 设置鼠标回调函数,将鼠标事件与回调函数绑定
cv2.setMouseCallback('Image', mouse_callback)
# 主循环,显示图像并等待用户操作
while True:
# 显示图像
cv2.imshow('Image', img)
# 按下'q'键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 关闭所有OpenCV创建的窗口
cv2.destroyAllWindows()
3.2将图像模糊后转化为hsv并求均值
代码如下(示例):
roi_blur = cv2.blur(roi,(11,11))
hsv = cv2.cvtColor(roi_blur, cv2.COLOR_BGR2HSV)
h = np.mean(hsv[:, :, 0])
s = np.mean(hsv[:, :, 1])
v = np.mean(hsv[:, :, 2])
3.3 判断hsv处于何种颜色
代码如下(示例):
def classify_color(new_hsv, color_ranges):
# 遍历颜色范围
for color_name, hsv_range in color_ranges.items():
# 检查新HSV值是否在当前颜色范围内
if hsv_range[0][0] <= new_hsv[0] <= hsv_range[1][0] and \
hsv_range[0][1] <= new_hsv[1] <= hsv_range[1][1] and \
hsv_range[0][2] <= new_hsv[2] <= hsv_range[1][2]:
return color_name
return "未知颜色"
#hsv颜色范围为
# minRed1 = np.array([0, 43, 46])
# maxRed1 = np.array([10, 255, 255])
# minRed2 = np.array([156, 43, 46])
# maxRed2 = np.array([180, 255, 255])
# # 橙
# minOrange = np.array([11, 43, 46])
# maxOrange = np.array([25, 255, 255])
# # 黄
# minYellow = np.array([26, 43, 46])
# maxYellow = np.array([34, 255, 255])
# # 绿
# minGreen = np.array([35, 43, 46])
# maxGreen = np.array([77, 255, 255])
# # 青
# minCyan = np.array([78, 43, 46])
# maxCyan = np.array([99, 255, 255])
# # 蓝
# minBlue = np.array([100, 43, 46])
# maxBlue = np.array([124, 255, 255])
# # 紫
# minPurple = np.array([125, 43, 46])
# maxPurple = np.array([155, 255, 255])
# # 黑
# minBlack = np.array([0, 0, 0])
# maxBlack = np.array([180, 255, 46])
# # 灰
# minGray = np.array([0, 0, 46])
# maxGray = np.array([180, 43, 220])
# # 白
# minWhite = np.array([0, 0, 221])
# maxWhite = np.array([180, 30, 255])
四:整体代码实现
# 导入OpenCV库,用于图像处理
import cv2
# 导入NumPy库,用于数值计算
import numpy as np
# 定义一个函数,用于根据HSV值判断颜色
def classify_color(new_hsv, color_ranges):
# 遍历预设的颜色范围字典
for color_name, hsv_range in color_ranges.items():
# 检查输入的HSV值是否在当前颜色范围之内
if hsv_range[0][0] <= new_hsv[0] <= hsv_range[1][0] and \
hsv_range[0][1] <= new_hsv[1] <= hsv_range[1][1] and \
hsv_range[0][2] <= new_hsv[2] <= hsv_range[1][2]:
# 如果在范围内,返回对应的颜色名称
return color_name
# 如果不在任何预设范围内,返回未知颜色
return "未知颜色"
# 预设的颜色范围字典,键为颜色名称,值为HSV范围
color_ranges = {
"yellow": [[11, 43, 46], [34, 255, 255]],
"blue": [[100, 43, 46], [124, 255, 255]],
"green": [[35, 43, 46], [99, 255, 255]]
}
# 定义鼠标回调函数,用于处理鼠标事件
def on_mouse(event, x, y, flags, param):
global ix, iy
# 当鼠标左键按下时,记录当前位置
if event == cv2.EVENT_LBUTTONDOWN:
ix, iy = x, y
# 当鼠标左键释放时,处理截取的图像区域
elif event == cv2.EVENT_LBUTTONUP:
# 根据记录的起始点和当前点截取图像区域
roi = image[iy:y, ix:x]
# 对截取区域进行模糊处理以减少噪声
roi_blur = cv2.blur(roi, (11, 11))
# 将BGR图像转换为HSV格式
hsv = cv2.cvtColor(roi_blur, cv2.COLOR_BGR2HSV)
# 计算HSV通道的平均值
h = np.mean(hsv[:, :, 0])
s = np.mean(hsv[:, :, 1])
v = np.mean(hsv[:, :, 2])
# 使用classify_color函数判断颜色
color_name = classify_color([h, s, v], color_ranges)
# 设置字体和文字参数
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 1
color = (0, 0, 0) # 文字颜色为黑色
thickness = 2
position = (10, 50)
# 在图像上绘制颜色名称
cv2.putText(roi_blur, color_name, position, font, font_scale, color, thickness, cv2.LINE_AA)
# 打印颜色名称和HSV值
print(f"截图区域属于 {color_name}")
print(h, s, v)
# 显示处理后的图像区域
cv2.imshow('roi', roi_blur)
# 读取图像文件
image = cv2.imread(r'F:\im\12.jpg')
# 初始化鼠标事件记录的起始点
ix, iy = -1, -1
# 创建窗口显示图像
cv2.namedWindow('image')
# 设置鼠标回调函数
cv2.setMouseCallback('image', on_mouse)
# 主循环,显示图像并等待用户操作
while True:
# 显示图像
cv2.imshow('image', image)
# 检测按键操作,'q'键退出
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
# 关闭所有OpenCV创建的窗口
cv2.destroyAllWindows()
五,效果:
原图:
效果图: