#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; }