OpenCV中Camshift算法原理与Python实现详解

夏知夏
夏知夏
发布时间:2026-10-13| 4人浏览过
原创

本文深入解析OpenCV中的Camshift(连续自适应Meanshift)算法,旨在解决传统Meanshift在目标距离变化时窗口大小固定及无法处理旋转的问题。通过Python代码示例,演示如何结合直方图反向投影与Camshift函数实现自适应窗口大小的目标跟踪,并解析其返回值含义及迭代优化过程。

Camshift算法背景与引入原因

在前文学习Meanshift算法时,观察其标记结果会发现一个明显缺陷,具体表现如下图所示:

当目标(如汽车)距离较远时,使用较小的窗口即可将其框住,这符合近大远小的视觉投影原理;然而,当目标靠近时,情况如下所示:

此时,固定大小的窗口已无法完全包围目标,导致跟踪失效。为了解决这一问题,引入了Camshift(Continuously Adaptive Meanshift,连续自适应Meanshift)算法。此外,该算法还能有效判断物体的旋转方向,这也是其重要功能之一。该算法源自1998年发表的论文《Computer Vision Face Tracking for Use in a Perceptual User Interface》。

Camshift算法工作原理

Camshift算法的执行流程如下:首先应用Meanshift算法找到概率密度最大的区域,随后更新窗口的大小,并计算能够最佳包裹该区域的椭圆;若结果仍不满足条件,则进入下一轮迭代,直到满足Meanshift的收敛条件且窗口大小适配为止。

Camshift函数返回两个关键值:第一个值ret代表旋转后的窗口参数,第二个值是用于下一次搜索的窗口位置。具体代码示例如下:

Python代码实现与解析


#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import numpy as np
import cv2
from matplotlib import pyplot as plt
 
capture = cv2.VideoCapture(1)
if not capture.isOpened:
  print('Unable to open: ')
  exit(0)
  
#获取第一帧图片
ret,frame = capture.read()
 
#设置目标窗口
#读取文件
find = cv2.imread('luohu1.png')
h,w = find.shape[:2]
roi = find[10: 120, 10: 120]
x = 10
y = 10
width = 120 - x
height = 120 - y
track_window = (x, y, w, h)
print(track_window)
#跟踪目标
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)
 
#设置迭代条件,每10移动一点
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
 
while(1):
  ret, frame = capture.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.CamShift(dst, track_window, term_crit)
 
    #显示标记
    pts = cv2.boxPoints(ret)
    pts = np.int0(pts)
    img2 = cv2.polylines(frame,[pts],True, (255,0,0),2)
    cv2.imshow('img2',img2)
 
    cv2.imshow("dst", dst) 
    cv2.imshow("roi", roi)
    keyboard = cv2.waitKey(1)
    if keyboard == ord('q') or keyboard == ord('Q'):
      break
  else:
    break
 
  
capture.release()
cv2.destroyAllWindows()

运行结果展示

程序运行后的输出结果如下所示:

以下是目标距离较远时的跟踪效果照片:

以下是目标距离较近时的跟踪效果照片:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。