您的位置:首页 > 运维架构

opencv质心以及轮廓的识别,视频的跟踪处理二值化

2017-09-10 13:44 555 查看
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <opencv2/core/core.hpp>  
  4. #include <opencv/cv.hpp>  
  5. #include <opencv2/highgui/highgui.hpp>  
  6. #include <time.h>  
  7. #include <math.h>  
  8. #include <ctype.h>  
  9. #include <stdio.h>  
  10. #include <string.h>  
  11. #include<windows.h>  
  12. #include <mmsystem.h>  
  13.   
  14. //跟踪参数  
  15. const double MHI_DURATION = 0.5;//最大跟踪时间  
  16. const double MAX_TIME_DELTA = 0.5;  
  17. const double MIN_TIME_DELTA = 0.05;  
  18. const int N = 3;  
  19. const int CONTOUR_MAX_AERA = 100;//矩形面积  
  20.   
  21. IplImage **buf = 0;  
  22. int last = 0;  
  23. int flag;  
  24. IplImage *mhi = 0; // MHI: motion history image  
  25. CvConnectedComp *cur_comp, min_comp;  
  26. CvConnectedComp comp;  
  27. CvMemStorage *storage;  
  28. CvPoint pt[4];  
  29. // img – 输入视频帧  
  30. // dst – 检测结果  
  31.   
  32.   
  33. using namespace cv;   
  34. using namespace std;   
  35. Mat src;   
  36. Mat src_gray;   
  37. int thresh = 30;   
  38. int max_thresh = 255;   
  39.   
  40.   
  41. void update_mhi(IplImage* img, IplImage* dst, int diff_threshold)  
  42. {  
  43.     double timestamp = clock() / 100.; //获取当前时间  
  44.     CvSize size = cvSize(img->width, img->height);  
  45.     int i, idx1, idx2;  
  46.     IplImage* silh;  
  47.     IplImage* pyr = cvCreateImage(cvSize((size.width & -2) / 2, (size.height & -2) / 2), 8, 1);  
  48.     CvMemStorage *stor;  
  49.     CvSeq *cont;  
  50.     if (!mhi || mhi->width != size.width || mhi->height != size.height)  
  51.     {  
  52.         if (buf == 0)  
  53.         {  
  54.             buf = (IplImage**)malloc(N*sizeof(buf[0]));//动态内存分配  
  55.             memset(buf, 0, N*sizeof(buf[0]));  
  56.         }  
  57.   
  58.         for (i = 0; i < N; i++)  
  59.         {  
  60.             cvReleaseImage(&buf[i]);  
  61.             buf[i] = cvCreateImage(size, IPL_DEPTH_8U, 1);  
  62.             cvZero(buf[i]);  
  63.         }  
  64.         cvReleaseImage(&mhi);  
  65.         mhi = cvCreateImage(size, IPL_DEPTH_32F, 1);  
  66.         cvZero(mhi);  
  67.     }  
  68.     cvCvtColor(img, buf[last], CV_BGR2GRAY); //rgb->gray  
  69.     idx1 = last;  
  70.     idx2 = (last + 1) % N;  
  71.     last = idx2;  
  72.     // 做帧差  
  73.     silh = buf[idx2];  
  74.     cvAbsDiff(buf[idx1], buf[idx2], silh); //两帧差异  
  75.     // 对差图像做二值化  
  76.     cvThreshold(silh, silh, 30, 255, CV_THRESH_BINARY); //src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;  
  77.   
  78.     cvUpdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); //更新像素点的运动历史  
  79.     cvCvtScale(mhi, dst, 255. / MHI_DURATION,  
  80.         (MHI_DURATION - timestamp)*255. / MHI_DURATION);//timestamp是时间戳;MHI_DURATION,获得的是当前时间  
  81.     cvCvtScale(mhi, dst, 255. / MHI_DURATION, 0);  
  82.   
  83.     // 中值滤波,消除小的噪声  
  84.     cvSmooth(dst, dst, CV_MEDIAN, 3, 0, 0, 0);  
  85.   
  86.     // 向下采样,去掉噪声  
  87.     cvPyrDown(dst, pyr, 7);  
  88.     cvDilate(pyr, pyr, 0, 1); // 做膨胀操作,消除目标的不连续空洞  
  89.     cvPyrUp(pyr, dst, 7);  
  90.     //  
  91.   
  92.     vector<vector<Point> > contours;      
  93.     vector<Vec4i> hierarchy;    
  94.     Mat canny_output(dst);   
  95.     // 找到所有轮廓  
  96.     findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );     
  97.     //计算轮廓矩       
  98.     vector<Moments> mu(contours.size() );       
  99.     for( int i = 0; i < contours.size(); i++ )     
  100.     {   
  101.         mu[i] = moments( contours[i], false );   
  102.     }     
  103.     //计算轮廓的质心     
  104.     vector<Point2f> mc( contours.size() );      
  105.     for( int i = 0; i < contours.size(); i++ )     
  106.     {   
  107.         mc[i] = Point2d( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );   
  108.     }     
  109.     // 直接使用CONTOUR中的矩形来画轮廓  
  110.     int order = 1;  
  111.     Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );         
  112.     for( int i = 0; i< contours.size(); i++ )      
  113.     {         
  114.         Scalar color = Scalar( 255, 0, 0);   
  115.         double area = mu[i].m00;//面积  
  116.         Rect ret1 = boundingRect(Mat(contours[i]));   //获取目标序列号放置位置  
  117.         if(area > 50)           //剔除小面积轮廓  
  118.         {  
  119.             drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );         
  120.             circle( drawing, mc[i], 5, Scalar( 0, 0, 255), -1, 8, 0 );                
  121.             rectangle(drawing, boundingRect(contours.at(i)), cvScalar(0,255,0));   
  122.               
  123.             char tam[100];   
  124.             sprintf(tam, "(%0.0f,%0.0f)",mc[i].x,mc[i].y);   
  125.             putText(drawing, tam, Point(mc[i].x, mc[i].y), FONT_HERSHEY_SIMPLEX, 0.4, cvScalar(255,0,255),1);  
  126.   
  127.             char tam1[100];   
  128.             sprintf(tam1, "%d",order++);   
  129.             putText(drawing, tam1, Point(ret1.x+ret1.width, ret1.y+ret1.height), FONT_HERSHEY_SIMPLEX, 0.4, cvScalar(0,255,255),1);  
  130.         }  
  131.   
  132.     }     
  133.     namedWindow( "Contours", CV_WINDOW_AUTOSIZE );    
  134.     imshow( "Contours", drawing );    
  135.     moveWindow("Contours",0,0);       
  136.     //waitKey(0);   
  137. }  
  138.   
  139. int main(int argc, char** argv)  
  140. {  
  141.     IplImage* motion = 0;  
  142.     CvCapture* capture = 0; //视频获取结构   
  143.       
  144.     while (1){  
  145.         //capture = cvCreateCameraCapture(0);//读摄像头视频  
  146.         capture = cvCreateFileCapture("C:\\Users\\Lijunliang\\Desktop\\0.5X.avi");    //读本地视频文件  
  147.         if (capture)  
  148.         {  
  149.             cvNamedWindow("Motion", 1);  
  150.             for (;;)  
  151.             {  
  152.                 SYSTEMTIME sys;//获取当前系统时间  
  153.                 GetLocalTime(&sys);  
  154.                 char* t_y = new char[128];  
  155.                 sprintf(t_y, ("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d"),  
  156.   
  157.                     sys.wYear, sys.wMonth, sys.wDay,  
  158.                     sys.wHour, sys.wMinute, sys.wSecond);  
  159.   
  160.                 CvFont font;  
  161.                 cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 0.5, 0.5, 0, 2, 8);  
  162.                 IplImage* image;  
  163.                 if (!cvGrabFrame(capture)) //从摄像头或者视频文件中抓取帧  
  164.                     break;  
  165.                 image = cvRetrieveFrame(capture); //取回由函数cvGrabFrame抓取的图像,返回由函数cvGrabFrame 抓取的图像的指针  
  166.                 if (image)  
  167.                 {  
  168.                     if (!motion)  
  169.                     {  
  170.                         motion = cvCreateImage(cvSize(image->width, image->height), 8, 1);  
  171.                         cvZero(motion);  
  172.                         motion->origin = image->origin; ///* 0 - 顶—左结构, 1 - 底—左结构 (Windows bitmaps 风格) */  
  173.                     }  
  174.                 }  
  175.                 update_mhi(image, motion, 6);  
  176.                 cvPutText(image, t_y, cvPoint(10, 25), &font, CV_RGB(255, 0, 0));  
  177.                 //cvShowImage("Motion", image);  
  178.                 if (cvWaitKey(10) >= 0)  
  179.                     break;  
  180.             }  
  181.             cvReleaseCapture(&capture);  
  182.             //cvDestroyWindow("Motion");  
  183.         }  
  184.     }  
  185.     return 0;  
  186. }  
  187. 主要理解Opencv运动跟踪,以及质点提取等方法探讨.

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: