首页 > 代码库 > 帧差法侦测运动目标

帧差法侦测运动目标

  1 #include<iostream>
  2 #include<opencv2\core\core.hpp>
  3 #include<opencv2\highgui\highgui.hpp>
  4 #include<opencv2\imgproc\imgproc.hpp>
  5 using namespace std;
  6 using namespace cv;
  7 
  8 const unsigned char FORE_GROUD = 255;
  9 int thresh = 30;
 10 int maxArea = 100;
 11 int times = 100;
 12 
 13 Point getCenterPoint(Rect rect)
 14 {
 15     Point cpt;
 16     cpt.x = rect.x + cvRound(rect.width/2.0);
 17     cpt.y = rect.y + cvRound(rect.height/2.0);
 18     return cpt;
 19 }
 20 
 21 int main(int argc,char*argv[])
 22 {
 23 
 24     VideoCapture video(0);
 25 
 26     //判断如果video是否可以打开
 27     if(!video.isOpened())
 28         return -1;
 29     cout<<"Opened"<<endl;
 30 
 31     //用于保存当前帧的图片
 32     Mat currentBGRFrame;
 33 
 34     //用来保存上一帧和当前帧的灰度图片
 35     Mat previousSecondGrayFrame;
 36     Mat previousFirstGrayFrame;
 37     Mat currentGaryFrame;
 38 
 39     //保存两次的帧差
 40     Mat previousFrameDifference;//previousFrameFirst - previousFrameSecond的差分
 41     Mat currentFrameDifference;//currentFrame - previousFrameFirst;
 42 
 43     //用来保存帧差的绝对值
 44     Mat absFrameDifferece;
 45 
 46     //用来显示前景
 47     Mat previousSegmentation;
 48     Mat currentSegmentation;
 49     Mat segmentation;
 50 
 51 
 52     //显示前景
 53     namedWindow("segmentation",1);
 54     createTrackbar("阈值:","segmentation",&thresh,FORE_GROUD,NULL);
 55     createTrackbar("面积:","segmentation",&maxArea,FORE_GROUD,NULL);
 56 
 57     //帧数
 58     int numberFrame = 0;
 59 
 60     //形态学处理用到的算子
 61     Mat morphologyKernel = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
 62 
 63     for(;;)
 64     {
 65         //读取当前帧
 66         video >> currentBGRFrame;
 67 
 68         //判断当前帧是否存在
 69         if(!currentBGRFrame.data)
 70             continue;
 71 
 72         numberFrame++;
 73         //颜色空间的转换
 74         cvtColor(currentBGRFrame,currentGaryFrame,COLOR_BGR2GRAY);
 75 
 76         if( numberFrame == 1)
 77         {
 78             //保存当前帧的灰度图
 79             previousSecondGrayFrame = currentGaryFrame.clone();
 80 
 81             //显示视频
 82            imshow("video",currentBGRFrame);
 83             continue;
 84         }
 85         else if( numberFrame == 2)
 86         {
 87             //保存当前帧的灰度图
 88             previousFirstGrayFrame = currentGaryFrame.clone();
 89 
 90             //previousFirst - previousSecond
 91             subtract(previousFirstGrayFrame,previousSecondGrayFrame,previousFrameDifference,Mat(),CV_16SC1);
 92 
 93             //取绝对值
 94             absFrameDifferece = abs(previousFrameDifference);
 95 
 96             //位深的改变
 97             absFrameDifferece.convertTo(absFrameDifferece,CV_8UC1,1,0);
 98 
 99             //阈值处理
100             threshold(absFrameDifferece,previousSegmentation,double(thresh),double(FORE_GROUD),THRESH_BINARY);
101 
102             //显示视频
103            imshow("video",currentBGRFrame);
104             continue;
105         }
106 
107         else
108         {
109             //src1-src2
110             //subtract(currentGaryFrame,previousFirstGrayFrame,currentFrameDifference,Mat(),CV_16SC1);
111 
112             //取绝对值
113             //absFrameDifferece = abs(currentFrameDifference);
114             absdiff(currentGaryFrame,previousFirstGrayFrame,absFrameDifferece);
115 
116             //位深的改变
117             absFrameDifferece.convertTo(absFrameDifferece,CV_8UC1,1,0);
118 
119             //阈值处理
120             threshold(absFrameDifferece,currentSegmentation,double(thresh),double(FORE_GROUD),THRESH_BINARY);
121 
122             //与运算
123             bitwise_and(previousSegmentation,currentSegmentation,segmentation);
124 
125             //中值滤波
126             medianBlur(segmentation,segmentation,3);
127 
128             //形态学处理(开闭运算)
129             //morphologyEx(segmentation,segmentation,MORPH_OPEN,morphologyKernel,Point(-1,-1),1,BORDER_REPLICATE);
130             morphologyEx(segmentation,segmentation,MORPH_CLOSE,morphologyKernel,Point(-1,-1),2,BORDER_REPLICATE);
131 
132 
133             //找边界
134             vector< vector<Point> > contours;
135             vector<Vec4i> hierarchy;
136             //复制segmentation
137             Mat tempSegmentation = segmentation.clone();
138             findContours( segmentation, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );//CV_RETR_TREE
139             vector< vector<Point> > contours_poly( contours.size() );
140 
141             /*存储运动物体*/
142             Rect rect = Rect(0,0,0,0);
143             vector<Rect> boundRect;
144             boundRect.clear();
145 
146             //画出运动物体
147             for(unsigned int index = 0;index < contours.size() ;index++)
148             {
149                 approxPolyDP( Mat(contours[index]), contours_poly[index], 3, true );
150                 Rect tmprect =  boundingRect( Mat(contours_poly[index]) );
151                 //cout<<getCenterPoint(rect)<<endl;
152                 int currentArea = tmprect.area();
153                 if( currentArea >= rect.area() && currentArea >= maxArea*times )
154                     rect = tmprect;
155             }
156             rectangle(currentBGRFrame,rect,Scalar(0,255,255),2);
157 
158             //显示视频
159             imshow("video",currentBGRFrame);
160 
161            //前景检测
162             imshow("segmentation",segmentation);
163 
164             //保存当前帧的灰度图
165             previousFirstGrayFrame = currentGaryFrame.clone();
166 
167             //保存当前的前景检测
168             previousSegmentation = currentSegmentation.clone();
169         }
170 
171         if(waitKey(33) == q)
172             break;
173 
174     }
175     return 0;
176 }

 

帧差法侦测运动目标