opencv-python实战项目一:获取鼠标框选区域的颜色


一:简介

在计算机视觉领域,颜色检测是一项非常实用的技术。通过颜色检测,我们可以轻松识别图像中的特定颜色区域,从而实现目标追踪、物体识别等功能。本文将带你了解如何使用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()

五,效果:

原图:在这里插入图片描述
效果图:
在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值