📄 w4运动检测06-09-18.cpp
字号:
cvAbsDiff( Cur_Frame, Next_Frame, pSubMat1 );
cvCmp( pSubMat1, SigmaValue, pSubMat1, CV_CMP_GT );
cvAbsDiff( Pre_Frame, Cur_Frame, pSubMat2 );
cvCmp( pSubMat2, SigmaValue, pSubMat2, CV_CMP_GT );
cvAnd( pSubMat1, pSubMat2, pFrameMat, 0 );
cvAddS( mS, cvScalarAll( 1 ) , mS, pFrameMat );
*/
cvZero(pFrImg);
for (int i = 0; i < pFrame->height; i++)
{
for (int j = 0; j < pFrame->width; j++)
{
int tt=CurImg(i,j);
int cc=MinValueMat(i,j);
int mm=MedianFrameDiffMat(i,j);
if (abs(CurImg(i,j) - MinValueMat(i,j)) < 2*MedianFrameDiffMat(i,j) ||
abs(CurImg(i,j) - MaxValueMat(i,j)) < 2*MedianFrameDiffMat(i,j) )
// if (abs(Cur_Mat(i,j) - MinValueMat(i,j)) < 10 ||
// abs(Cur_Mat(i,j) - MaxValueMat(i,j)) < 10 )
{
TempImg(i,j)=0; //背景
}
else
{
TempImg(i,j)=255; //前景
FrImg(i,j)=CurImg(i,j);
}
}
}
//进行形态学滤波,去掉噪音
Opening(pBkImg, pBkImg, pBkImg, 1);
Closing(pBkImg, pBkImg, pBkImg, 1);
Opening(pFrImg, pFrImg, pFrImg, 1);
Closing(pFrImg, pFrImg, pFrImg, 1);
Opening(pTempImg, pTempImg, pTempImg, 1);
Closing(pTempImg, pTempImg, pTempImg, 1);
cvShowImage("video", pCurImg); //视频
cvShowImage("back", pBkImg); //背景图像
cvShowImage("fore", pFrImg); //仅有目标的图像
cvShowImage("temp", pTempImg); //二值化目标提取
for (w = 1; w < NUM; w++)
cvCopy( buf[w], buf[w-1], 0 );
cvCopy( pCurImg, buf[NUM-1], 0 );
//根据参数更新背景
cvZero(gS);cvZero(mS);cvZero(hS);
for ( i = 0; i < pFrame->height; i++)
{
for ( j = 0; j < pFrame->width; j++)
{
int countback=0;
int countfore=0;
for ( w = 0; w < NUM; w++)
{
// 判定为背景MedianFrameDiffMat(i,j)
if ((abs(BufMAT(w,i,j) - MinValueMat(i,j)) < 2*MedianFrameDiffMat(i,j)) ||
(abs(BufMAT(w,i,j) - MaxValueMat(i,j)) < 2*MedianFrameDiffMat(i,j)) )
{
gSMat(i,j) = gSMat(i,j)+1;
temp[countback] = BufMAT(w,i,j); //背景像素
countback++;
}
else
{
temp1[countfore] = BufMAT(w,i,j); //前景像素
countfore++;
}
}
for (w = 1; w < NUM - 2; w++)
{
if ((abs(BufMAT(w,i,j) - BufMAT(w-1,i,j)) > 2*SigmaValueMat(i,j)) &&
(abs(BufMAT(w,i,j) - BufMAT(w+1,i,j)) > 2*SigmaValueMat(i,j)))
{
mSMat(i,j) = mSMat(i,j)+1; //有运动加一
}
}
int cc=gSMat(i,j);
if (gSMat(i,j) > 0.8*NUM) //也就是这时候几乎都是背景像素
{
//用背景图像更新背景参数
double tmp;
for (w = 0; w < countback; w++)
{
for (int x = 0; x < countback - w - 1; x++)
{
if (temp[x] > temp[x+1])
{
tmp = temp[x];
temp[x] = temp[x + 1];
temp[x+1] = tmp;
}
}
}
int y = countback / 2;
tmp = temp[y];
double mean=temp[0];
double max_deviation=0;
double temp_deviation[NUM];
for ( w = 1; w < countback-1; w++)
{
tmp=temp[w]-temp[w-1];
if (max_deviation<tmp)
{
max_deviation=tmp;
}
temp_deviation[w] = abs( temp[w] - temp[w-1] );
mean += 1.0*( temp[w] - mean) / (w+1);
}
double variance=0.0; //标准方差
for (w = 0; w < countback-1; w++)
{
tmp = (temp[w] - mean);
variance += (tmp * tmp - variance) / (w + 1);
}
variance=sqrt(1.0 * variance * (countback-1)/ (countback-2) );
//背景排序求中值,最大值最小值等
for (w = 0; w < countback; w++)
{
for (int x = 0; x < countback - w - 1; x++)
{
if (temp[x] > temp[x + 1])
{
tmp = temp[x];
temp[x] = temp[x + 1];
temp[x + 1] = tmp;
}
}
}
//对背景离差进行排序,取其中值
for (w = 0; w < countback-1; w++)
{
for ( x = 0; x < countback - w - 2; x++)
{
if (temp_deviation[x] > temp_deviation[x + 1])
{
tmp = temp_deviation[x];
temp_deviation[x] = temp_deviation[x + 1];
temp_deviation[x + 1] = tmp;
}
}
}
int ttindex= (countback-1)/2;
if(temp_deviation[(countback-2)/2]<PARAMETER)
{
temp_deviation[(countback-2)/2]=PARAMETER;
}
if (variance<PARAMETER)
{
variance=PARAMETER;
}
if (max_deviation<PARAMETER)
{
max_deviation=PARAMETER;
}
//更新背景参数
MinValueMat(i,j) = temp[0]; //最小值
MaxValueMat(i,j) = temp[countback - 1]; //最大值
MaxFrameDiffMat(i,j) = max_deviation; //相邻帧最大差
MedianFrameDiffMat(i,j) = temp_deviation[(countback-2)/2]; //相邻帧差的中值
SigmaValueMat(i,j) = variance; //标准方差
MeanValueMat(i,j) = mean; //均值
BkImg(i,j)=temp[ttindex]; //背景值
}
else if(mSMat(i,j) < 0.1*NUM)
{
//用前景图像更新背景参数
double tmp;
for (w = 0; w < countfore; w++)
{
for (int x = 0; x < countfore - w - 1; x++)
{
if (temp1[x] > temp1[x+1])
{
tmp = temp1[x];
temp1[x] = temp1[x + 1];
temp1[x+1] = tmp;
}
}
}
int y = countfore / 2;
tmp = temp1[y];
double mean=temp1[0];
double max_deviation=0;
double temp_deviation[NUM];
for ( w = 1; w < countfore-1; w++)
{
tmp=temp1[w]-temp1[w-1];
if (max_deviation<tmp)
{
max_deviation=tmp;
}
temp_deviation[w] = abs( temp1[w] - temp1[w-1] );
mean += 1.0*( temp1[w] - mean) / (w+1);
}
double variance=0.0; //标准方差
for (w = 0; w < countfore-1; w++)
{
tmp = (temp1[w] - mean);
variance += (tmp * tmp - variance) / (w + 1);
}
variance=sqrt(1.0 * variance * (countfore-1)/ (countfore-2) );
//前景排序求中值,最大值最小值等
for (w = 0; w < countfore; w++)
{
for (int x = 0; x < countfore - w - 1; x++)
{
if (temp1[x] > temp1[x + 1])
{
tmp = temp1[x];
temp1[x] = temp1[x + 1];
temp1[x + 1] = tmp;
}
}
}
//对前景离差进行排序,取其中值
for (w = 0; w < countfore-1; w++)
{
for ( x = 0; x < countfore - w - 2; x++)
{
if (temp_deviation[x] > temp_deviation[x + 1])
{
tmp = temp_deviation[x];
temp_deviation[x] = temp_deviation[x + 1];
temp_deviation[x + 1] = tmp;
}
}
}
int ttindex= (countfore-1)/2;
if(temp_deviation[(countfore-2)/2]<PARAMETER)
{
temp_deviation[(countfore-2)/2]=PARAMETER;
}
if (variance<PARAMETER)
{
variance=PARAMETER;
}
if (max_deviation<PARAMETER)
{
max_deviation=PARAMETER;
}
//更新背景参数
MinValueMat(i,j) = temp[0]; //最小值
MaxValueMat(i,j) = temp[countfore - 1]; //最大值
MaxFrameDiffMat(i,j) = max_deviation; //相邻帧最大差
MedianFrameDiffMat(i,j) = temp_deviation[(countfore-2)/2]; //相邻帧差的中值
SigmaValueMat(i,j) = variance; //标准方差
MeanValueMat(i,j) = mean; //均值
BkImg(i,j)=temp[ttindex]; //背景值
}//else if
}//for
}//for
}//else
//如果有按键事件,则跳出循环 //此等待也为cvShowImage函数提供时间完成显示 //等待时间可以根据CPU速度调整 if( cvWaitKey(2) >= 0 ) break; }//while
for( i = 0; i < NUM; i++ )
{
cvReleaseImage( &buf[i] );
}
cvReleaseCapture( &Capture );
//销毁窗口 cvDestroyWindow("video"); cvDestroyWindow("back"); cvDestroyWindow("fore"); cvDestroyWindow("temp");
//释放图像和矩阵
cvReleaseImage(&pFrame);
cvReleaseImage(&pFrImg); cvReleaseImage(&pBkImg); cvReleaseImage(&pTempImg);
cvReleaseMat(&MinValue);
cvReleaseMat(&MaxValue);
cvReleaseMat(&MaxFrameDiff);
cvReleaseMat(&MeanValue);
cvReleaseMat(&SigmaValue);
cvReleaseMat(&MedianFrameDiff);
cvReleaseMat(&gS);
cvReleaseMat(&mS);
cvReleaseMat(&hS);
return 0;}
void Opening(IplImage* src, IplImage* image, IplImage* dest, int pos)
{
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, 0 );
cvErode(src,image,element,1);
cvDilate(image,dest,element,1);
cvReleaseStructuringElement(&element);
}
// implements closing
void Closing(IplImage* src, IplImage* image, IplImage* dest, int pos)
{
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, 0 );
cvDilate(src,image,element,1);
cvErode(image,dest,element,1);
cvReleaseStructuringElement(&element);
}
// implements erosion
void Erosion(IplImage* src, IplImage* dest, int pos)
{
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, 0 );
cvErode(src,dest,element,1);
cvReleaseStructuringElement(&element);
}
// implements dilation
void Dilation(IplImage* src, IplImage* dest, int pos)
{
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, 0 );
cvDilate(src,dest,element,1);
cvReleaseStructuringElement(&element);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -