📄 w4运动检测06-09-18.cpp
字号:
/************************************************** * 背景建模,运动物体检测 * **************************************************/#ifdef _CH_
#pragma package <opencv>
#endif
#ifndef _EiC
#include <stdio.h>#include <cv.h>#include <cxcore.h>#include <highgui.h>
#include <ctype.h>
#endif
#define FALSE 0
#define TRUE 1
#define EPS 1e-6
#define SQUARE(x) ((x) * (x))
#define ZERO(x) (fabs((x)) < EPS ? TRUE : FALSE)
#define LearnFrame 20
#define NUM 20
#define PARAMETER 2
IplConvKernel* element = 0;
const int element_shape = CV_SHAPE_RECT;
//形态学滤波函数操作
void Opening(IplImage* src, IplImage* image, IplImage* dest, int pos);
void Closing(IplImage* src, IplImage* image, IplImage* dest, int pos);
void Erosion(IplImage* src, IplImage* dest, int pos);
void Dilation(IplImage* src, IplImage* dest, int pos);
CvMemStorage* storage = 0; // temporary storage
int i;
CvPoint pt;
CvPoint pre_pt;
int N;
int main( ){ //声明当前帧IplImage指针 IplImage* pFrame = NULL; IplImage* pFrImg = NULL; IplImage* pBkImg = NULL;
IplImage* pCurImg = NULL;
IplImage* pTempImg = NULL; CvMat* MinValue = NULL;
CvMat* MaxValue = NULL;
CvMat* MaxFrameDiff = NULL;
CvMat* MeanValue = NULL;
CvMat* SigmaValue = NULL;
CvMat* MedianFrameDiff = NULL;
//运动参数矩阵
CvMat* gS = NULL;
CvMat* mS = NULL;
CvMat* hS = NULL;
IplImage** buf = NULL;
CvCapture* Capture = NULL; int nFrmNum = 0;
int thresh=0;
int sum=0;
int alert=0;
int i,j,w,x;
double temp[NUM];
double temp1[NUM];
double tmp;
int countframe=0;
#define MinValueMat(ROW,COL) ((uchar *)(MinValue->data.ptr + MinValue->step *(ROW)))[(COL)]
#define MaxValueMat(ROW,COL) ((uchar *)(MaxValue->data.ptr + MaxValue->step *(ROW)))[(COL)]
#define MaxFrameDiffMat(ROW,COL) ((uchar *)(MaxFrameDiff->data.ptr + MaxFrameDiff->step *(ROW)))[(COL)]
#define MedianFrameDiffMat(ROW,COL) ((uchar *)(MedianFrameDiff->data.ptr + MedianFrameDiff->step *(ROW)))[(COL)]
#define MeanValueMat(ROW,COL) ((float *)(MeanValue->data.fl + MeanValue->step/sizeof(float) *(ROW)))[(COL)]
#define SigmaValueMat(ROW,COL) ((float *)(SigmaValue->data.fl + SigmaValue->step/sizeof(float) *(ROW)))[(COL)]
#define BufMAT(NUMBER,ROW,COL) ((uchar*)(buf[(NUMBER)]->imageData + buf[(NUMBER)]->widthStep*(ROW)))[(COL)]
#define gSMat(ROW,COL) ((uchar *)(gS->data.ptr + gS->step *(ROW)))[(COL)]
#define mSMat(ROW,COL) ((uchar *)(mS->data.ptr + mS->step *(ROW)))[(COL)]
#define hSMat(ROW,COL) ((uchar *)(hS->data.ptr + hS->step *(ROW)))[(COL)]
#define BkImg(ROW,COL) ((uchar*)(pBkImg->imageData + pBkImg->widthStep*(ROW)))[(COL)]
#define FrImg(ROW,COL) ((uchar*)(pFrImg->imageData + pFrImg->widthStep*(ROW)))[(COL)]
#define TempImg(ROW,COL) ((uchar*)(pTempImg->imageData + pTempImg->widthStep*(ROW)))[(COL)]
#define CurImg(ROW,COL) ((uchar*)(pCurImg->imageData + pCurImg->widthStep*(ROW)))[(COL)]
//创建窗口 cvNamedWindow("video", 2); cvNamedWindow("back",2); cvNamedWindow("fore",2);
cvNamedWindow("temp",2);
// Capture =cvCaptureFromCAM(0);
Capture = cvCaptureFromFile("I:\\经典运动检测\\99.avi"); pFrame = cvQueryFrame( Capture );
//使窗口有序排列
cvMoveWindow("video", 30, 20);
cvMoveWindow("back", 50+2*pFrame->width, 20);
cvMoveWindow("fore", 30, 110+2*pFrame->height);
cvMoveWindow("temp", 50+2*pFrame->width, 110+2*pFrame->height);
//申请内存,并初始化
//背景、前景、临时图像
pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
pTempImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
pCurImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
//均值矩阵,最大值矩阵、最小值矩阵、最大相邻帧差
MinValue = cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
MaxValue = cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
MaxFrameDiff = cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
MedianFrameDiff= cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
gS = cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
mS = cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
hS = cvCreateMat(pFrame->height, pFrame->width, CV_8UC1);
cvZero(MinValue);cvZero(MaxValue);cvZero(MaxFrameDiff);
cvZero(gS);cvZero(mS);cvZero(hS);
//均值矩阵、方差矩阵
MeanValue = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
SigmaValue = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
cvZero(MeanValue);cvZero(SigmaValue);
//初始化时使用的NUM帧数据
buf = (IplImage**)malloc(NUM*sizeof(buf[0]));
memset( buf, 0, NUM * sizeof(buf[0]) );
for( i = 0; i < NUM; i++ )
{
buf[i] = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
cvZero( buf[i] );
}
storage = cvCreateMemStorage(0);
//逐帧读取视频 while(pFrame = cvQueryFrame( Capture )) { if(countframe<0)
{
countframe++;
continue;
} if(nFrmNum<LearnFrame)//背景模型初始化 {
//转化成单通道图像再处理 cvCvtColor(pFrame, pTempImg, CV_BGR2GRAY);
//中值滤波
cvSmooth( pTempImg, pCurImg, CV_MEDIAN , 3, 0, 0 );//CV_GAUSSIAN or CV_MEDIAN
cvFlip( pCurImg, pCurImg, 0 );
cvCopy( pCurImg, buf[nFrmNum], 0 );
nFrmNum++;
printf("frame= %d \n",nFrmNum);
continue; }
else if (nFrmNum==LearnFrame) //建立 W4 背景模型
{
nFrmNum++;
cvCvtColor(pFrame, pTempImg, CV_BGR2GRAY);
cvFlip( pTempImg, pTempImg, 0 );
//中值滤波
cvSmooth( pTempImg, pCurImg, CV_MEDIAN , 3, 0, 0 );//CV_GAUSSIAN or CV_MEDIAN
for (w = 1; w < NUM; w++)
cvCopy( buf[w], buf[w-1], 0 );
cvCopy( pCurImg, buf[NUM-1], 0 );
for ( i = 0; i < pFrame->height; i++)
{
for ( j = 0; j < pFrame->width; j++)
{
double temp_deviation[NUM];
temp[0] = BufMAT(0,i,j);
//临时存储
for ( w = 1; w < NUM; w++)
{
temp[w] = BufMAT(w,i,j);
temp_deviation[w-1] = abs(temp[w]-temp[w-1]); //临时离差
}
//排序取其数据的中值
for (w = 0; w < NUM; w++)
{
for ( x = 0; x < NUM - 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 < NUM-1; w++)
{
for ( x = 0; x < NUM - 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;
}
}
}
//得到中值数,以及中值离差,利用中值滤波,剔除非背景点
tmp = temp[NUM / 2];
int tindex = 0;
for (w = 0; w < NUM; w++)
{
if (abs(BufMAT(w,i,j) - tmp) < 4 * temp_deviation[(NUM-1)/2])
{
temp[tindex] = BufMAT(w,i,j);
tindex++;
}
}
//重新计算前景参数
double max_deviation = 0.0; //最大离差
double median_deviation= 0.0; //中值离差
double mean = 0.0; //均值
mean=temp[0];
for ( w = 1; w < tindex-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 < tindex-1; w++)
{
tmp = (temp[w] - mean);
variance += (tmp * tmp - variance) / (w + 1);
}
variance=sqrt(1.0 * variance * (tindex-1)/ (tindex-2) );
//背景排序求中值,最大值最小值等
for (w = 0; w < tindex; w++)
{
for (int x = 0; x < tindex - 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 < tindex-1; w++)
{
for ( x = 0; x < tindex - 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= (tindex-1)/2;
if(temp_deviation[(tindex-2)/2]<PARAMETER)
{
temp_deviation[(tindex-2)/2]=PARAMETER;
}
if (variance<PARAMETER)
{
variance=PARAMETER;
}
if (max_deviation<PARAMETER)
{
max_deviation=PARAMETER;
}
//背景参数
MinValueMat(i,j) = temp[0]; //最小值
MaxValueMat(i,j) = temp[tindex - 1]; //最大值
MaxFrameDiffMat(i,j) = max_deviation; //相邻帧最大差
MedianFrameDiffMat(i,j) = temp_deviation[(tindex-2)/2]; //相邻帧差的中值
SigmaValueMat(i,j) = variance; //标准方差
MeanValueMat(i,j) = mean; //均值
BkImg(i,j)=temp[ttindex]; //背景值
}
}
printf("initialization ofbackground model is completed!\n");
} else //背景减并进行背景更新
{
countframe++;
printf(" The current frame is %d ; \n",countframe);
//提取前景目标
cvCvtColor(pFrame, pTempImg, CV_BGR2GRAY);
cvFlip( pTempImg, pTempImg, 0 );
//中值滤波
cvSmooth( pTempImg, pCurImg, CV_MEDIAN , 3, 0, 0 );//CV_GAUSSIAN or CV_MEDIAN
/*
cvConvert(Cur_Frame, pFrameMat);
cvAbsDiff( pFrameMat, MinValue, pSubMat1 );
cvCmp( pSubMat1, MaxFrameDiff, pSubMat1, CV_CMP_LE );
cvAbsDiff( pFrameMat, MaxValue, pSubMat2 );
cvCmp( pSubMat2, MaxFrameDiff, pSubMat2, CV_CMP_LE );
//确定前景背景
cvOr( pSubMat1, pSubMat2, pFrMat, 0 );
cvAnd( pFrameMat, pFrMat, pFrImg, pFrMat );
cvConvert(pBkMat, pBkImg);
cvConvert(pFrMat, pTempImg);
cvShowImage("background", pBkImg); //显示背景图像
cvShowImage("foreground", pFrImg); //显示前景图像
cvShowImage("temp", pTempImg); //显示二值前景图像
*/ //%%%%%%%%%%%%%%%%%%%%%%%
/* 计算相关的运动参数矩阵
//a detection support map(gS) matrix
cvAddS( gS, cvScalarAll( 1 ) , gS, pBkMat );
//a motion support map(mS) matrix
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -