#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移动平均法背景建模
最新推荐文章于 2022-04-30 08:00:00 发布