配色: 字号:
PariticalFilter在MFC上的运行
2017-01-21 | 阅:  转:  |  分享 
  
PariticalFilter在MFC上的运行



由于项目需要,进行过一段时间的PariticalFilter研究。主要的工作就是将网络上的Console代码和Mfc融合在一起,并且添加了Mfc端的控制功能。



程序还有不完善的地方,现将相关的函数发布出来,大家相互研究。



程序的核心为两个部分,一个是核心PF函数,一个是界面操作

核心函数

/@file

Definitionsrelatedtotrackingwithparticlefiltering

@authorRobHess

@version1.0.0-20060307

jsxyhelu2016年11月修改更多代码,请浏览jsxyhelu.cnblogs.com

jsxyhelu2016年12月代码梳理,重构

/

#include"stdafx.h"

#include"GOPF.h"

usingnamespacestd;

usingnamespacecv;

//非常值得注意的一点是,本例中的指针的运用极大地提高了系统速度

//使用方法

///变量

intnum_particles=100;//狗的数目

intiFrame=0;//当前为第几帧

RectrectStart;//初始化矩形

MatmatFrame;//原始帧

MatmatClone;//原始帧复制

MatmatHSV;//原始帧的HSV形式

particleparticles,new_particles;

//gsl初始化

gsl_rngrng;

gsl_rng_env_setup();

rng=gsl_rng_alloc(gsl_rng_mt19937);

gsl_rng_set(rng,time(NULL));

//gsl初始化结束,rng为输出

//打开视频

VideoCapturevideocapture;

videocapture.open("e:/sandbox/1.avi");

if(!videocapture.isOpened())

{

printf("视频打开失败!");

return-1;

}

//TODO

rectStart=Rect(449,86,21,13);

//主要循环

for(;;)

