• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

OpenCV实现平均背景法

c语言 搞代码 4年前 (2022-01-06) 36次浏览 已收录 0个评论

这篇文章主要为大家详细介绍了OpenCV实现平均背景法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

平均背景法的基本思想是计算每个像素的平均值和标准差作为它的背景模型。

平均背景法使用四个OpenCV函数:

  • cvAcc(),累积图像;
  • cvAbsDiff() ,计算一定时间内的每帧图像只差;
  • cvInRange(), 将图像分割成前景区域和背景区域;
  • cvOr(), 将不同的彩色通道图像中合成为一个掩膜图像

代码:

 /* 平均背景法 */ #include "highgui.h" #include "cv.h" #include #include //为不同的临时指针图像和统计属性创建指针 //Float, 3-channel images IplImage* IavgF, * IdiffF, * IprevF, * IhiF, *IlowF; IplImage* Iscratch, *Iscratch2; //Float 1-channel images IplImage* Igray1, * Igray2, * Igray3; IplImage* Ilow1, * Ilow2, * Ilow3; IplImage* Ihi1, *Ihi2, * Ihi3; //Byte, 1-channel image IplImage* Imask; IplImage* Imaskt; //Counts number of images learned for averaging later. float Icount; // 创建一个函数来给需要的所有临时图像分配内存 //为了方便,我们传递一幅图像(来自视频)作为大小参考来分配临时图像 void AllocateImages(IplImage* I) { CvSize sz = 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(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); Imask = cvCreateImage(sz, IPL_DEPTH_8U, 1); Imaskt = cvCreateImage(sz, IPL_DEPTH_8U,1); cvZero(Iscratch); cvZero(Iscratch2); } //学习累积背景图像和每一帧图像差值的绝对值 // Learn the background statistics for one more frame // I is a color sample of the background, 3-channel, 8u void accumulateBackground(IplImage *I) { static int first = 1; cvCvtScale(I, Iscratch, 1, 0); if(!first) { cvAcc(Iscratch,IavgF); cvAbsDiff(Iscratch, IprevF, Iscratch2); cvAcc(Iscratch2,IdiffF); Icount += 1.0; } first = 0; cvCopy(Iscratch, IprevF); } //setHighThreshold和setLowThreshold都是基于每一帧图像平均绝对差设置阈值的有效函数 void setHighThreshold(float scale) { cvConvertScale(IdiffF, Iscratch, scale); cvAdd(Iscratch, IavgF, IhiF); cvSplit(IhiF, Ihi1, Ihi2, Ihi3, 0); } void setLowThreshold(float scale) { cvConvertScale(IdiffF, Iscratch, scale); cvSub(IavgF, Iscratch, IlowF); cvSplit(IlowF, Ilow1, Ilow2, Ilow3, 0); } //当积累了足够多的帧图像之后,就将其转化为一个背景的统计模型 //计算每一个像素的均值和方差观测 void createModelsfromStats() { cvConvertScale(IavgF, IavgF, (double)(1.0/Icount)); cvConvertScale(IdiffF, IdiffF, (double)(1.0/Icount)); //Make sure diff is always something cvAddS(IdiffF, cvScalar(1.0, 1.0, 1.0), IdiffF); setHighThreshold(7.0); setLowThreshold(6.0); } //有了背景模型,同时给出了高,低阈值,就能用它将图像分割为前景和背景 // Create a binary: 0,255 mask where 255 means foregrond pixel // I Input image, 3-channel, 8u //Imask void backgroundDiff(IplImage* I) { cvCvtScale(I, Iscratch, 1, 0); cvSplit(Iscratch, Igray1, Igray2, Igray3, 0); //Channel 1 cvInRange(Igray1, Ilow1, Ihi1, Imask); //Channel 2 cvInRange(Igray2, Ilow2, Ihi2, Imaskt); cvOr(Imask, Imaskt, Imask); //Channel 3 cvInRange(Igray3, Ilow3, Ihi3, Imaskt); cvOr(Imask, Imaskt, Imask); //Finally, invert the result cvSubRS(Imask, cvScalar(255), Imask); } //完成背景建模后, 释放内存 void DeallocateImage() { cvReleaseImage(&IavgF); cvReleaseImage(&IdiffF); cvReleaseImage(&IprevF); cvReleaseImage(&IhiF); cvReleaseImage(&IlowF); cvReleaseIm<em style="color:transparent">来源gao.dai.ma.com搞@代*码网</em>age(&Ilow1); cvReleaseImage(&Ilow2); cvReleaseImage(&Ilow3); cvReleaseImage(&Iscratch); cvReleaseImage(&Iscratch2); cvReleaseImage(&Igray1); cvReleaseImage(&Igray2); cvReleaseImage(&Igray3); cvReleaseImage(&Imaskt); } //主函数 int main() { CvCapture* capture = cvCreateFileCapture("tree.avi"); if(!capture) { return -1; } cvNamedWindow("win1"); cvNamedWindow("win2"); IplImage* rawImage = cvQueryFrame(capture); cvShowImage("win1", rawImage); AllocateImages(rawImage); int i = 0; while(1) { if(i <= 30) { accumulateBackground(rawImage); if(i == 30) { createModelsfromStats(); } } else { backgroundDiff(rawImage); } cvShowImage("win2", Imask); if(cvWaitKey(33) == 27) { break; } if(!(rawImage = cvQueryFrame(capture))) { break; } cvShowImage("win1", rawImage); if(i == 56 || i == 63) cvWaitKey(); i = i+1; } DeallocateImage(); return 0; }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持gaodaima搞代码网

以上就是OpenCV实现平均背景法的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:OpenCV实现平均背景法
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址