OpenCV中cv2.inRange函数原理与HSV色彩空间阈值处理实战
本文详解OpenCV中cv2.inRange函数的用法,重点介绍如何将RGB图像转换至HSV空间以去除白色背景。通过解析lowerb与upperb参数机制,结合Python代码实例,展示如何利用该函数提取特定颜色像素并生成掩膜,适用于车道线检测等场景。
本次操作旨在将图像从RGB颜色空间转换至HSV颜色空间,并据此去除白色背景部分。
实现该目标主要调用OpenCV的两个核心函数:一是执行RGB到HSV转换的函数,二是进行阈值处理的函数。
具体实现步骤如下。
hsv = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV)
随后利用cv2.inRange函数设定阈值范围,从而剔除背景区域。
mask = cv2.inRange(hsv, lower_red, upper_red) #lower20===>0,upper200==>0,
该函数逻辑简单,主要包含三个关键参数。
第一个参数hsv代表输入的原始图像数据。
第二个参数lower_red指定下边界值,图像中低于此值的像素点将被置为0。
第三个参数upper_red指定上边界值,图像中高于此值的像素点同样被置为0。
位于lower_red与upper_red之间的像素值则被赋为255。
lower_red = np.array([20, 20, 20])
upper_red = np.array([200, 200, 200])
mask = cv2.inRange(hsv, lower_red, upper_red) #lower20===>0,upper200==>0,lower~upper==>255
综上所述,该操作将低于lower_red和高于upper_red的像素分别设为0,而介于两者之间的像素设为255。
具体代码实现如下所示。
hsv = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV)
lower_red = np.array([20, 20, 20])
upper_red = np.array([200, 200, 200])
# mask -> 1 channel
mask = cv2.inRange(hsv, lower_red, upper_red) #lower20===>0,upper200==>0
补充说明:色彩阈值化处理——OpenCV-Python中inRange()等相关函数的实测分析。
色彩阈值化概念。
在图像处理流程中,常通过形态学操作或滤波来突显关注元素,同时降低噪声及干扰项。此外,还可依据颜色特征从原图中提取关键像素。例如在车道检测场景中,车道通常仅由黄色和白色构成,因此可在RGB色彩空间对这两种颜色进行过滤以提取车道线像素。
色彩空间定义:使用一组值(通常为三或四个颜色成分)表示颜色的抽象数学模型。包括基于原色混合比例的色彩空间(如RGB,即红、绿、蓝),以及基于不同概念表示的色彩空间(如HSV,即色相、饱和度、明度;HSL,即色相、饱和度、亮度)。
需注意OpenCV中cv2.imread()读取的RGB三通道图像是以BGR顺序排列的,而matplotlib的plt.imread()读取的通道顺序为RGB,使用时应区分这一差异。
OpenCV中cv2.inRange()函数是实现色彩阈值化的关键,先参考官网对该函数的定义。
dst = cv.inRange( src, lowerb, upperb[, dst] )
该函数用于检测数组元素是否位于其他两个元素之间。
该函数的检测范围判定方式如下。
对于单通道输入的每个元素。

对于双通道输入的情况。

该逻辑同样适用于四通道图像。
即若src(I)位于指定的1D、2D、3D等维度框内,则dst(I)为255,否则为0。当下边界和/或上边界参数为标量时,公式中对应边界的索引应省略。
各参数详细含义如下。
src:输入的数组。
lowerb:下边界数组或标量。
upperb:上边界数组或标量。
dst:与src大小相同且类型为CV_8U的输出数组。
接下来结合简单示例,通过Python代码深入理解该函数。
import matplotlib.pyplot as plt
import numpy as np
import cv2
# 对图片进行读取
img_cv2 = cv2.imread('D:\\test\\CVtest.jpg')
print(img_cv2)
为便于理解,使用绘图工具生成一张5×5像素的红色图片。上述代码运行结果如下。
[[[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]]
[[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]]
[[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]]
[[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]]
[[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]
[ 36 27 237]]]
读者可自行测试,当B=36、G=27、R=237时,该颜色为红色。
# 创建RGB色彩空间
color_Low1 = np.array([30,27,237])
color_Low2 = np.array([39,27,237])
color_High = np.array([40,27,237])
# 对图片进行阀值化处理
img_dst1 = cv2.inRange(img_cv2,color_Low1,color_High)
img_dst2 = cv2.inRange(img_cv2,color_Low2,color_High)
#对结果进行打印
print(img_dst1,'\n', img_dst2)
# 运行结果分别为
[[255 255 255 255 255]
[255 255 255 255 255]
[255 255 255 255 255]
[255 255 255 255 255]
[255 255 255 255 255]]
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]
可见,当图片像素点落在指定色彩空间范围内时,输出结果全为255;若不在此范围内,则输出结果全为0。对最终结果进行显示。
#对图像进行展示
cv2.imshow("origin_img",img_cv2)
cv2.imshow("dst_img1",img_dst1)
cv2.imshow("dst_img2",img_dst2)
cv2.waitKey(0)
cv2.destroyAllWindows()
最终结果显示为一个红色点、一个黑色点和一个白色点。
以上为个人经验总结,希望能提供参考。如有错误或未考虑周全之处,欢迎指正。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













