opencv-Python 目标跟踪(一)《Meanshift算法、Camshift算法》
作者:RayChiu_Labloy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
目录
Meanshift算法
Meanshift算法原理:
追踪一个运动的物体大致流程如下:
视频追踪目标测试:
Camshift算法
对meanShift的改进:
原理:
分为三个部分:
1、色彩投影图(反向投影):
2、meanshift
3--camshift
Meanshift算法
meanShift,均值漂移,在聚类、图像平滑、分割、跟踪等方面有着广泛的应用,其最初的含义正如其名:偏移的均值向量;但随着理论的发展,meanShift的含义已经发生了很多变化。如今,我们说的meanShift算法,一般是指一个迭代的步骤,即先算出当前点的偏移均值,然后以此为新的起始点,继续移动,直到满足一定的结束条件。
Meanshift算法原理:
假设你有一堆点集,例如直方图反向投影得到的点集。还有一个小的窗口,这个窗口可能是圆形的,现在要移动这个窗口到点集密度最大的区域当中。
最开始的窗口是蓝色圆环的区域,命名为C1。蓝色圆环的重音用一个蓝色的矩形标注,命名为C1_o。
然而,我们发现在这个窗口当中所有点的点集构成的质心在蓝色圆形点处。而且,圆环的型心和质心并不重合。所以,移动蓝色的窗口,使得型心与之前得到的质心重合。在新移动后的圆环的区域当中再次寻找圆环当中所包围点集的质心,然后再次移动,通常情况下,型心和质心是不重合的。不断执行上面的移动过程,直到型心和质心大致重合结束。
这样,最后圆形的窗口会落到像素分布最大的地方,也就是图中的绿色圈,命名为C2。
meanshift算法不仅仅限制在二维的图像处理问题当中,同样也可以使用于高维的数据处理。可以通过选取不同的核函数,来改变区域当中偏移向量的权重,最后meanshift算法的过程一定会收敛到某一个位置。
meanshift算法除了应用在视频追踪当中,在聚类,平滑等等各种涉及到数据以及非监督学习的场合当中均有重要应用,是一个应用广泛的算法。
假如在二维环境当中,meanshift算法处理的数据是一群离散的二维点集,但是图像是一个矩阵信息,如何在一个视频当中使用meanshift算法来追踪一个运动的物体呢?
追踪一个运动的物体大致流程如下:
1.首先在图像上使用矩形框或者圆形框选定一个目标区域
2.计算选定好区域的直方图分布。
3.对下一帧图像b同样计算直方图分布。
4.计算图像b当中与选定区域直方图分布最为相似的区域,使用meanshift算法将选定区域沿着最为相似的部分进行移动。(样例当中使用的是直方图反向投影)
5.重复3到4的过程。
视频追踪目标测试:
import cv2
import numpy as np# 设置初始化的窗口位置
r,h,c,w = 0,200,0,200 # 设置初试窗口位置和大小
track_window = (c,r,w,h)cap = cv2.VideoCapture(0)
ret, frame= cap.read() # 设置追踪的区域
roi = frame[r:r+h, c:c+w]
# roi区域的hsv图像
hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 取值hsv值在(0,60,32)到(180,255,255)之间的部分
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次或者至少移动1次
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 ) while(1):ret, frame = cap.read()frame = cv2.flip(frame,1)if ret == True:# 计算每一帧的hsv图像hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# 计算反向投影dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)# 调用meanShift算法在dst中寻找目标窗口,找到后返回目标窗口ret, track_window = cv2.meanShift(dst, track_window, term_crit)# Draw it on imagex,y,w,h = track_windowimg2 = cv2.rectangle(frame, (x,y), (x+w,y+h), 255,2)cv2.imshow('img2',img2)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()
Camshift算法
对meanShift的改进:
如果被追踪的物体迎面过来,由于透视效果,物体会放大,之前设置好的窗口区域大小会不合适, Camshift会调整框的大小。
原理:
camshift利用目标的颜色直方图模型将图像转换为颜色概率分布图,初始化一个搜索窗的大小和位置,并根据上一帧得到的结果自适应调整搜索窗口的位置和大小,从而定位出当前图像中目标的中心位置。
分为三个部分:
1、色彩投影图(反向投影):
(1).RGB颜色空间对光照亮度变化较为敏感,为了减少此变化对跟踪效果的影响,首先将图像从RGB空间转换到HSV空间。
(2).然后对其中的H分量作直方图,在直方图中代表了不同H分量值出现的概率或者像素个数,就是说可以查找出H分量大小为h的概率或者像素个数,即得到了颜色概率查找表。
(3).将图像中每个像素的值用其颜色出现的概率对替换,就得到了颜色概率分布图。这个过程就叫反向投影,颜色概率分布图是一个灰度图像。
2、meanshift
meanshift算法是一种密度函数梯度估计的非参数方法,通过迭代寻优找到概率分布的极值来定位目标。
算法过程为:
(1).在颜色概率分布图中选取搜索窗W
(2).计算零阶距:
计算一阶矩:
计算搜索框的质心:
(3).调整搜索窗大小,宽度为:
长度为1.2s;
(4).移动搜索窗的中心到质心,如果移动距离大于预设的固定阈值,则重复2)3)4),直到搜索窗的中心与质心间的移动距离小于预设的固定阈值,或者循环运算的次数达到某一最大值,停止计算。
3--camshift
将meanshift算法扩展到连续图像序列,就是camshift算法。它将视频的所有帧做meanshift运算,并将上一帧的结果,即搜索窗的大小和中心,作为下一帧meanshift算法搜索窗的初始值。如此迭代下去,就可以实现对目标的跟踪。
算法过程为:
(1).初始化搜索窗
(2).计算搜索窗的颜色概率分布(反向投影)
(3).运行meanshift算法,获得搜索窗新的大小和位置。
(4).在下一帧视频图像中用(3)中的值重新初始化搜索窗的大小和位置,再跳转到(2)继续进行。
camshift能有效解决目标变形和遮挡的问题,对系统资源要求不高,时间复杂度低,在简单背景下能够取得良好的跟踪效果。但当背景较为复杂,或者有许多与目标颜色相似像素干扰的情况下,会导致跟踪失败。因为它单纯的考虑颜色直方图,忽略了目标的空间分布特性,所以这种情况下需加入对跟踪目标的预测算法。
视频追踪测试:
import cv2
import numpy as npcap = cv2.VideoCapture(0)# ret判断是否读到图片
# frame读取到的当前帧的矩阵
# 返回的是元组类型,所以也可以加括号
ret, frame = cap.read()# 设置跟踪框参数
r, h, c, w = 0, 100, 0, 100 # simply hardcoded the values
track_window = (c, r, w, h) # 从当前帧中框出一个小框
roi = frame[r:r + h, c:c + w]
# RGB转为HSV更好处理
hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# inRange函数设置亮度阈值
# 去除低亮度的像素点的影响
# eg. mask = cv2.inRange(hsv, lower_red, upper_red)
# 将低于和高于阈值的值设为0
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.))) # 然后得到框中图像的直方图
# cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]])
# mask 即上文的阈值设置
# histSize表示这个直方图分成多少份(即多少个直方柱)
# range是表示直方图能表示像素值的范围
# 返回直方图
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180]) # 归一化函数CV2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]])
# 返回dst类型
# 归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内
# src - 输入数组
# dst - 与src大小相同的输出数组
# alpha - 范围值, 以便在范围归一化的情况下归一化到较低范围边界
# beta - 范围归一化时的上限范围; 它不用于标准规范化
# normType - 规范化类型 这里的NORM_MINMAX是数组的数值被平移或缩放到一个指定的范围,线性归一化。
# dtype - 当为负数时,输出数组与src的类型相同;否则,它具有与src相同的通道数;深度=CV_MAT_DEPTH(dtype)
# mask - 可选的操作掩码。
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 设置迭代的终止标准,最多十次迭代
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) while (1): ret, frame = cap.read() if ret == True: hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 反向投影函数(特征提取函数) # 反向投影是一种记录给定图像中的像素点如何适应直方图模型像素分布的方式 # 反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的特征 # cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])# images:待处理的图像,图像格式为uint8或float32 # channels:对应图像需要统计的通道,若是灰度图则为0,彩色图像B、G、R对应0、1、2 # mask:掩膜图像。如果统计整幅图像就设置为None,否则这里传入设计的掩膜图像。 # histSize表示这个直方图分成多少份(即多少个直方柱) # ranges:像素量化范围,通常为0 - 255。 dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1) # RotatedRect CamShift(InputArray probImage, Rect&window, TermCriteria criteria。 # probImage为输入图像直方图的反向投影图, # window为要跟踪目标的初始位置矩形框, # criteria为算法结束条件。 # 函数返回一个有方向角度的矩阵。ret, track_window = cv2.CamShift(dst, track_window, term_crit) # Draw it on image pts = cv2.boxPoints(ret) # 类型转换int0()用于索引的整数(same as C ssize_t; normally either int32 or int64) pts = np.int0(pts) # 非填充多边形:polylines() # cv2.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) # img – 要画的图片 # pts – 多边形的顶点 # isClosed – 是否闭合线段 # color – 颜色 img2 = cv2.polylines(frame, [pts], True, 255, 2) cv2.imshow('img2', img2) # 停止追踪按钮 k = cv2.waitKey(60) & 0xff if k == 27: break else: cv2.imwrite(chr(k) + ".jpg", img2) else: break cv2.destroyAllWindows()
cap.release()
【如果对您有帮助,交个朋友给个一键三连吧,您的肯定是我博客高质量维护的动力!!!】
opencv-Python 目标跟踪(一)《Meanshift算法、Camshift算法》相关推荐
- opencv python 多帧降噪算法_OpenCV-Python中用于视频跟踪的Meanshift和Camshift算法介绍...
学习目标 在本章中, 我们将学习用于跟踪视频中对象的Meanshift和Camshift算法. Meanshift Meanshift背后的直觉很简单,假设你有点的集合.(它可以是像素分布,例如直方图 ...
- 机器视觉 OpenCV—python目标跟踪(光流)
文章目录 一.运动检测 1.1 检测思路 1.2 代码 二.运动方向预测 2.1 关键点(角点)追踪 goodFeaturesToTrack() 2.2 光流法 一.运动检测 1.1 检测思路 目标跟 ...
- 使用Python,OpenCV的Meanshift 和 Camshift 算法来查找和跟踪视频中的对象
使用Python,OpenCV的Meanshift 和 Camshift 算法来查找和跟踪视频中的对象 1. 效果图 2. 源码 2.1 MeanShift 2.2 Camshift(Continuo ...
- 基于Python和OpenCV的目标跟踪学习教程 Object Tracking using Python and OpenCV
实现12种不同的算法来跟踪视频和网络摄像头中的对象! 你会学到: 使用Python和OpenCV跟踪视频和网络摄像头中的对象 理解跟踪算法的基本直觉 实现12种跟踪算法 了解对象检测和对象跟踪之间的区 ...
- Object Tracking using OpenCV (C++/Python)(使用OpenCV进行目标跟踪)
本博客翻译搬运自https://www.learnopencv.com/object-tracking-using-opencv-cpp-python,用于初入目标跟踪的新手学习,转贴请注明! 使用O ...
- OpenCV均值移位(Meanshift)和Camshift算法
OpenCV Meanshift和Camshift算法 Meanshift和Camshift算法 目标 均值漂移Meanshift OpenCV中的Meanshift Camshift OpenCV中 ...
- OpenCV视频目标跟踪及背景分割器
目标跟踪 本文主要介绍cv2中的视频分析Camshift和Meanshift. 目标: 学习Meanshift算法和Camshift算法来寻找和追踪视频中的目标物体 Meanshift算法: mean ...
- 视频操作_02视频追踪:meanshift算法+Camshift算法
1.meanshift 1.1原理 meanshift算法的原理很简单.假设你有一堆点集,还有一个小的窗口,这个窗口可能是圆形的,现在你可能要移动这个窗口到点集密度最大的区域当中. 如下图: 最开始的 ...
- opencv动态目标跟踪学习总结
用opencv实现对视频中动态目标的追踪 第一步,是要建立一个编程环境,然后加载opencv的库路径等等.具体步骤在 http://www.opencv.org.cn/ 的"安装" ...
- 笔记 基于OpenCV的目标跟踪软件与系统实现
1.目标检测理论包括光流法.帧间差分法和背景差分法, 目标分割理论包括全局阈值法和局部阈值法, 目标跟踪的均值漂移法和卡尔曼滤波法. 2.基于opencv的目标跟踪软件设计于实现 在vc环境下,按照单 ...
最新文章
- c++重载运算符_C/C++编程笔记:运算符重载丨重载C++中的New和Delete运算符
- ArcPy学习入门(三):ArcPy 函数列表
- C Primer Plus 第7章 C控制语句:分支和跳转 7.1 if语句
- LUA table.sort的问题,数组与表的区别
- 数据结构(严蔚敏)之一——顺序表之c语言实现
- mysql errmsg unknown_详解MySQL Server 启动时出现bug的解决方法
- You must install pydot and graphviz for plotmodel to work报错如何处理
- RabbitMQ 基本概念与高级特性
- 【NOIP2010】【Luogu1179】数字统计(模拟,多位数分离)
- 家谱处理 (30 分)(map映射)
- 需求分析,我们应当怎样做
- 嵌入式Qt(实验三)——Qt网络编程
- Endnotex7无法保存修改后的格式
- 致远互联发布的智慧协同新一代企业管理平台,新在哪里?
- 机架服务器怎么安装系统,华三服务器安装系统步骤(图解华三服务器怎么安装)...
- 一文告诉你IT行业什么方向赚钱,需求多
- 集成学习方法之Bagging,Boosting,Stacking
- 计算机毕业设计基于Android平台的公交线路查询系统app
- 使用poi解析Excel
- labview中前面板如何设置背景图片
热门文章
- css盒模型——标准盒子、怪异盒子
- (基于matlab自写代码)语音信号的线性预测
- 数据分析方法:结构分析法
- 伴鱼英语有计算机英语语言吗,伴鱼少儿英语电脑版
- 设(X1,X2,…,Xn) 是来自正态总体N(μ,σ2),的一个样本,其中μ,σ2未知,求μ与σ2的极大似然估计量.
- 《C++ 黑客编程揭秘与防范(第2版)》—第6章6.2节详解PE文件结构
- Printing 1 to 1000 without loop or conditionals
- 硅谷的程序员, 入职第一天都在干什么?
- Toad 工具使用心得
- Stata画图——散点图与折线图