基于MeanShift算法的目标跟踪Word格式.docx
- 文档编号:16433994
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:19
- 大小:679.67KB
基于MeanShift算法的目标跟踪Word格式.docx
《基于MeanShift算法的目标跟踪Word格式.docx》由会员分享,可在线阅读,更多相关《基于MeanShift算法的目标跟踪Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
1.首先从摄像头或者本地文件读入视频
2.选择要跟踪的物体,程序读取一帧视频
3.计算视频帧的色调直方图
4.计算视频帧的反向投影图
5.输入反向投影图和跟踪矩形框,调用meanshift算法迭代,寻找局部最优解。
根据重心的移动,调整跟踪矩形框
6.读取下一帧视频,用当前矩形框作为输入,重复执行步骤2-5
1.4meanshift算法实现过程
1在颜色概率分布图中选取搜索窗W
2计算零阶距:
计算一阶距:
计算搜索窗的质心:
3调整搜索窗大小
宽度为
长度为1.2s
4移动搜索窗的中心到质心,如果移动距离大于预设的固定阈值,则重复2)3)4),直到搜索窗的中心与质心间的移动距离小于预设的固定阈值,或者循环运算的次数达到某一最大值,停止计算。
1.5meanshift算法跟踪效果
使用摄像头跟踪人的肤色效果如图1.5.1所示。
图1.5.1
对应于图1.5.1的反向投影图如下图1.5.2所示。
图1.5.2
点选区域的像素点直方图如图1.5.3所示。
图1.5.3
从以上效果图可以发现,meanshift算法处理的是HSV中的色调分量。
换句话说,就是通过追踪相同的颜色,而达到追踪物体的功能。
程序首先计算点选框里的有效像素点,通过统计获得像素点分布直方图;
然后计算出视频的反向投影图,即是像素点的概率分布图。
如上图1.5.2所示,越亮的点就是与原物体越匹配的点,大量的亮点的聚集处就极有可能是需要跟踪的物体;
最后用矩形框框住当前帧中带跟踪的物体,如上图1.5.1所示的结果。
当被跟踪的物体的色调与背景相似时,跟踪就会失效,如图1.5.4所示。
图1.5.4
显然,当背景与被跟踪物体颜色难以区分时跟踪会失败。
原因很简单,meanshift算法实现跟踪的原理就是通过计算色调的概率分布达到跟踪的效果,所以待跟踪的物体一定要与背景在色调上有区分度。
类似的,本程序也可以通过设置:
调试->
命令参数,使用本地的视频文件来实现视频中特定物体的跟踪,具体方法如图1.5.5所示。
由于实验的效果与使用摄像头跟踪物体差不多,所以就不一一截图显示了。
图1.5.5
2程序源码与数据结构
#include<
stdlib.h>
#include"
stdafx.h"
#ifdef_CH_
#pragmapackage<
opencv>
#endif
#ifndef_EiC
#include<
stdio.h>
cv.h"
highgui.h"
ctype.h>
IplImage*image=0,*hsv=0,*hue=0,*mask=0,*backproject=0,*histimg=0;
//用HSV中的Hue分量进行跟踪
CvHistogram*hist=0;
//直方图类
intbackproject_mode=0;
intselect_object=0;
inttrack_object=0;
intshow_hist=1;
CvPointorigin;
CvRectselection;
CvRecttrack_window;
CvBox2Dtrack_box;
//Meanshift跟踪算法返回的Box类
//typedefstructCvBox2D{
//CvPoint2D32fcenter;
/*盒子的中心*/
//CvSize2D32fsize;
/*盒子的长和宽*/
//floatangle;
/*水平轴与第一个边的夹角,用弧度表示*/
//}CvBox2D;
CvConnectedComptrack_comp;
//连接部件
//typedefstructCvConnectedComp{
//doublearea;
/*连通域的面积*/
//floatvalue;
/*分割域的灰度缩放值*/
//CvRectrect;
/*分割域的ROI*/
//}CvConnectedComp;
inthdims=32;
//划分直方图bins的个数,越多越精确
floathranges_arr[]={0,180};
//像素值的范围
float*hranges=hranges_arr;
//用于初始化CvHistogram类
intvmin=10,vmax=256,smin=30;
//用于设置滑动条
intcvmeanshift(constvoid*imgProb,CvRectwindowIn,CvTermCriteriacriteria,CvConnectedComp*comp)//实现meanshift算法
{
CvMomentsmoments;
//CvMoments用来计算矩形的重心,面积等形状特征
inti=0,eps;
CvMatstub,*mat=(CvMat*)imgProb;
CvMatcur_win;
CvRectcur_rect=windowIn;
//当前矩形框
CV_FUNCNAME("
cvmeanshift"
);
if(comp)//初始化跟踪矩形
{
comp->
rect=windowIn;
}
moments.m00=moments.m01=moments.m10=0;
//将阶矩和阶矩置
__BEGIN__;
CV_CALL(mat=cvGetMat(mat,&
stub));
if(CV_MAT_CN(mat->
type)>
1)//通道数选择出错
{
CV_ERROR(CV_BadNumChannels,cvUnsupportedFormat);
if(windowIn.height<
=0||windowIn.width<
=0)//点选的窗口无效
CV_ERROR(CV_StsBadArg,"
Inputwindowhasnon-positivesizes"
);
if(windowIn.x<
0||windowIn.x+windowIn.width>
mat->
cols||windowIn.y<
0||windowIn.y+windowIn.height>
rows)
InitialwindowisnotinsidetheimageROI"
CV_CALL(criteria=cvCheckTermCriteria(criteria,1.,100));
//迭代的标准,精度=1.0,迭代次数=100
eps=cvRound(criteria.epsilon*criteria.epsilon);
//精度eps=1
for(i=0;
i<
criteria.max_iter;
i++)
intdx,dy,nx,ny;
doubleinv_m00;
//选取搜索区域,对该矩形区域计算它的,1阶矩
CV_CALL(cvGetSubRect(mat,&
cur_win,cur_rect));
CV_CALL(cvMoments(&
cur_win,&
moments));
/*Calculatingcenterofmass*/
if(fabs(moments.m00)<
DBL_EPSILON)
{
break;
}
//搜索区域的质量m00
inv_m00=moments.inv_sqrt_m00*moments.inv_sqrt_m00;
//搜索区域的水平重心偏移dx
dx=cvRound(moments.m10*inv_m00-windowIn.width*0.5);
//搜索区域的垂直重心偏移dy
dy=cvRound(moments.m01*inv_m00-windowIn.height*0.5);
//搜索区域的重心坐标(nx,ny)
nx=cur_rect.x+dx;
ny=cur_rect.y+dy;
//跟踪目标处于图像边缘时进行一些对应的处理
if(nx<
0)
nx=0;
elseif(nx+cur_rect.width>
cols)
nx=mat->
cols-cur_rect.width;
if(ny<
ny=0;
elseif(ny+cur_rect.height>
ny=mat->
rows-cur_rect.height;
dx=nx-cur_rect.x;
dy=ny-cur_rect.y;
cur_rect.x=nx;
cur_rect.y=ny;
/*Checkforcoveragecentersmass&
window*/
//精度达到要求时就可以退出循环
if(dx*dx+dy*dy<
eps)
__END__;
if(comp)
rect=cur_rect;
area=(float)moments.m00;
//图像面积
returni;
}
voidon_mouse(intevent,intx,inty,intflags,void*param)
//鼠标回调函数,该函数用鼠标进行跟踪目标的选择
if(!
image)
return;
if(image->
origin)
y=image->
height-y;
//如果图像原点坐标在左下,则将其改为左上
if(select_object)
//select_object为,表示在用鼠标进行目标选择
//此时对矩形类selection用当前的鼠标位置进行设置
selection.x=MIN(x,origin.x);
selection.y=MIN(y,origin.y);
selection.width=selection.x+CV_IABS(x-origin.x);
selection.height=selection.y+CV_IABS(y-origin.y);
selection.x=MAX(selection.x,0);
selection.y=MAX(selection.y,0);
selection.width=MIN(selection.width,image->
width);
selection.height=MIN(selection.height,image->
height);
selection.width-=selection.x;
selection.height-=selection.y;
switch(event)
caseCV_EVENT_LBUTTONDOWN:
//鼠标按下,开始点击选择跟踪物体
origin=cvPoint(x,y);
selection=cvRect(x,y,0,0);
select_object=1;
break;
caseCV_EVENT_LBUTTONUP:
//鼠标松开,完成选择跟踪物体
select_object=0;
if(selection.width>
0&
&
selection.height>
//如果选择物体有效,则打开跟踪功能
track_object=-1;
CvScalarhsv2rgb(floathue)
//用于将Hue量转换成RGB量
intrgb[3],p,sector;
staticconstintsector_data[][3]=
{{0,2,1},{1,2,0},{1,0,2},{2,0,1},{2,1,0},{0,1,2}};
hue*=0.033333333333333333333333333333333f;
sector=cvFloor(hue);
p=cvRound(255*(hue-sector));
p^=sector&
1?
255:
0;
rgb[sector_data[sector][0]]=255;
rgb[sector_data[sector][1]]=0;
rgb[sector_data[sector][2]]=p;
returncvScalar(rgb[2],rgb[1],rgb[0],0);
intmain(intargc,char**argv)
CvCapture*capture=0;
if(argc==1||(argc==2&
strlen(argv[1])==1&
isdigit(argv[1][0])))
//打开摄像头
capture=cvCaptureFromCAM(argc==2?
argv[1][0]-'
0'
:
0);
elseif(argc==2)
//打开avi
capture=cvCaptureFromAVI(argv[1]);
capture)
//打开视频流失败
fprintf(stderr,"
Couldnotinitializecapturing...\n"
return-1;
printf("
Hotkeys:
\n"
"
\tESC-quittheprogram\n"
\tc-stopthetracking\n"
\tb-switchto/frombackprojectionview\n"
\th-show/hideobjecthistogram\n"
Toinitializetracking,selecttheobjectwithmouse\n"
//打印程序功能列表
cvNamedWindow("
Histogram"
1);
//用于显示直方图
MeanShiftDemo"
//用于显示视频
cvSetMouseCallback("
on_mouse,0);
//设置鼠标回调函数
cvCreateTrackbar("
Vmin"
"
&
vmin,256,0);
Vmax"
vmax,256,0);
Smin"
smin,256,0);
//设置滑动条
for(;
;
)
//进入视频帧处理主循环
IplImage*frame=0;
inti,bin_w,c;
frame=cvQueryFrame(capture);
//读取一帧图像
frame)
//image为,表明刚开始还未对image操作过,先建立一些缓冲区
image=cvCreateImage(cvGetSize(frame),8,3);
image->
origin=frame->
origin;
hsv=cvCreateImage(cvGetSize(frame),8,3);
hue=cvCreateImage(cvGetSize(frame),8,1);
mask=cvCreateImage(cvGetSize(frame),8,1);
//分配掩膜图像空间
backproject=cvCreateImage(cvGetSize(frame),8,1);
//分配反向投影图空间,大小一样,单通道
hist=cvCreateHist(1,&
hdims,CV_HIST_ARRAY,&
hranges,1);
//分配直方图空间
histimg=cvCreateImage(cvSize(320,200),8,3);
//分配用于直方图显示的空间
cvZero(histimg);
//置背景为黑色
cvCopy(frame,image,0);
cvCvtColor(image,hsv,CV_BGR2HSV);
//把图像从RGB表色系转为HSV表色系
if(track_object)
//track_object非零,表示有需要跟踪的物体
int_vmin=vmin,_vmax=vmax;
cvInRangeS(hsv,cvScalar(0,smin,MIN(_vmin,_vmax),0),
cvScalar(180,256,MAX(_vmin,_vmax),0),mask);
//制作掩膜板,只处理像素值为H:
~180,S:
smin~256,V:
vmin~vmax之间的部分
cvSplit(hsv,hue,0,0,0);
//分离H分量
if(track_object<
//如果需要跟踪的物体还没有进行属性提取,则进行选取框类的图像属性提取
floatmax_val=0.f;
cvSetImageROI(hue,selection);
//设置原选择框为ROI
cvSetImageROI(mask,selection);
//设置掩膜板选择框为ROI
cvCalcHist(&
hue,hist,0,mask);
//得到选择框内且满足掩膜板内的直方图
cvGetMinMaxHistValue(hist,0,&
max_val,0,0);
cvConvertScale(hist->
bins,hist->
bins,max_val?
255./max_val:
0.,0);
//对直方图的数值转为~255
cvResetImageROI(hue);
//去除ROI
cvResetImageROI(mask);
track_window=selection;
track_object=1;
//置track_object为,表明属性提取完成
bin_w=histimg->
width/hdims;
hdims;
//画直方图到图像空间
intval=cvRound(cvGetReal1D(hist-
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 MeanShift 算法 目标 跟踪