可以从静态场景中检测出移动的物体,并对目标进行标记和计数。本文的主要工作包括:在图像预处理阶段,本文采用HSV色彩空间 减轻了目标阴影对目标提取的影响,采用中值滤波器去掉了椒盐噪声,采用图像二值化使图像变的简单,采用图像学去噪中的腐蚀和膨胀分别提取消除图像噪声和填 充图像空洞。在动态目标识别的阶段,采用三帧差分法提取出动态的目标,并用更新运动历史图像的方法来减轻重影现象。最后通过在原图像帧中画矩形框的方式来 标记动态目标的位置,并显示当前运动目标的个数,以及当前帧率、系统运行时间、当前帧数等系统信息。
gra.h
- #ifndef GRA_H_INCLUDED
- #define GRA_H_INCLUDED
-
- #endif // GRA2_H_INCLUDED
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <math.h>
- #include <float.h>
- #include <limits.h>
- #include <time.h>
- #include <ctype.h>
- #include <opencv2/opencv.hpp>
-
- using namespace std;
- using namespace cv;
-
-
-
- void bgrToGray(IplImage *src,IplImage *dst);
- IplImage* doPyrDown( IplImage* src );
- IplImage* doPyrUp( IplImage* src );
- void graAbsDiff(IplImage* src1,IplImage* src2,IplImage* dst);
- void graZero(IplImage* src);
- void graAdd(IplImage* src1,IplImage* src2,IplImage* dst);
-
-
-
-
- void bgrToGray(IplImage *src,IplImage *dst)
- {
-
-
- if(src==NULL)
- {
- printf("bgrToGray传入的图像为空");
- return;
- }
- int i,j,k,avg;
- int height,width,step,channels;
- uchar *data,*dstdata;
- height=src->height;
- width=src->width;
- step=src->widthStep;
- channels=src->nChannels;
- data=(uchar*)src->imageData;
- dstdata=(uchar*)dst->imageData;
-
-
- for(i=0; i<height; i++)
- {
- for(j=0; j<width; j++)
- {
-
-
- avg=0.072169*data[ i * step+ j * channels + 1]
- +0.715160*data[ i *step+ j * channels + 2]
- +0.212671*data[ i *step+ j *channels + 3];
-
-
-
-
- dstdata[i*dst->widthStep+j]=avg;
-
- }
- }
- }
-
-
- IplImage* doPyrDown( IplImage* src )
- {
- IplImage* result = cvCreateImage( cvSize( src -> width/2, src -> height/2 )
- , src -> depth, src -> nChannels );
-
- cvPyrDown( src, result, CV_GAUSSIAN_5x5 );
-
- return result;
- }
- IplImage* doPyrUp( IplImage* src )
- {
- IplImage* result = cvCreateImage( cvSize( src -> width*2, src -> height*2 )
- , src -> depth, src -> nChannels );
- cvPyrUp( src, result, CV_GAUSSIAN_5x5 );
-
- return result;
- }
-
-
-
- void graAbsDiff(IplImage* src1,IplImage* src2,IplImage* dst)
- {
- if(src1==NULL||src2==NULL)
- {
- printf("graAbsDiff传入的图像为空");
- return;
- }
- int i,j,k;
- int height,width,step,channels;
- uchar *dataSrc1,*dataSrc2,*dataDst;
- height=src1->height;
- width=src1->width;
- step=src1->widthStep;
- channels=src1->nChannels;
- dataSrc1=(uchar*)src1->imageData;
- dataSrc2=(uchar*)src2->imageData;
- dataDst=(uchar*)dst->imageData;
-
-
-
- for(i=0; i<height; i++)
- {
- for(j=0; j<width; j++)
- {
- for(k=0; k<channels; k++)
- {
- dataDst[i*step+j*channels+k]=abs(dataSrc1[i*step+j*channels+k]
- -dataSrc2[i*step+j*channels+k]);
- }
- }
- }
-
- }
-
- void graZero(IplImage* src)
- {
- if(src==NULL)
- {
- printf("graZero传入的图像为空");
- return;
- }
- int i,j,k;
- int height,width,step,channels;
- uchar *data,*dstdata;
- height=src->height;
- width=src->width;
- step=src->widthStep;
- channels=src->nChannels;
- data=(uchar*)src->imageData;
-
-
-
- for(i=0; i<height; i++)
- {
- for(j=0; j<width; j++)
- {
- for(k=0; k<channels; k++)
- {
- data[i*step+j*channels+k]=0;
- }
- }
- }
- }
-
-
- void graAdd(IplImage* src1,IplImage* src2,IplImage* dst)
- {
- if(src1==NULL||src2==NULL)
- {
- printf("graAbsDiff传入的图像为空");
- return;
- }
- int i,j,k;
- int height,width,step,channels;
- uchar *dataSrc1,*dataSrc2,*dataDst;
- height=src1->height;
- width=src1->width;
- step=src1->widthStep;
- channels=src1->nChannels;
- dataSrc1=(uchar*)src1->imageData;
- dataSrc2=(uchar*)src2->imageData;
- dataDst=(uchar*)dst->imageData;
-
-
-
- for(i=0; i<height; i++)
- {
- for(j=0; j<width; j++)
- {
- for(k=0; k<channels; k++)
- {
- dataDst[i*step+j*channels+k]=abs(dataSrc1[i*step+j*channels+k]
- +dataSrc2[i*step+j*channels+k]);
- }
- }
- }
-
- }
-
-
- void graThreshold(IplImage* src1,IplImage* dst,double threshold,double max_value)
- {
- if(src1==NULL)
- {
- printf("\ngraThreshold没有传入图像");
- return ;
- }
- int i,j,k;
- int height,width,step,channels;
- uchar *dataSrc1,*dataDst;
- height=src1->height;
- width=src1->width;
- step=src1->widthStep;
- channels=src1->nChannels;
- if(channels!=1)
- {
- printf("将要把彩色图像二值化");
- bgrToGray(src1,dst);
- }
- dataSrc1=(uchar*)src1->imageData;
- dataDst=(uchar*)dst->imageData;
-
-
-
- for(i=0; i<height; i++)
- {
- for(j=0; j<width; j++)
- {
-
- if(dataSrc1[i*step+j]>threshold)
- {
- dataDst[i*step+j]=max_value;
- }
- else
- {
- dataDst[i*step+j]=0;
- }
- }
- }
- }
-
-
- bool graFilterMid(IplImage* &image,int k)
- {
- if(image==NULL)
- {
- printf("\nFilterMid没有传入图像");
- return false;
- }
- uchar *ImagePix=(uchar *)image->imageData;
- int m=(k-1)/2;
- for(int x=m; x<image->height-m; ++x)
- {
- for(int y=m; y<image->width-m; ++y)
- {
- uchar PixArray[100];
- int t=0;
- for(int i=-m; i<m+1; ++i)
- {
- for(int j=-m; j<m+1; j++)
- {
- PixArray[t++]=((uchar *)image->imageData)[(x+i)*image->widthStep+y+j];
- }
- }
-
-
-
- for(int i=0; i<k*k-1; ++i)
- for(int j=0; j<k*k-i-1; ++j)
- {
- if(PixArray[j]>PixArray[j+1])
- {
- uchar k=PixArray[j];
- PixArray[j]=PixArray[j+1];
- PixArray[j+1]=k;
- }
- }
- ImagePix[x*image->widthStep+y]=PixArray[(k*k-1)/2];
- }
- }
- return true;
- }
- void saturate_SV(IplImage* image)
- {
- for(int y = 0; y < image -> height; ++y)
- {
-
- uchar* ptr=(uchar*)(
- image -> imageData + y * image->widthStep);
-
- for(int x = 0; x < image -> width; ++x)
- {
-
-
- ptr[3 * x + 2] =255;
- }
- }
- }
main.cpp
- #include "gra.h"
-
- using namespace cv;
- using namespace std;
-
-
- const double MHI_DURATION = 0.5;
- const double MAX_TIME_DELTA = 0.5;
- const double MIN_TIME_DELTA = 0.05;
- const int N = 3;
- int num=0;
-
-
- const int CONTOUR_MAX_AERA = 1600;
-
-
- IplImage **buf = 0;
- int last = 0;
-
-
- IplImage *mhi = 0;
-
- int filter = CV_GAUSSIAN_5x5;
-
- CvPoint pt[4];
-
-
- int main(int argc, char** argv)
- {
- printf("程序开始,按ESC可以退出程序");
- IplImage *pFrame = NULL;
- IplImage *pFrame1 = NULL;
-
- int inMonitor=0;
- int num=0;
- float fps;
- char str[5];
- double t = 0;
- int countsInMonitor=0;
- double runT=clock();
- char runTime[10];
- double runT2;
- char* str3;
- int seconds=0;
- IplImage* motion = 0;
- CvCapture* pCapture = 0;
-
- int width,height;
-
- if(argc>2)
- {
- fprintf(stderr, "Usage: bkgrd [video_file_name]\n");
- return -1;
- }
-
- if (argc ==1)
- {
- if( !(pCapture = cvCaptureFromCAM(-1)))
- {
- fprintf(stderr, "Can not open camera.\n");
- return -2;
- }
- }
-
-
- if(argc == 2)
- if( !(pCapture = cvCaptureFromFile(argv[1])))
- {
- fprintf(stderr, "Can not open video file %s\n", argv[1]);
- return -2;
- }
-
-
- if( pCapture )
- {
-
-
- pFrame=cvQueryFrame( pCapture );
- IplImage *silh1,*silh2,*silh;
- pFrame1 = cvCreateImage( cvSize(pFrame->width,pFrame->height), 8, 3 );
- width=pFrame->width;
- height=pFrame->height;
-
-
- CvPoint pt1_Rect;
- CvPoint pt2_Rect;
- CvPoint pt3_Rect;
- CvPoint pt4_Rect;
- pt1_Rect.x=(1.0/5)*width;
- pt1_Rect.y=0;
- pt2_Rect.x=(1.0/5)*width;
- pt2_Rect.y=pFrame->height;
- pt3_Rect.x=(4.0/5)*width;
- pt3_Rect.y=0;
- pt4_Rect.x=(4.0/5)*width;
- pt4_Rect.y=pFrame->height;
- int thickness=1;
- int line_type=8;
- CvScalar color=CV_RGB(100,100,100);
-
- CvRect ROI_rect;
- ROI_rect.x=pt1_Rect.x;
- ROI_rect.y=pt1_Rect.y;
- ROI_rect.width=pt3_Rect.x-pt1_Rect.x;
- ROI_rect.height=pt2_Rect.y-pt1_Rect.y;
-
- char warnings[20];
-
-
-
- silh1 = cvCreateImage( cvSize(pFrame->width,pFrame->height), 8, 1 );
- silh2 = cvCreateImage( cvSize(pFrame->width,pFrame->height), 8, 1 );
- silh = cvCreateImage( cvSize(pFrame->width,pFrame->height), 8, 1 );
- cvNamedWindow("Motion",CV_WINDOW_AUTOSIZE);
- cvMoveWindow("Motion",100,100);
- for(;;)
- {
- t = (double)getTickCount();
- num++;
-
- if( !cvGrabFrame( pCapture ))
- break;
- pFrame = cvRetrieveFrame( pCapture );
-
- if( pFrame )
- {
- if( !motion )
- {
- motion = cvCreateImage( cvSize(pFrame->width,pFrame->height), 8, 1 );
- cvZero( motion );
- motion->origin = pFrame->origin;
- }
- }
-
-
-
-
- double timestamp = clock()/100.;
- CvSize size = cvSize(pFrame->width,pFrame->height);
- int i, j, idx1, idx2,idx3;
-
- 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;
-
-
- 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 );
- printf("sd");
- cvZero( buf[i] );
- }
- cvReleaseImage( &mhi );
- mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 );
- cvZero( mhi );
- }
-
- cvCvtColor(pFrame,pFrame1,CV_BGR2HSV);
- saturate_SV(pFrame1);
- cvCvtColor(pFrame1,pFrame1,CV_HSV2BGR);
-
- bgrToGray( pFrame1, buf[last]);
- idx1 = last;
- idx2 = (last + 1) % N;
- idx3=(idx2+1)%N;
- last = idx3;
- cvShowImage("asda",pFrame1);
-
-
-
- graAbsDiff( buf[idx1], buf[idx2], silh1 );
- graAbsDiff( buf[idx2], buf[idx3], silh2 );
- graAdd(silh1,silh2,silh);
- cvShowImage("aaaa",silh);
-
- graThreshold( silh, silh, 50, 255);
-
-
- cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION );
-
-
-
- cvCvtScale( mhi, motion, 255./MHI_DURATION,
- (MHI_DURATION - timestamp)*255./MHI_DURATION );
-
-
-
- graFilterMid(motion,3);
-
-
-
- pyr=doPyrDown(motion);
- cvDilate( pyr, pyr, 0, 1 );
-
- motion=doPyrUp(pyr);
-
-
- cvSetImageROI(motion,ROI_rect);
-
-
-
-
- stor = cvCreateMemStorage(0);
- cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
-
-
- cvFindContours( motion, stor, &cont, sizeof(CvContour),
- CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
-
-
-
-
-
-
-
-
-
-
-
-
- cvResetImageROI(motion);
- cvSetImageROI(pFrame,ROI_rect);
-
- countsInMonitor=0;
- for(; cont; cont = cont->h_next)
- {
- CvRect r = ((CvContour*)cont)->rect;
- if(r.height * r.width > CONTOUR_MAX_AERA)
- {
- cvRectangle( pFrame, cvPoint(r.x,r.y),
- cvPoint(r.x + r.width, r.y + r.height),
- CV_RGB(255,0,0), 1, CV_AA,0);
- inMonitor=1;
- countsInMonitor++;
- }
-
- }
-
-
- cvReleaseMemStorage(&stor);
- cvReleaseImage( &pyr );
-
- cvResetImageROI(pFrame);
-
- CvFont font;
- cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX,0.5, 0.5, 0, 1, 1);
-
-
-
- t = ((double)cvGetTickCount() - t) / getTickFrequency();
- fps = 1.00 / t;
-
- sprintf(str,"fps: %.1f",fps);
-
-
- cvPutText(pFrame, str , cvPoint(20,pFrame->height-20), &font, CV_RGB(255,0,0));
-
-
- runT2=clock();
- seconds=(int)runT2/1000;
- sprintf(runTime,"time: %ds",seconds);
- cvPutText(pFrame, runTime, cvPoint(100,pFrame->height-20), &font, CV_RGB(255,0,0));
-
- char texta[10];
-
- sprintf(texta,"%dth frame",num);
-
- cvPutText(pFrame, texta , cvPoint(200,pFrame->height-20), &font, CV_RGB(255,0,0));
-
-
- if(inMonitor==1)
- {
- sprintf(warnings,"%d in monitor area",countsInMonitor);
- cvPutText(pFrame, warnings , cvPoint(0.25*width,height-60), &font, CV_RGB(255,0,0));
- }
-
-
- cvLine( pFrame, pt1_Rect, pt2_Rect,color ,thickness, line_type, 0 );
- cvLine( pFrame, pt3_Rect, pt4_Rect,color ,thickness, line_type, 0 );
-
- cvShowImage( "Motion", pFrame );
- inMonitor=0;
- if( cvWaitKey(10) >= 0 )
- break;
- }
- cvReleaseCapture( &pCapture );
- cvDestroyWindow( "Motion" );
- printf("\n程序结束,一共运行了%d s",seconds);
- }
-
- return 0;
- }
(lawdong) |