Python OpenCV基于HSV的颜色分割实现示例

闻溪
闻溪
发布时间:2026-10-15 | 4人浏览过
原创

本文介绍如何利用Python和OpenCV进行HSV颜色分割,以交通信号灯检测为例。详细解析HSV模型中H、S、V参数的含义及取值范围,并通过createTrackbar函数实现阈值动态调整,最终生成掩码以提取感兴趣区域,提升识别准确率。

前言

近一周专注于机器学习和图像处理的深入学习,虽然内容繁杂,但有必要将所学进行系统记录。

尽管深度学习能解决诸多问题,但在特定场景下,将其与图像处理结合往往效果更佳。例如在交通信号灯检测任务中,先利用目标检测模型定位信号灯位置,再对定位区域进行颜色分割与识别,可显著提升整体准确率。

机器学习领域有句名言:数据和特征决定了模型的上限,算法仅负责逼近该上限。因此,掌握常用机器学习算法并熟悉特征工程至关重要。

1、什么是HSV

大家熟知RGB颜色模式,通过不同比例混合可生成各种颜色。HSV同样是重要的颜色模式,其模型结构如图所示

从图示可以看出,HSV模型与RGB类似,均由三个属性共同决定颜色。H、S、V分别代表色调、饱和度(深度)和明度(明暗)。随着图中方向的变化,对应颜色也会发生改变,且三者均有特定的取值范围:

  • H(色调):以角度为单位度量,取值范围为0°至360°
  • S(饱和度):表示颜色接近光谱色的程度。通常取值范围为0%至100%,数值越大,颜色越饱和。
  • V(明度):表示颜色的明亮程度。对于光源色,明度值与发光体的光亮度相关;对于物体色,则与物体的透射比或反射比有关。通常取值范围为0%(黑色)到100%(白色)。

HSV空间中的三个指标相互独立,能够直观地表达色彩的明暗、色调及鲜艳程度,便于颜色间的对比,因此常用于颜色的分割与识别。各颜色在HSV空间中的具体范围见下表

2、代码实战

从网络下载了一张交通信号灯图片,如图所示

我们的目标是通过颜色分割,提取出感兴趣的区域,以便进行后续操作。

2.1 createTrackbar使用方法及步骤

在开始实际操作前,先了解createTrackbar函数。这是OpenCV提供的API,可在显示图像的窗口中快速创建一个滑动控件,用于手动调节阈值,效果直观。通过直接观察阈值选择的效果,可以确定理想的阈值参数。

使用Trackbar需要掌握两个关键函数:

(1)创建滑动条函数

一个滑动条仅能用于一个参数。若需改变多个参数,需创建多个滑动条。

cv2.createTrackbar(trackbarName, windowName, value, count, onChange)

各参数意义如下:

trackbarName:滑动条的名称;

windowName:滑动条依附的图像窗口名称;

value:初始化阈值;

count:滑动控件的刻度范围,最小值默认为0。

onChange:回调函数名称。所谓回调函数,即每次修改滑动条后需传入新变量的函数,其定义如下:

onchange:void foo(int,void*)。

其中第一个参数代表滑动条位置,第二个参数为用户数据(详见下一参数)。若回调为空指针,则不调用回调函数,仅更新值。

用户数据:按原样传递给回调的用户数据。它可用于处理滑动条事件,从而避免使用全局变量。

(2)获取滑动条的值函数

cv.getTrackbarPos用于获取滑动条位置处的值。

g = cv2.getTrackbarPos(trackbarName2, windowName)
#第一个参数为滑动条1的名称,第二个参数为窗口的名称。

注意:必须在回调函数内部采用cv.getTrackbarPos获取滑动条位置处的值。否则,若存在多个滑动条,函数无法获取更新后的参数值。

2.2 代码详解

import cv2
# 滑动条的回调函数,获取滑动条位置处的值
def empty(a):
    h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
    h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
    s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
    s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
    v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
    v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
    print(h_min, h_max, s_min, s_max, v_min, v_max)
    return h_min, h_max, s_min, s_max, v_min, v_max
path = 'Resources/11.jpg'
# 创建一个窗口,放置6个滑动条
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",19,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",110,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",240,255,empty)
cv2.createTrackbar("Val Min","TrackBars",153,255,empty)
cv2.createTrackbar("Val Max","TrackBars",255,255,empty)
while True:
    img = cv2.imread(path)
    imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    # 调用回调函数,获取滑动条的值
    h_min,h_max,s_min,s_max,v_min,v_max = empty(0)
    lower = np.array([h_min,s_min,v_min])
    upper = np.array([h_max,s_max,v_max])
    # 获得指定颜色范围内的掩码
    mask = cv2.inRange(imgHSV,lower,upper)
    # 对原图图像进行按位与的操作,掩码区域保留
    imgResult = cv2.bitwise_and(img,img,mask=mask)
    cv2.imshow("Mask", mask)
    cv2.imshow("Result", imgResult)
    cv2.waitKey(1)

在交通信号灯检测中,我们只需获得掩码(mask图像)即可进行后续识别。

3、总结

颜色分割在多种场景中均有应用,结合深度学习可获得更佳效果。后续将记录字符分割的方法。字符分割的应用场景和思路同样广泛,更多关于Python OpenCV HSV颜色分割的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表