今日继续学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi)
本人所用树莓派4B 装载的系统与版本如下:
版本可用命令 (lsb_release -a) 查询:
Opencv 版本是4.5.1:
OpenCv颜色追踪_程序手动调试HSV色彩空间_检测灰度图中的圆
今日学习的程序主要是为了能够手动微调整好更为适合多变环境的HSV色彩空间
文章提供测试代码讲解,整体代码贴出、测试效果图
目录
实验目的:
实时地从视频流中检测特定颜色范围内的圆形物体。
用户可以通过Trackbars调整HSV颜色阈值来指定要检测的HSV颜色范围。使得程序对特定颜色小球的检测更为准确
检测到的圆形物体将在原始帧上被绘制出来,并根据其大小以不同的颜色和线宽进行区分。此外,如果检测到的圆的半径超过某个阈值(在这里是35),则会设置一个标志(
buzz
)。实验全部过程视频:
OpenCv颜色追踪_程序手动调试HSV色彩空间_检测圆
完整实例代码贴出:
实时地从视频流中检测特定颜色范围内的圆形物体。
可以通过Trackbars调整HSV颜色阈值来指定要检测圆的颜色范围。
# -*- coding: utf-8 -*- import cv2 import numpy as np import time kernel = np.ones((5,5),np.uint8) # 从网络摄像头获取输入 cap = cv2.VideoCapture(0) time.sleep(0.5) # 将视频尺寸减小到320x240,这样rpi处理速度就会更快 cap.set(3,320) cap.set(4,240) #第一个空回调函数 def nothing(x): pass # 创建一个供以后使用的窗口 cv2.namedWindow('HueComp') cv2.namedWindow('SatComp') cv2.namedWindow('ValComp') cv2.namedWindow('closing') cv2.namedWindow('tracking') # 创建跟踪条的最小和最大的色调,饱和度和价值 # 允许用户实时调整参数值HSV cv2.createTrackbar('hmin', 'HueComp',12,179,nothing) cv2.createTrackbar('hmax', 'HueComp',37,179,nothing) cv2.createTrackbar('smin', 'SatComp',96,255,nothing) cv2.createTrackbar('smax', 'SatComp',255,255,nothing) cv2.createTrackbar('vmin', 'ValComp',186,255,nothing) cv2.createTrackbar('vmax', 'ValComp',255,255,nothing) while(1): buzz = 0 #读取帧并转换到HSV空间 _, frame = cap.read() hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) hue,sat,val = cv2.split(hsv) #获取Trackbar的当前值 hmn = cv2.getTrackbarPos('hmin','HueComp') hmx = cv2.getTrackbarPos('hmax','HueComp') smn = cv2.getTrackbarPos('smin','SatComp') smx = cv2.getTrackbarPos('smax','SatComp') vmn = cv2.getTrackbarPos('vmin','ValComp') vmx = cv2.getTrackbarPos('vmax','ValComp') #应用HSV阈值 hthresh = cv2.inRange(np.array(hue),np.array(hmn),np.array(hmx)) sthresh = cv2.inRange(np.array(sat),np.array(smn),np.array(smx)) vthresh = cv2.inRange(np.array(val),np.array(vmn),np.array(vmx)) # 组合HSV阈值 使用按位与操作来组合三个HSV分量的阈值结果,从而得到颜色范围内所有像素的掩码。 tracking = cv2.bitwise_and(hthresh,cv2.bitwise_and(sthresh,vthresh)) #形态学操作 #对掩码进行膨胀、闭操作和高斯模糊,以减少噪声并增强圆形物体的检测。 dilation = cv2.dilate(tracking,kernel,iterations = 1) closing = cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel) closing = cv2.GaussianBlur(closing,(5,5),0) #使用霍夫圆变换来检测圆形。 circles = cv2.HoughCircles(closing,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=50,minRadius=10,maxRadius=0) #绘制检测到的圆形 #如果检测到圆形,就在原始帧上绘制它们。根据圆形的半径大小,使用不同的颜色和线宽进行绘制。 if circles is not None: x, y, r = circles[0][0] x_p = int(round(x)) print (x_p) for i in circles[0,:]: if int(round(i[2])) < 30: cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),int(round(i[2])),(0,255,0),5) cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),2,(0,255,0),10) elif int(round(i[2])) > 35: cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),int(round(i[2])),(0,0,255),5) cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),2,(0,0,255),10) buzz = 1 cv2.imshow('HueComp',hthresh) cv2.imshow('SatComp',sthresh) cv2.imshow('ValComp',vthresh) cv2.imshow('closing',closing) cv2.imshow('tracking',frame) if cv2.waitKey(1) & 0xFF == ord('q'): cap.release() L_Motor.stop() R_Motor.stop() GPIO.cleanup() cv2.destroyAllWindows() break cap.release() cv2.destroyAllWindows()
代码小结:
1、创建Trackbar
2、始化循环,读取帧并转换到HSV空间
3、获取Trackbar的当前值
4、应用HSV阈值
5、组合HSV阈值
6、形态学操作
7、检测圆形
8、绘制检测到的圆形
9、输出和判断
代码实验操作与测试结果图:
1、使用树莓派的USB摄像头拍摄一张球形物体的图片用于取色获取大致BGR色域范围:
我的颜色范围是:138 67 17
拍摄程序在这篇文章有提到:树莓派4B_OpenCv学习笔记4:测试摄像头_imread加载显示图像_imwrite保存图片_树莓派摄像头怎么保存照片-CSDN博客
2、运行程序将BGR颜色空间转换为HSV:
BGR_HSV转换程序在这篇文章有提到:
树莓派4B_OpenCv学习笔记6:OpenCv识别已知颜色_运用掩膜_树莓派 图像融合-CSDN博客
3、运行本次实验的程序,将TrackBar调整到差不多的HSV范围:
发现如果不进行调整直接运用第二步得到的颜色空间范围,那么将会检测到许多的“圆”:
然后根据HSV窗口展示轮廓,调整它们的最大值与最小值,使其掩膜中的目标圆球轮廓更清晰,而其余噪声点更小:
然后拿远点测试,以及将瓶盖侧放,看是否会误检测为圆:
应用HSV阈值函数 cv2.inRange()
:
#应用HSV阈值
hthresh = cv2.inRange(np.array(hue),np.array(hmn),np.array(hmx))
sthresh = cv2.inRange(np.array(sat),np.array(smn),np.array(smx))
vthresh = cv2.inRange(np.array(val),np.array(vmn),np.array(vmx))
hthresh
np.array(hue)
: HSV图像中的色调通道(H)。np.array(hmn)
: 色调通道的下限值。np.array(hmx)
: 色调通道的上限值。- 输出: 一个二值图像,其中在
hmn
和hmx
之间的色调值被设置为白色,其他值被设置为黑色。
sthresh
np.array(sat)
: HSV图像中的饱和度通道(S)。np.array(smn)
: 饱和度通道的下限值。np.array(smx)
: 饱和度通道的上限值。- 输出: 一个二值图像,其中在
smn
和smx
之间的饱和度值被设置为白色,其他值被设置为黑色。
vthresh
np.array(val)
: HSV图像中的亮度通道(V或I,取决于你如何称呼它)。np.array(vmn)
: 亮度通道的下限值。np.array(vmx)
: 亮度通道的上限值。- 输出: 一个二值图像,其中在
vmn
和vmx
之间的亮度值被设置为白色,其他值被设置为黑色。Tip:之前的颜色追踪实验也用到了掩膜,inRange(),只不过指定的通道为HSV全部:
组合HSV阈值 cv2.bitwise_and()
:
# 组合HSV阈值 使用按位与操作来组合三个HSV分量的阈值结果,
从而得到颜色范围内所有像素的掩码。
tracking = cv2.bitwise_and(hthresh,cv2.bitwise_and(sthresh,vthresh))
函数作用:
cv2.bitwise_and()
对两个数组进行按位与操作,通常用于组合或修改二值图像。当想将多个二值图像(或掩码)组合在一起时,通常需要使用这个函数来确保只有在所有掩码中对应位置都为“真”(即白色或255)的像素才会在结果图像中保留为白色。
在给出的例子中,将三个HSV分量(色调、饱和度和亮度)的阈值结果组合成一个最终的掩码,以识别特定颜色范围内的所有像素。
在这个修正后的代码中:
hsv_thresh_hs
是hthresh
和sthresh
的按位与结果,它只包含同时在色调和饱和度范围内的像素。tracking
是hsv_thresh_hs
和vthresh
的按位与结果,它只包含同时在色调、饱和度和亮度范围内的像素,即您想要跟踪的颜色范围内的所有像素。
形态学操作函数:(膨胀/腐蚀/开运算/闭运算):
closing = cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel)
cv2.morphologyEx()
是 OpenCV 中用于形态学变换的函数,它可以执行各种形态学操作,如腐蚀(erosion)、膨胀(dilation)、开运算(opening)和闭运算(closing)等。在给出的例子中,
cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel)
是执行闭运算(closing operation)的调用。函数作用:闭运算首先执行膨胀操作,然后执行腐蚀操作。闭运算的主要目的是消除图像中的小孔(即黑色区域中的白色点),并连接相邻的对象。这在图像处理中用于平滑物体的轮廓,去除小的孔洞,以及连接断裂的轮廓。
传入参数:
src
:输入图像,通常是二值图像。在给出的例子中,是
dilation
,即已经过膨胀操作的图像。
- 类型:可以是灰度图或二值图,其数据类型通常是
CV_8U
,CV_16U
,CV_16S
,CV_32F
, 或CV_64F
之一。- 描述:源图像,即要进行形态学操作的图像。
operation
:形态学操作的类型。在给出的例子中,是
cv2.MORPH_CLOSE
,表示执行闭运算。
cv2.MORPH_ERODE
:腐蚀操作cv2.MORPH_DILATE
:膨胀操作cv2.MORPH_OPEN
:开运算(先腐蚀后膨胀)cv2.MORPH_CLOSE
:闭运算(先膨胀后腐蚀)cv2.MORPH_GRADIENT
:形态学梯度cv2.MORPH_TOPHAT
:原图像减去膨胀的图像cv2.MORPH_HITMISS
:结构元素对应的点集比较- 注意:其他可能还有如
cv2.MORPH_BLACKHAT
等操作,具体请参考 OpenCV 官方文档。kernel
:结构元素(structuring element)。
- 类型:数组,通常是 numpy 数组,形状如矩形、椭圆或交叉形等。
- 描述:定义了形态学操作的局部形状和大小。可以使用
cv2.getStructuringElement()
函数来创建结构元素。dst (输出图像, 可选):
- 类型:与
src
相同的数据类型- 描述:输出图像,如果未指定,则函数会创建一个新的输出图像。
anchor (锚点位置, 可选):
- 类型:元组,指定了结构元素的锚点位置。
- 描述:默认为结构元素的中心。如果指定了锚点,则形态学操作将围绕该点进行。
iterations (迭代次数, 可选):
- 类型:整数
- 描述:腐蚀与膨胀被应用的次数。默认为1。
borderType (边界类型, 可选):
- 类型:整数
- 描述:像素边界扩展类型,具体类型请参考 OpenCV 官方文档中的
BorderTypes
。borderValue (边界值, 可选):
- 类型:与
src
相同的数据类型- 描述:当
borderType
为BORDER_CONSTANT
时,用于填充边界的常量值。
高斯模糊cv2.GaussianBlur()
:
closing = cv2.GaussianBlur(closing,(5,5),0)
在 OpenCV 中用于对图像进行高斯模糊。高斯模糊是一种用于减少图像噪声和细节层次的图像滤波技术。它使用一个高斯函数来创建模糊滤波器,该滤波器在中心点的权重最高,然后随着距离的增加权重逐渐降低。
该函数对
closing
图像进行高斯模糊。这通常在图像处理流程中用于减少图像的细节和噪声,尤其是在特征检测或对象识别之前。
传入参数:
- src (
closing
在此例中):输入图像,即要进行高斯模糊的图像。- ksize ((5,5) 在此例中):高斯核的大小。它必须是正奇数,并且可以是元组
(width, height)
,其中width
和height
必须是正整数且都是奇数。如果ksize
是一个整数,那么它会被视为(ksize, ksize)
的正方形核。在此例中,(5,5)
表示一个 5x5 的核。- sigmaX (0 在此例中):X 方向的标准差;决定了模糊的程度。如果
sigmaX
是 0,那么它会根据核大小来计算。如果sigmaY
也是 0,那么sigmaY
会与sigmaX
相等。在此例中,因为sigmaX
是 0,所以会根据 5x5 的核大小来计算标准差。输出:
输出是一个与输入图像closing
大小和类型相同的新图像,其中包含了高斯模糊的结果。这个新的图像是原图像的模糊版本,细节层次被降低,噪声被减少。
霍夫圆变换来检测圆形:
#使用霍夫圆变换来检测圆形。
circles = cv2.HoughCircles(closing,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=50,minRadius=10,maxRadius=0)
cv2.HoughCircles
函数用于在灰度图像中检测圆形。它使用霍夫变换的一个变种来检测图像中的圆形。传入参数:
image
:8位单通道灰度图像。method
:检测方法,如cv2.HOUGH_GRADIENT
或cv2.HOUGH_GRADIENT_ALT
。dp
:检测器分辨率的倒数。如果设置为 1,则与图像分辨率相同。如果设置为 2,则分辨率是原始图像的一半。minDist
:检测到的圆心之间的最小距离。param1
:Canny 边缘检测中的高阈值。param2
:在检测阶段,检测到的圆心的累加器阈值。这个值越小,检测到的圆就越多。minRadius
:最小圆半径。maxRadius
:最大圆半径。如果设置为 0,则使用最大可能的半径。输出:
返回一个 NumPy 数组,其中包含检测到的圆的 (x,y) 坐标和半径。数组的形状是(num_circles, 3)
,其中每一行包含三个值:(x, y, radius)
。