背景建模练习练习.docx

上传人:b****4 文档编号:24444426 上传时间:2023-05-27 格式:DOCX 页数:21 大小:2.35MB
下载 相关 举报
背景建模练习练习.docx_第1页
第1页 / 共21页
背景建模练习练习.docx_第2页
第2页 / 共21页
背景建模练习练习.docx_第3页
第3页 / 共21页
背景建模练习练习.docx_第4页
第4页 / 共21页
背景建模练习练习.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

背景建模练习练习.docx

《背景建模练习练习.docx》由会员分享,可在线阅读,更多相关《背景建模练习练习.docx(21页珍藏版)》请在冰豆网上搜索。

背景建模练习练习.docx

背景建模练习练习

二帧差法:

#include

#include

#include

#definethreshold_diff20//设置简单帧差法阈值

usingnamespacecv;

usingnamespacestd;

intmain(intargc,unsignedchar*argv[])

{

Matimg_src1,img_src2,img_dst,gray1,gray2,gray_diff;

boolpause=false;

VideoCapturevido_file("test.avi");//在这里改相应的文件名

namedWindow("foreground",0);

for(;;)

{

if(!

pause)

{

vido_file>>img_src1;//提取一副图像

cvtColor(img_src1,gray1,CV_BGR2GRAY);//转化为灰度图像

imshow("video_src1",img_src1);

waitKey(5);

vido_file>>img_src2;//过5毫秒又一副图像

cvtColor(img_src2,gray2,CV_BGR2GRAY);

imshow("video_src2",img_src2);

waitKey(5);

subtract(gray1,gray2,gray_diff);//函数计算两幅灰度图像的差值

for(inti=0;i

for(intj=0;j

if(abs(gray_diff.at(i,j))>=threshold_diff)

gray_diff.at(i,j)=255;

elsegray_diff.at(i,j)=0;

imshow("foreground",gray_diff);//完成对每个点的检测后显示这幅图

}

charc=(char)waitKey(10);

if(c==27)

{

break;

}

if(c=='')

pause=!

pause;

}

return0;

}

三帧差法:

#include

#include

#include

#definethreshold_diff110

#definethreshold_diff210

usingnamespacecv;

usingnamespacestd;

intmain(intargc,unsignedchar*argv[]){

Matimg_src1,img_src2,img_src3;

Matimg_dst,gray1,gray2,gray3;

Matgray_diff1,gray_diff2;

Matgray;

boolpause=false;

VideoCapturevido_file("test.avi");

for(;;){

if(!

pause){

vido_file>>img_src1;

cvtColor(img_src1,gray1,CV_BGR2GRAY);

waitKey(5);

vido_file>>img_src2;

cvtColor(img_src2,gray2,CV_BGR2GRAY);

waitKey(5);

vido_file>>img_src3;

cvtColor(img_src3,gray3,CV_BGR2GRAY);

subtract(gray2,gray1,gray_diff1);

subtract(gray3,gray2,gray_diff2);

imshow("1",img_src2);

imshow("2",gray1);

imshow("3",gray2);

imshow("4",gray_diff1);

imshow("5",gray_diff2);

for(inti=0;i

for(intj=0;j

if(abs(gray_diff1.at(i,j))>threshold_diff1)

gray_diff1.at(i,j)=255;

elsegray_diff1.at(i,j)=0;

if(abs(gray_diff2.at(i,j))>threshold_diff2)

gray_diff2.at(i,j)=255;

elsegray_diff2.at(i,j)=0;

}

}

bitwise_and(gray_diff1,gray_diff2,gray);//求两个的交集

imshow("前景",gray);

}

charc=(char)waitKey(500);

if(c==27)break;

if(c=='')pause=!

pause;

}

return0;

}

结果截图:

平均背景建模:

通过多幅图像求图像的平均值和差值的平均值,并以此为依据建立背景模型,差值用于比较的阀值的参考数据,通过比较当前帧与背景模型,确定前景。

#include

#include

#include

IplImage*IavgF,*IdiffF,*IprevF,*IhiF,*IlowF;

IplImage*Iscratch,*Iscratch2;

IplImage*Igray1,*Igray2,*Igray3;

IplImage*Ilow1,*Ilow2,*Ilow3;

IplImage*Ihi1,*Ihi2,*Ihi3;

IplImage*Imaskt;

IplImage*Imask;

floatIcount;

voidAllocateImages(IplImage*I);

voidaccumulateBackground(IplImage*I);

voidcreateModelsfromStats();

voidsetHighThreshold(floatscale);

voidsetLowThreshold(floatscale);

voidbackgroundDiff(IplImage*I,IplImage*Imask);

voidDeallocateImages();

intmain(intargc,char**argv)

{

CvCapture*capture=cvCreateCameraCapture(-1);

if(NULL==capture)

{

printf("没有找到摄像头装置!

\n");

return-1;

}

IplImage*Img=cvQueryFrame(capture);

cvNamedWindow("原图",0);

cvNamedWindow("检测图",0);

cvShowImage("原图",Img);

AllocateImages(Img);//初始化

printf("开始统计背景模型\n");

while(Icount<30)//统计背景模型

{

accumulateBackground(Img);

Img=cvQueryFrame(capture);

cvWaitKey(10);

cvShowImage("原图",Img);

printf(".");

}

createModelsfromStats();//就算每一个像素的均值和方差观测

printf("\n统计背景模型结束.....\n");

printf("按任意键开始分割图像.....\n");

cvWaitKey(NULL);

printf("开始分割图像.....\n");

while

(1)

{

Img=cvQueryFrame(capture);

backgroundDiff(Img,Imask);

cvShowImage("原图",Img);

cvShowImage("检测图",Imask);

if(27==cvWaitKey(100))

break;

}

cvDestroyAllWindows();

//释放内存

DeallocateImages();

cvReleaseCapture(&capture);

return0;

 

}

//初始化函数:

voidAllocateImages(IplImage*I)//传入原图的大小,根据这个大小初始化。

{

CvSizesz=cvGetSize(I);

IavgF=cvCreateImage(sz,IPL_DEPTH_32F,3);

IdiffF=cvCreateImage(sz,IPL_DEPTH_32F,3);

IprevF=cvCreateImage(sz,IPL_DEPTH_32F,3);

IhiF=cvCreateImage(sz,IPL_DEPTH_32F,3);

IlowF=cvCreateImage(sz,IPL_DEPTH_32F,3);

Ilow1=cvCreateImage(sz,IPL_DEPTH_32F,1);

Ilow2=cvCreateImage(sz,IPL_DEPTH_32F,1);

Ilow3=cvCreateImage(sz,IPL_DEPTH_32F,1);

Ihi1=cvCreateImage(sz,IPL_DEPTH_32F,1);

Ihi2=cvCreateImage(sz,IPL_DEPTH_32F,1);

Ihi3=cvCreateImage(sz,IPL_DEPTH_32F,1);

cvZero(IavgF);//cvZero的作用是把矩阵里的值都置为零,初始化的作用。

cvZero(IdiffF);

cvZero(IprevF);

cvZero(IhiF);

cvZero(IlowF);

Icount=0.00001;

Iscratch=cvCreateImage(sz,IPL_DEPTH_32F,3);

Iscratch2=cvCreateImage(sz,IPL_DEPTH_32F,3);

Igray1=cvCreateImage(sz,IPL_DEPTH_32F,1);

Igray2=cvCreateImage(sz,IPL_DEPTH_32F,1);

Igray3=cvCreateImage(sz,IPL_DEPTH_32F,1);

Imaskt=cvCreateImage(sz,IPL_DEPTH_8U,1);

Imask=cvCreateImage(sz,IPL_DEPTH_8U,1);

cvZero(Iscratch);

cvZero(Iscratch2);

cvZero(Imask);

cvZero(Imaskt);

}

//循环统计背景模型

voidaccumulateBackground(IplImage*I)

{

staticintfirst=1;

cvCvtScale(I,Iscratch,1,0);//数组线性转化函数,四个参数分别为:

转换前数组、转换后数组、转换比例因子、比例缩放后加到结果数组上的数。

if(!

first)

{

cvAcc(Iscratch,IavgF);//将帧叠加到累加器中三个参数:

第一个是输入图像,第二个是图像的累积,第三个是可选择的运算。

cvAbsDiff(Iscratch,IprevF,Iscratch2);//计算两个数组差的绝对值的函数,差的绝对值的结果为第三个参数。

这里表示计算当前图像和上一个图像的差值。

cvAcc(Iscratch2,IdiffF);//IdiffF是相邻两幅图像差值的绝对值的累积

Icount+=1.0;

}

first=0;

cvCopy(Iscratch,IprevF);//把第一个数组copy给第二个数组

}

 

voidcreateModelsfromStats()

{

//通过除以输入图像积累的数目计算平均原始图像和绝对差分图像

cvConvertScale(IavgF,IavgF,(double)(1.0/Icount));//通过多幅图像的积累除以图像的个数得到平均原始图像。

cvConvertScale(IdiffF,IdiffF,(double)(1.0/Icount));//相邻图像差值绝对值的平均值

 

//makesurediffisslwayssomething

cvAddS(IdiffF,cvScalar(1.0,1.0,1.0),IdiffF);//确保平均差分图像的值最小是1,第一个数组和第二个标量元素级相加得到第三个元素。

setHighThreshold(7.0);//当计算前景和背景阈值以及避免前景阈值和背景阈值相等而出现的退化情况时,我们要缩放这个因素

setLowThreshold(6.0);

}

voidsetHighThreshold(floatscale)

{

cvConvertScale(IdiffF,Iscratch,scale);

cvAdd(Iscratch,IavgF,IhiF);

cvSplit(IhiF,Ihi1,Ihi2,Ihi3,0);//把第一个多通道图像分为多个单通道图像

}

voidsetLowThreshold(floatscale)

{

cvConvertScale(IdiffF,Iscratch,scale);

cvSub(IavgF,Iscratch,IlowF);//矩阵减法运算

cvSplit(IlowF,Ilow1,Ilow2,Ilow3,0);

}

voidbackgroundDiff(IplImage*I,IplImage*Imask)

{

cvConvertScale(I,Iscratch,1,0);

cvSplit(Iscratch,Igray1,Igray2,Igray3,0);

cvInRange(Igray1,Ilow1,Ihi1,Imask);//cvInRange的作用是判断第一个数组每个参数是不是在第二三个数组对应参数之间,把结果放入第四个参数的相对位置。

cvInRange(Igray2,Ilow2,Ihi2,Imaskt);

cvOr(Imask,Imaskt,Imask);//求第一二个数组的并集,结果放入第三个数组中

cvInRange(Igray3,Ilow3,Ihi3,Imask);

cvOr(Imask,Imaskt,Imask);

cvSubRS(Imask,cvScalar(255),Imask);

}

voidDeallocateImages()

{

cvReleaseImage(&IavgF);

cvReleaseImage(&IdiffF);

cvReleaseImage(&IprevF);

cvReleaseImage(&IhiF);

cvReleaseImage(&IlowF);

cvReleaseImage(&Ilow1);

cvReleaseImage(&Ilow2);

cvReleaseImage(&Ilow3);

cvReleaseImage(&Ihi1);

cvReleaseImage(&Ihi2);

cvReleaseImage(&Ihi3);

cvReleaseImage(&Iscratch);

cvReleaseImage(&Iscratch2);

cvReleaseImage(&Igray1);

cvReleaseImage(&Igray2);

cvReleaseImage(&Igray3);

cvReleaseImage(&Imaskt);

cvReleaseImage(&Imask);

}

均值漂移算法:

寻找区域中数据点的重心,或者加权平均值,将寻找中心移动到,数据点的重心处,并重复这个过程直到寻找区域重心收敛到一个稳定点。

求图像像素点的分布直方图:

#include"cv.h"

#include

#include

#include

usingnamespacecv;

usingnamespacestd;

classHistogram1D{

private:

inthistSize[1];//项的数量

floathranges[2];//像素的最大和最小值

constfloat*ranges[1];//像素

intchannels[1];//通道数,这里表示只有一个通道。

public:

Histogram1D(){

histSize[0]=256;

hranges[0]=0.0;

hranges[1]=255.0;

ranges[0]=hranges;

channels[0]=0;//考察零号通道

}

MatNDgetHistogram(Mat&image){

MatNDhist;

calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);

returnhist;

}

MatgetHistogramImage(Mat&image){

MatNDhist=getHistogram(image);

doublemaxVal=0;

doubleminVal=0;

minMaxLoc(hist,&minVal,&maxVal,0,0);//查找数组中最大值和最小值的函数,第一个参数表示输入数组,第二三个表示最小大值的指针,第四五个表示最小大值的位置指针。

//得到显示直方图的图像:

MathistImg(histSize[0],histSize[0],CV_8U,Scalar(255));

//设置最高点为nbins的90%

inthpt=static_cast(0.9*histSize[0]);

//依次划线

for(inth=0;h

floatbinVal=hist.at(h);

intintensity=static_cast(binVal*hpt/maxVal);

line(histImg,Point(h,histSize[0]),Point(h,histSize[0]-intensity),cvScalar(0,0,0));

}

returnhistImg;

}

};

voidmain(){

MatImage=imread("beauty.jpg");

Histogram1Dh;

MatNDhisto=h.getHistogram(Image);

intsum=0;

for(inti=0;i<256;i++){

cout<<"像素值为"<(i)<

sum=sum+histo.at(i);

}

cout<<"汇总:

"<

imshow("describe",h.getHistogramImage(Image));

waitKey(0);

}

运动物体检测:

背景实时变化,把当前图像乘以一个均值加入背景中,主要是下面的cvRunningAvg函数

/**************************************************

*背景建模,运动物体检测

**************************************************/

#include

#include

#include

#include

intmain(intargc,char**argv)

{

//声明IplImage指针

IplImage*pFrame=NULL;

IplImage*pFrImg=NULL;

IplImage*pBkImg=NULL;

CvMat*pFrameMat=NULL;

CvMat*pFrMat=NULL;

CvMat*pBkMat=NULL;

CvCapture*pCapture=NUL

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 机械仪表

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1