背景建模练习练习.docx
- 文档编号:24444426
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:21
- 大小:2.35MB
背景建模练习练习.docx
《背景建模练习练习.docx》由会员分享,可在线阅读,更多相关《背景建模练习练习.docx(21页珍藏版)》请在冰豆网上搜索。
背景建模练习练习
二帧差法:
#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 gray_diff.at elsegray_diff.at 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 gray_diff1.at elsegray_diff1.at if(abs(gray_diff2.at gray_diff2.at elsegray_diff2.at } } 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 //依次划线 for(inth=0;h floatbinVal=hist.at intintensity=static_cast 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 } 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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 背景 建模 练习