📄 motiondetect.c
字号:
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
//#include <iostream.h>
//using namespace std;
double TrianglArea( int x1,int y1,int x2, int y2, int x3,int y3);
double SquArea(int x1,int y1,int x2, int y2, int x3,int y3,int x4,int y4);
void detect_face(IplImage* dst_img,int* count);
// various tracking parameters (in seconds)
const double MHI_DURATION = 0.5;
const double MAX_TIME_DELTA = 0.5;
const double MIN_TIME_DELTA = 0.05;
const int N = 3;
//
const int CONTOUR_MAX_AERA = 16;
// ring image buffer
IplImage **buf = 0;
int last = 0;
int nFrmnum=1;
// 临时图像参数
IplImage *mhi = 0; // MHI: 运动历史图像
CvFilter filter = CV_GAUSSIAN_5x5; //采用5x5的高斯滤波模板
CvConnectedComp *cur_comp, min_comp;
CvConnectedComp comp;
CvMemStorage *storage;
CvPoint pt[4];
//检测出的感兴趣区域参数
IplImage* dst_img1=0; //定义感兴趣区域图像指针
//CvMemStorage *stor1;
//CvSeq *cont1;
IplImage *sub_buy=0;
//IplImage* sub_buy=0;
// 参数:
// img – 输入视频帧
// dst – 检测结果
void update_mhi( IplImage* img, IplImage* dst, int diff_threshold )
{
double timestamp = clock()/100.; // 获取当前时间
CvSize size = cvSize(img->width,img->height); // 获取当前帧的大小
int i, j, idx1, idx2;
int danger_x[4]; //定义危险区域的边界顶点坐标
int danger_y[4];
int obj_x[100][4];
int obj_y[100][4];
int objArea=0;
int numobj=0; //定义检测到的目标数量
double ratio1,ratio2;
//int danger_x2;
//int danger_y2;
//int danger_x3;
//int danger_y3;
//int danger_x4;
//int danger_y4;
int danger_width=60; //定义危险区域的宽度
int danger_length=40; //定义危险区域的长度
double T_area1,T_area2,T_area3,T_area4,Sb; //定义计算不规则四边形面积的所需要的变量
double Sf[4];
double F_area1[100],F_area2[100],F_area3[100],F_area4[100],St; //定义计算目标四边形面积的所需要的变量
double Sp[100][4];
char strSaveImagename[40] = "C:\\motiondetect\\"; //!保存图片的目录名
char strTmp[20];
IplImage* silh; //定义帧间差分图像指针
IplImage* Bimg=0; //定义感兴趣区域图像指针
//uchar val;
//float temp;
IplImage* pyr = cvCreateImage( cvSize((size.width & -2)/2, (size.height & -2)/2), 8, 1 );
CvMemStorage *stor;
CvSeq *cont;// *result, *squares;
//CvSeqReader reader;
double Y;//,Cr,Cb;
if( !mhi || mhi->width != size.width || mhi->height != size.height )
{
if( buf == 0 )
{
buf = (IplImage**)malloc(N*sizeof(buf[0]));
memset( buf, 0, N*sizeof(buf[0]));
}
for( i = 0; i < N; i++ )
{
cvReleaseImage( &buf[i] );
buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
cvZero( buf[i] );
}
cvReleaseImage( &mhi );
mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 );
cvZero( mhi ); // clear MHI at the beginning
} // end of if(mhi)
cvCvtColor( img, buf[last], CV_BGR2GRAY ); // convert frame to grayscale
idx1 = last;
idx2 = (last + 1) % N; // index of (last - (N-1))th frame
last = idx2;
// 做帧差
silh = buf[idx2];
cvAbsDiff( buf[idx1], buf[idx2], silh ); // 帧间做差
// 对差图像做二值化
cvThreshold( silh, silh, 30, 255, CV_THRESH_BINARY ); // and threshold it
cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ); // update MHI
cvCvtScale( mhi, dst, 255./MHI_DURATION,(MHI_DURATION - timestamp)*255./MHI_DURATION );
cvCvtScale( mhi, dst, 255./MHI_DURATION, 0 );
// 中值滤波,消除小的噪声
cvSmooth( dst, dst, CV_MEDIAN, 3, 0, 0, 0 );
// 向下采样,去掉噪声
cvPyrDown( dst, pyr, 7 );
cvDilate( pyr, pyr, 0, 1 ); // 做膨胀操作,消除目标的不连续空洞
cvPyrUp( pyr, dst, 7 );
//===================================================================================
// 下面的程序段用来找到轮廓
// Create dynamic structure and sequence.
stor = cvCreateMemStorage(0);
cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
// 找到所有轮廓
numobj=cvFindContours( dst, stor, &cont, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
/*
for(;cont;cont = cont->h_next)
{
// Number point must be more than or equal to 6 (for cvFitEllipse_32f).
if( cont->total < 6 )
continue;
// Draw current contour.
cvDrawContours(img,cont,CV_RGB(255,0,0),CV_RGB(255,0,0),0,1, 8, cvPoint(0,0));
} // end of for-loop: "cont"
*/
//在图像窗口中绘制一个危险区域
//========================================================================
//不规则四边形顶点坐标的初始化
danger_x[0]=40;
danger_y[0]=10;
danger_x[3]=100;
danger_y[3]=5;
danger_x[1]=danger_x[0]+danger_width;
danger_y[1]=danger_y[0]+danger_length;
danger_x[2]=danger_x[3]+danger_width-20;
danger_y[2]=danger_y[3]+danger_length;
//======================================================================
// 直接使用CONTOUR中的矩形来画轮廓
for(;cont;cont = cont->h_next)
{
CvRect r = ((CvContour*)cont)->rect;
CvFont font;
obj_x[numobj][0]=r.x;
obj_y[numobj][0]=r.y;
obj_x[numobj][1]=r.x;
obj_y[numobj][1]=r.y;
obj_x[numobj][2]=r.x;
obj_y[numobj][2]=r.y;
obj_x[numobj][3]=r.x;
obj_y[numobj][3]=r.y;
for(j=0;j<4;j++)
{
T_area1=TrianglArea( danger_x[j],danger_y[j],r.x+r.width,r.y, r.x,r.y);
T_area2=TrianglArea( danger_x[j],danger_y[j],r.x+r.width,r.y,r.x,r.y+r.height);
T_area3=TrianglArea( danger_x[j],danger_y[j],r.x,r.y+r.height,r.x+r.width,r.y+r.height);
T_area4=TrianglArea( danger_x[j],danger_y[j],r.x+r.width,r.y+r.height, r.x,r.y);
Sf[j]=T_area1+T_area2+T_area3+T_area4;
}
Sb=SquArea( r.x,r.y,r.x+r.width,r.y,r.x,r.y+r.height,r.x+r.width,r.y+r.height); //计算划定的危险区域的面积
//cvSetImageROI(img, cvRect( r.x,r.y,r.x+r.width,r.y+r.height)); //设置检测出来的感兴趣的区域
//cvShowImage("img",img);
for(j=0;j<4;j++)
{
F_area1[numobj]=TrianglArea( danger_x[0],danger_y[0],danger_x[1],danger_y[1], obj_x[numobj][j],obj_y[numobj][j]);
F_area2[numobj]=TrianglArea( danger_x[2],danger_y[2],danger_x[1],danger_y[1], obj_x[numobj][j],obj_y[numobj][j]);
F_area3[numobj]=TrianglArea( danger_x[2],danger_y[2],danger_x[3],danger_y[3], obj_x[numobj][j],obj_y[numobj][j]);
F_area4[numobj]=TrianglArea( danger_x[3],danger_y[3],danger_x[1],danger_y[1], obj_x[numobj][j],obj_y[numobj][j]);
Sp[numobj][j]=T_area1+T_area2+T_area3+T_area4;
}
St=SquArea( danger_x[3],danger_y[3],danger_x[1],danger_y[1],danger_x[2],danger_y[2],danger_x[3],danger_y[3]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -