OpenCV目标检测Meanshif和Camshift算法解析

作者:uncle_ll 时间:2022-06-15 21:30:35 

学习目标

在本章中,将学习用于跟踪视频中对象的Meanshift和Camshift算法

Meanshift

Meanshift背后的原理很简单,假设有点的集合(它可以是像素分布,例如直方图反投影)。 给定一个小窗口(可能是一个圆形),必须将该窗口移动到最大像素密度(或最大点数)的区域。如下图所示:

OpenCV目标检测Meanshif和Camshift算法解析

初始窗口以蓝色圆圈显示,名称为“C1”。其原始中心以蓝色矩形标记,名称为“C1_o”。但是,如果找到该窗口内点的质心,则会得到点“C1_r”(标记为蓝色小圆圈),它是窗口的真实质心。当然,二者是不匹配的。因此,移动窗口使新窗口的圆与上一个质心匹配。再次找到新的质心。很可能不会匹配。因此,再次移动它,并继续迭代,以使窗口的中心及其质心落在同一位置(或在很小的期望误差内)。因此,最终获得的是一个具有最大像素分布的窗口。它带有一个绿色圆圈,名为“C2”。正如您在图像中看到的,它具有最大的点数。整个过程在下面的静态图像上演示:

OpenCV目标检测Meanshif和Camshift算法解析

因此,通常会传递直方图反投影图像和初始目标位置当对象移动时,显然该移动会反映在直方图反投影图像中。因此,Meanshift算法就是将窗口移动到最大密度的新位置的算法。

OpenCV目标检测Meanshif和Camshift算法解析

OpenCV中的Meanshift

要在OpenCV中使用Meanshift,首先需要设置目标,找到其直方图,以便可以将目标反投影到每帧上以计算均值偏移。我们还需要提供窗口的初始位置。对于直方图,此处仅考虑色相(Hue)。另外,为避免由于光线不足而产生错误的值,可以使用cv2.inRange()函数丢弃光线不足的值。 使用的视频中的三帧如下:

import cv2
import numpy as np
video_file = 'slow_traffic_small.mp4'
cap = cv2.VideoCapture(video_file)
# take first frame of the video
ret, frame = cap.read()
# setup initial location of window
x, y, w, h = 300, 200, 100, 50  # simply hardcoded the values
track_window = (x, y, w, h)
# setup the roi for tracking
roi = frame[y:y+h, x:x+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)
# setup the termination criteria, either 10 iteration or move by atleast 1 pt
term_crit = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10, 1)
while True:
   ret, frame = cap.read()
   if ret == True:
       hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
       dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
       # apply meansift to get the new location
       ret, track_window = cv2.meanShift(dst, track_window, term_crit)
       # draw it on image
       x, y, w, h = track_window
       img2 = cv2.rectangle(frame, (x, y), (x+w, y+h), 255, 2)
       cv2.imshow('img2', img2)
       cv2.waitKey(0)
   else:
       cv2.destroyAllWindows()
       break

OpenCV目标检测Meanshif和Camshift算法解析

Camshift

OpenCV目标检测Meanshif和Camshift算法解析

OpenCV目标检测Meanshif和Camshift算法解析

度为止。

OpenCV目标检测Meanshif和Camshift算法解析

OpenCV中的Camshift

它与Meanshift相似,但是返回一个旋转的矩形和box参数(用于在下一次迭代中作为搜索窗口传递)。

import cv2
import numpy as np
video_file = 'slow_traffic_small.mp4'
cap = cv2.VideoCapture(video_file)
# take first frame of the video
ret, frame = cap.read()
# setup initial location of window
x, y, w, h = 300, 200, 100, 50  # simply hardcoded the values
track_window = (x, y, w, h)
# setup the roi for tracking
roi = frame[y:y+h, x:x+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)
# setup the termination criteria, either 10 iteration or move by atleast 1 pt
term_crit = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10, 1)
while True:
   ret, frame = cap.read()
   if ret == True:
       hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
       dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
       # apply meansift to get the new location
       ret, track_window = cv2.CamShift(dst, track_window, term_crit)
       # draw it on image
       pts = cv2.boxPoints(ret)  # find four points of the box
       pts = np.int0(pts)
       img2 = cv2.polylines(frame, [pts], True, 255, 2)
       cv2.imshow('img2', img2)
       cv2.waitKey(0)
   else:
       cv2.destroyAllWindows()
       break

三帧的结果如下:

OpenCV目标检测Meanshif和Camshift算法解析

附加资源

  • French Wikipedia page on Camshift

  • Bradski, G.R., "Real time face and object tracking as a component of a perceptual user interface," Applications of Computer Vision, 1998. WACV '98. Proceedings., Fourth IEEE Workshop on , vol., no., pp.214,219, 19-21 Oct 1998

来源:https://juejin.cn/post/7225959500839878713

标签:OpenCV,Meanshif,Camshift,算法
0
投稿

猜你喜欢

  • Python二维码生成识别实例详解

    2021-06-10 19:59:22
  • 带你了解Python妙开根号的三种方式

    2021-10-18 08:27:56
  • 解决python 输出到csv 出现多空行的情况

    2022-11-09 10:27:39
  • Python中import语句用法案例讲解

    2023-08-07 05:33:47
  • python相对包导入报“Attempted relative import in non-package”错误问题解决

    2022-02-28 12:57:05
  • 用户体验之网页板块设计

    2011-05-14 16:41:00
  • ASP脚本循环语句

    2009-02-19 13:34:00
  • 详解Python logging调用Logger.info方法的处理过程

    2023-03-14 19:45:37
  • Python通过RabbitMQ服务器实现交换机功能的实例教程

    2023-08-24 01:15:19
  • Python实现桶排序与快速排序算法结合应用示例

    2022-10-26 23:33:39
  • python接入使用百度翻译流程

    2022-11-26 01:01:43
  •  Go 语言实现 HTTP 文件上传和下载

    2023-06-23 01:42:24
  • python编程使用PyQt制作预览窗口游戏中的小地图

    2023-12-29 09:54:24
  • YOLOv5车牌识别实战教程(五)字符分割与识别

    2022-04-07 07:38:25
  • centos6.7安装python2.7.11的具体方法

    2022-04-29 00:42:54
  • OpenCV计算平均值cv::mean实例代码

    2023-06-19 10:26:02
  • php日期转时间戳,指定日期转换成时间戳

    2023-06-20 17:02:23
  • Python实现从文件中加载数据的方法详解

    2022-05-28 12:41:31
  • 使用Python的Twisted框架编写非阻塞程序的代码示例

    2021-01-22 16:20:51
  • 价值3亿美元的按钮[译]

    2009-03-18 19:39:00
  • asp之家 网络编程 m.aspxhome.com