OpenCV目标检测Meanshif和Camshift算法解析
本文旨在对OpenCV中的Meanshift和Camshift算法进行解析,给读者提供OpenCV目标检测的攻略。
什么是Meanshift
Meanshift算法最初是用于图像压缩的,但是这个算法可以用于计算对象在图像中的位置。在计算机视觉中,Meanshift算法被广泛应用于目标跟踪任务。
Meanshift算法首先需要选择一块需要跟踪的区域,通常是矩形或者圆形。然后,根据此区域的颜色分布计算出“重心”(图像直方图峰值区域的中心点)。接着,将此中心点作为新的区域重心计算出来,并不断重复此过程直到重心位置不再移动。
Meanshift算法使用简单,对于非刚性变形,颜色不变等情况能够得到较好的跟踪效果。
Meanshift示例
下面的示例展示了Meanshift算法的使用。我们选择一张含有绿色叶子的图片,然后在图片上选择一块区域进行跟踪。
import cv2
# 读入图片
img = cv2.imread("leaf.jpg")
# 选择需要跟踪的区域
r,h,c,w = 250,90,400,125
track_window = (c,r,w,h)
# 提取所选择区域的直方图
roi = img[r:r+h, c:c+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
# 创建一个窗口并展示所选择的区域
cv2.namedWindow('roi')
cv2.imshow('roi',roi)
# 对视频帧进行处理,不断更新跟踪框的位置
cap = cv2.VideoCapture(0)
while(1):
ret ,frame = cap.read()
if ret == True:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)
# 使用Meanshift算法
ret, track_window = cv2.meanShift(dst, track_window, termination=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1))
# 在原图上画出跟踪框
x,y,w,h = track_window
img2 = cv2.rectangle(frame, (x,y), (x+w,y+h), 255,2)
cv2.imshow('img2',img2)
k = cv2.waitKey(60) & 0xff
if k == 27:
break
else:
break
cv2.destroyAllWindows()
cap.release()
执行以上代码,选择一块叶子区域,再运行后打开摄像头,会发现跟踪框始终在叶子区域内。
什么是Camshift
Camshift是Meanshift的一种变体,由Gary R. Bradsky在OpenCV的文献中提出。Camshift算法在Meanshift的基础上进行了改进,处理非刚性变形能力更强。Camshift可以自适应地调整所选择区域的大小和形状,从而能够更好地跟踪目标对象。
Camshift算法首先利用Histogram Back Projection(直方图反向投影)得到目标对象的区域,并执行Meanshift算法,得到对象的中心点。然后,在新的样本区域中计算出新的直方图,并以此更新原来的直方图。在计算出新直方图并执行Meanshift算法所得到的中心坐标与原构算出的中心坐标不同的情况下,即目标对象发生运动或变形的情况下,Camshift会重新调整目标区域的大小和形状,再次运行直方图反向投影、更新直方图和执行Meanshift算法的过程。
Camshift示例
下面的代码展示了Camshift算法的使用。我们在一个静态图片中选择一个区域用于跟踪,并且在每一帧上更新该区域的形状和大小,从而使跟踪始终跟随目标移动。
import cv2
import numpy as np
# 读入图片
img = cv2.imread('bird.jpg')
# 选择跟踪的区域
r,h,c,w = 250,100,400,150
track_window = (c,r,w,h)
# 提取所选择区域的直方图
roi = img[r:r+h, c:c+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
# 设置终止条件
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
# 打开摄像头,进行CamShift算法处理
cap = cv2.VideoCapture(0)
while(1):
ret ,frame = cap.read()
# 识别对象的直方图来跟踪
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)
# 关键步骤,使用CamShift跟踪
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
# 进行图像的矩形绘制
pts = cv2.boxPoints(ret)
pts = np.int0(pts)
img2 = cv2.polylines(frame,[pts],True, 255,2)
cv2.imshow('img2',img2)
k = cv2.waitKey(60) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
执行以上代码,选择一块鸟的区域,然后打开摄像头,会发现跟踪框一直跟随着鸟移动。
结论
本文详细介绍了OpenCV中的Meanshift和Camshift算法,展示了两个实例来说明算法的使用方法。通过这些示例,读者可以学会如何使用Meanshift和Camshift算法来进行目标跟踪。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:OpenCV目标检测Meanshif和Camshift算法解析 - Python技术站