OpenCV移动平均法背景建模

#ifndef MOVINGAVER_H
#define MOVINGAVER_H

#include "cvInclude.h"

class CMovingAver
{
public:
   CMovingAver();

    doubleB;
    doublek;
    doublea;
    IplImage*m_pFrameTemp;
    IplImage*m_foreground;
    IplImage*m_background;

    voidProcess(IplImage* frame );
    voidReleaseMemory();
    voidAllotMemory(IplImage* img);
    voidInitProcess();

    virtual~CMovingAver();

protected:
    intmyOtsu(const IplImage *frame);
};

#endif // MOVINGAVER_H


#include "MovingAver.h"

CMovingAver::CMovingAver()
{
}

CMovingAver::~CMovingAver()
{
   ReleaseMemory();
}

voidCMovingAver::InitProcess()    //初始化参数
{
    B =1.0;
    a =1.0;
}

void CMovingAver::AllotMemory(IplImage* img)
{
    m_pFrameTemp= cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );
    m_background= cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );
    m_foreground= cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
}

void CMovingAver::ReleaseMemory()
{
   cvReleaseImage( &m_pFrameTemp );
   cvReleaseImage( &m_background );
   cvReleaseImage( &m_foreground );
}

void CMovingAver::Process( IplImage* frame)
{
    B = a*B +1;
    k =1.0/B;

   
   //计算两组数的加权和
   cvAddWeighted(frame, 1, m_background, -1, 0, m_pFrameTemp);
   cvAddWeighted(m_background, 1, m_pFrameTemp, k, 0,m_background);
    //voidcvAbsDiff(const CvArr* src1, const CvArr* src2, CvArr* dst);
   cvAbsDiff(frame, m_background, m_pFrameTemp);//它可以把两幅图的差的绝对值输出到另一幅图上面来
    //voidcvCvtColor( const CvArr* src, CvArr* dst, int code );
   cvCvtColor(m_pFrameTemp, m_foreground,CV_BGR2GRAY);   //颜色空间的转换

 //   doublethreshold = myOtsu(m_foreground);
  //当视频中没有运动目标时, 自动阈值获取会错检
  //因此阈值选取有运动目标时,myOtsu获得的阈值40.0(约)
   cvThreshold(m_foreground,m_foreground, 40.0, 255.0, CV_THRESH_BINARY);
 //   cvThreshold(m_foreground, m_foreground, threshold, 255.0,CV_THRESH_BINARY);
 //   qDebug()<<"Threshold:"<<threshold<<endl;
    //voidcvThreshold( const CvArr*  src,CvArr* dst,   double  threshold, double max_value,   int threshold_type );
   //对单通道数组应用固定阈值操作

   //cvConvert(m_pFrameTemp, m_foreground);
}

//一种阈值方法otsu
int CMovingAver::myOtsu(const IplImage *frame)
{
    #defineGrayScale256      //frame灰度级
    int width =frame->width;
    int height =frame->height;
    intpixelCount[GrayScale] = {0};
    floatpixelPro[GrayScale] = {0};
    int i,j,pixelSum = width * height, threshold = 0;
    uchar* data= (uchar*)frame->imageData;

   //统计每个灰度级中像素的个数
    for(i = 0;i< height; i++)
    {
       for(j=0 ; j
       {
           pixelCount[ (int)data[ i*width + j ] ]++;
       }
    }

   //计算每个灰度级像素数目占整幅图像的比例
    for(i=0; i< GrayScale; i++)
    {
       pixelPro[i] = (float)pixelCount[i] / pixelSum;
    }

   //遍历灰度级[0,255], 寻找合适的threshold
    floatw0,w1,u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax = 0;
    for(i=0;i< GrayScale ; i++)
    {
       w0 = w1 = u0tmp =u1tmp = u0 =u1 =deltaTmp =0;
       for(j=0; j< GrayScale; j++)
       {
           if(j <=i)     //背景部分
           {
               w0 += pixelPro[j];
               u0tmp += j * pixelPro[j];
           }
           else       //前景部分
           {
               w1 += pixelPro[j];
               u1tmp += j * pixelPro[j];
           }
       }
       u0 = u0tmp / w0;
       u1 = u1tmp / w1;
       deltaTmp = (float) ( w0 * w1 * pow ( (u0 -u1 ), 2) );
       if(deltaTmp > deltaMax)
       {
           deltaMax = deltaTmp;
           threshold = i;
       }
    }
    returnthreshold;
}


你可能感兴趣的:(opencv,背景建模)