资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

OpenCV实现平均背景法

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

创新互联建站"三网合一"的企业建站思路。企业可建设拥有电脑版、微信版、手机版的企业网站。实现跨屏营销,产品发布一步更新,电脑网络+移动网络一网打尽,满足企业的营销需求!创新互联建站具备承接各种类型的成都网站建设、成都网站制作项目的能力。经过10年的努力的开拓,为不同行业的企事业单位提供了优质的服务,并获得了客户的一致好评。

平均背景法使用四个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, *Iscratch3;
 
//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);
 Iscratch3 = 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(Iscratch3);
}
 
//学习累积背景图像和每一帧图像差值的绝对值
// 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, Iscratch3);
 cvAcc(Iscratch3,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);
 cvReleaseImage(&Ilow1);
 cvReleaseImage(&Ilow2);
 cvReleaseImage(&Ilow3);
 cvReleaseImage(&Iscratch);
 cvReleaseImage(&Iscratch3);
 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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。


网页名称:OpenCV实现平均背景法
当前URL:http://cdkjz.cn/article/pgcshg.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220