{

videocapture>>matFrame;

if(matFrame.empty())

break;

matClone=matFrame.clone();

imshow("原始图像",matFrame);

//step0当前帧转换为hsv模式,注意是在float下转换

matFrame.convertTo(matHSV,CV_32F,1.0/255);

cvtColor(matHSV,matHSV,COLOR_BGR2HSV);

//step1如果为第一帧,初始化相关数据

if(iFrame==0)

{

//计算初始区域的粒子

histogramref_histos=compute_ref_histos(matHSV,rectStart);

particles=init_distribution(rectStart,ref_histos,1,num_particles);

iFrame=1;

}

else

{

//step2放出100狗

for(intj=0;j
{

//生成随机狗

particles[j]=transition(particles[j],matFrame.cols,matFrame.rows,rng);

floats=particles[j].s;

//计算相似性

particles[j].w=likelihood(matHSV,cvRound(particles[j].y),

cvRound(particles[j].x),

cvRound(particles[j].widths),

cvRound(particles[j].heights),

particles[j].histo);

}

//step3重新规划

normalize_weights(particles,num_particles);

new_particles=resample(particles,num_particles);

free(particles);

particles=new_particles;

}

display_particle(&matClone,particles);

imshow("结果图像",matClone);

waitKey(15);

iFrame=iFrame+1;

}/



//根据hsv的bin的返回结果

inthisto_bin(floath,floats,floatv)

{

#defineH_MAX360.0

#defineS_MAX1.0

#defineV_MAX1.0

#defineS_THRESH0.1

#defineV_THRESH0.2

inthd,sd,vd;

/ifSorVislessthanitsthreshold,returna"colorless"bin/

vd=MIN((int)(vNV/V_MAX),NV-1);

if(s
returnNHNS+vd;

/otherwisedetermine"colorful"bin/

hd=MIN((int)(hNH/H_MAX),NH-1);

sd=MIN((int)(sNS/S_MAX),NS-1);returnsdNH+hd;

}

//计算直方图结果,因为所有的值都是计算成直方图,所以这个是核心算法(意味运行次数最多,优化最有效)

histogramcalc_histogram(IplImageimgs,intn)

{

histogramhisto;

IplImageh,s,v;

floathist;

inti,r,c,bin;

histo=(histogram)malloc(sizeof(histogram));

histo->n=NHNS+NV;

hist=histo->histo;

memset(hist,0,histo->nsizeof(float));

h=cvCreateImage(cvGetSize(imgs),IPL_DEPTH_32F,1);

s=cvCreateImage(cvGetSize(imgs),IPL_DEPTH_32F,1);

v=cvCreateImage(cvGetSize(imgs),IPL_DEPTH_32F,1);

cvSplit(imgs,h,s,v,NULL);

/incrementappropriatehistogrambinforeachpixel/

for(r=0;rheight;r++)

for(c=0;cwidth;c++)

{

bin=histo_bin(/pixval32f(h,r,c)/((float)(h->imageData+h->widthStepr))[c],

((float)(s->imageData+s->widthStepr))[c],

((float)(v->imageData+v->widthStepr))[c]);

hist[bin]+=1;

}

cvReleaseImage(&h);

cvReleaseImage(&s);

cvReleaseImage(&v);

returnhisto;

}

//直方图正定化

voidnormalize_histogram(histogramhisto)

{

floathist;

floatsum=0,inv_sum;

inti,n;

hist=histo->histo;

n=histo->n;

/computesumofallbinsandmultiplyeachbinbythesum''sinverse/

for(i=0;i
sum+=hist[i];

inv_sum=1.0/sum;

for(i=0;i
hist[i]=inv_sum;

}

//计算n个histogram的数据结构

histogramcompute_ref_histos(Matsrc,Rectrect)

{

IplImagematsrc(src);

IplImageframe=&matsrc;

CvRectregions=(CvRect)rect;

histogramhistos=(histogram)malloc(sizeof(histogram));

IplImagetmp;

cvSetImageROI(frame,regions);

tmp=cvCreateImage(cvGetSize(frame),IPL_DEPTH_32F,3);

cvCopy(frame,tmp,NULL);

cvResetImageROI(frame);

histos=calc_histogram(tmp,1);

normalize_histogram(histos);

cvReleaseImage(&tmp);

returnhistos;

}

//初始化distribution

particleinit_distribution(Rectrect,histogramhistos,intn,intp)

{

CvRectregions=(CvRect)rect;

particleparticles;

intnp;

floatx,y;

inti,j,width,height,k=0;

particles=(particle)malloc(psizeof(particle));

np=p/n;

width=regions.width;

height=regions.height;

x=regions.x+width/2;

y=regions.y+height/2;

for(j=0;j
{

particles[k].x0=particles[k].xp=particles[k].x=x;

particles[k].y0=particles[k].yp=particles[k].y=y;

particles[k].sp=particles[k].s=1.0;

particles[k].width=width;

particles[k].height=height;

particles[k].histo=histos;

particles[k++].w=0;

}

/makesuretocreateexactlypparticles/

i=0;

while(k
{

width=regions.width;

height=regions.height;

x=regions.x+width/2;

y=regions.y+height/2;

particles[k].x0=particles[k].xp=particles[k].x=x;

particles[k].y0=particles[k].yp=particles[k].y=y;

particles[k].sp=particles[k].s=1.0;

particles[k].width=width;

particles[k].height=height;

particles[k].histo=histos;

particles[k++].w=0;

i=(i+1)%n;

}

returnparticles;

}

//预测狗的位置

particletransition(particlep,intw,inth,gsl_rngrng)

{

#defineTRANS_X_STD1.0

#defineTRANS_Y_STD0.5

#defineTRANS_S_STD0.001

/autoregressivedynamicsparametersfortransitionmodel/

#defineA12.0

#defineA2-1.0

#defineB01.0000

floatx,y,s;

particlepn;

//采用second-order进行狗的估算

/samplenewstateusingsecond-orderautoregressivedynamics/

x=A1(p.x-p.x0)+A2(p.xp-p.x0)+

B0gsl_ran_gaussian(rng,TRANS_X_STD)+p.x0;

pn.x=MAX(0.0,MIN((float)w-1.0,x));

y=A1(p.y-p.y0)+A2(p.yp-p.y0)+

B0gsl_ran_gaussian(rng,TRANS_Y_STD)+p.y0;

pn.y=MAX(0.0,MIN((float)h-1.0,y));

s=A1(p.s-1.0)+A2(p.sp-1.0)+

B0gsl_ran_gaussian(rng,TRANS_S_STD)+1.0;

pn.s=MAX(0.1,s);

pn.xp=p.x;

pn.yp=p.y;

pn.sp=p.s;

pn.x0=p.x0;

pn.y0=p.y0;

pn.width=p.width;

pn.height=p.height;

pn.histo=p.histo;

pn.w=0;

returnpn;

}

//histogram比较,马氏距离

floathisto_dist_sq(histogramh1,histogramh2)

{

floathist1,hist2;

floatsum=0;

inti,n;

n=h1->n;

hist1=h1->histo;

hist2=h2->histo;

for(i=0;i
sum+=sqrt(hist1[i]hist2[i]);

return1.0-sum;

}

//粒子比较

intparticle_cmp(constvoidp1,constvoidp2)

{

particle_p1=(particle)p1;

particle_p2=(particle)p2;

if(_p1->w>_p2->w)

return-1;

if(_p1->w<_p2->w)

return1;

return0;

}

//相似性计算

floatlikelihood(MatmatSrc,intr,intc,intw,inth,histogramref_histo)

{

#defineLAMBDA20

IplImagematimg(matSrc);

IplImageimg=&matimg;



IplImagetmp;

histogramhisto;

floatd_sq;

/extractregionaround(r,c)andcomputeandnormalizeitshistogram/

cvSetImageROI(img,cvRect(c-w/2,r-h/2,w,h));

tmp=cvCreateImage(cvGetSize(img),IPL_DEPTH_32F,3);

cvCopy(img,tmp,NULL);

cvResetImageROI(img);

histo=calc_histogram(tmp,1);

cvReleaseImage(&tmp);

normalize_histogram(histo);

/computelikelihoodase^{\lambdaD^2(h,h^)}/

d_sq=histo_dist_sq(histo,ref_histo);

free(histo);

returnexp(-LAMBDAd_sq);

}

//权值归一化

voidnormalize_weights(particleparticles,intn)

{

floatsum=0;

inti;

for(i=0;i
sum+=particles[i].w;

for(i=0;i
particles[i].w/=sum;

}

//重新采样

particleresample(particleparticles,intn)

{

particlenew_particles;

inti,j,np,k=0;

//quicksort

qsort(particles,n,sizeof(particle),&particle_cmp);

new_particles=(particle)malloc(nsizeof(particle));

for(i=0;i
{

np=cvRound(particles[i].wn);

for(j=0;j
{

new_particles[k++]=particles[i];

if(k==n)

gotoexit;

}

}

while(k
new_particles[k++]=particles[0];

exit:

returnnew_particles;

}

//显示PF的结果

voiddisplay_particle(Matimg,particlep)

{

intx0,y0,x1,y1;

x0=cvRound(p.x-0.5p.sp.width);

y0=cvRound(p.y-0.5p.sp.height);

x1=x0+cvRound(p.sp.width);

y1=y0+cvRound(p.sp.height);

cv::rectangle(img,Point(x0,y0),Point(x1,y1),Scalar(0,0,255));

}

界面处理相关

voidCGOMfcTemplate2Dlg::OnMouseMove(UINTnFlags,CPointpoint)

{

CRectrect_ctr;

(this->GetDlgItem(IDC_CAM))->GetWindowRect(&rect_ctr);//获取Picture控件相对屏幕左上角的坐标,

ScreenToClient(rect_ctr);//获取Picture控件相对对话框客户区左上角的坐标

instant_position.x=point.x;

instant_position.y=point.y;

picture_ordinate_x=point.x-rect_ctr.left;

picture_ordinate_y=point.y-rect_ctr.top;//point获取的是鼠标相对对话框客户区左上角的坐标,减去rect_ctr.left和rect_ctr.top后,即为鼠标相对Picture控件左上角的坐标

if((nFlags==MK_LBUTTON)&&Is_LeftButton_Down)

{

::SetCursor(cross);

CClientDCdc(this);

CBrushOldBrush;

OldBrush=(CBrush)dc.SelectStockObject(NULL_BRUSH);

dc.SetROP2(R2_NOT);

dc.Rectangle(CRect(chosen_position,instant_position));

dc.Rectangle(CRect(chosen_position,point));

dc.SelectObwww.baiyuewang.netject(OldBrush);

instant_position=point;

}

else

::SetCursor(arrow);

CDialogEx::OnMouseMove(nFlags,point);

}



voidCGOMfcTemplate2Dlg::OnLButtonDown(UINTnFlags,CPointpoint)

{

Is_LeftButton_Down=true;

::SetCursor(cross);

chosen_position=instant_position=point;

CDialogEx::OnLButtonDown(nFlags,point);

}

voidCGOMfcTemplate2Dlg::OnLButtonUp(UINTnFlags,CPointpoint)

{

if(Is_LeftButton_Down)

{

Is_LeftButton_Down=false;

::SetCursor(arrow);

CClientDCdc(this);

CPenpOldPen=(CPen)dc.SelectObject(&pen);

dc.MoveTo(chosen_position);

dc.LineTo(chosen_position.x,instant_position.y);

dc.LineTo(instant_position);

dc.LineTo(instant_position.x,chosen_position.y);

dc.LineTo(chosen_position);

//写到rect_res中区

intrect_x=min(chosen_position.x,instant_position.x);

intrect_y=min(chosen_position.y,instant_position.y);

intrect_w=abs(chosen_position.x-instant_position.x);

intrect_h=abs(chosen_position.y-instant_position.y);

rectStart=Rect(rect_x,rect_y,rect_w,rect_h);

}

CDialogEx::OnLButtonUp(nFlags,point);

}

献花(0)
+1
(本文系thedust79首藏)