卡尔曼滤波+opencv 实现人脸跟踪

[cpp]  view plain  copy
  1. #include "opencv2/objdetect/objdetect.hpp"  
  2. #include "opencv2/highgui/highgui.hpp"  
  3. #include "opencv2/imgproc/imgproc.hpp"  
  4. #include "opencv2/video/tracking.hpp"  
  5. #include   
  6. #include   
  7.   
  8. using namespace std;  
  9. using namespace cv;  
  10.   
  11. /** 函数声明 */  
  12. void detectAndDisplay(Mat& frame);  
  13.   
  14. /** 全局变量 */  
  15. string face_cascade_name = "haarcascade_frontalface_alt.xml";  
  16. //string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";  
  17. CascadeClassifier face_cascade;  
  18. //CascadeClassifier eyes_cascade;  
  19. string window_name = "Face detection with Kalman";  
  20. RNG rng(12345);  
  21. struct face{  
  22.     Point leftTop=0;  
  23.     int width=0;  
  24.     int height=0;  
  25. };  
  26. face preFace;  
  27. /** @主函数 */  
  28. int main()  
  29. {  
  30.     //kalman参数设置  
  31.       
  32.     int stateNum = 4;  
  33.     int measureNum = 2;  
  34.     KalmanFilter KF(stateNum, measureNum, 0);  
  35.     //Mat processNoise(stateNum, 1, CV_32F);  
  36.     Mat measurement = Mat::zeros(measureNum, 1, CV_32F);  
  37.     KF.transitionMatrix = *(Mat_<float>(stateNum, stateNum) << 1, 0, 1, 0,//A 状态转移矩阵  
  38.         0, 1, 0, 1,  
  39.         0, 0, 1, 0,  
  40.         0, 0, 0, 1);  
  41.     //这里没有设置控制矩阵B,默认为零  
  42.     setIdentity(KF.measurementMatrix);//H=[1,0,0,0;0,1,0,0] 测量矩阵  
  43.     setIdentity(KF.processNoiseCov, Scalar::all(1e-5));//Q高斯白噪声,单位阵  
  44.     setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));//R高斯白噪声,单位阵  
  45.     setIdentity(KF.errorCovPost, Scalar::all(1));//P后验误差估计协方差矩阵,初始化为单位阵  
  46.     randn(KF.statePost, Scalar::all(0), Scalar::all(0.1));//初始化状态为随机值  
  47.   
  48.     //读入视频  
  49.       
  50.     if (!face_cascade.load(face_cascade_name)){ cout << "--(!)Error loading\n" << endl; };  
  51.     Mat frame, frame2;  
  52.     VideoCapture cap;  
  53.     cap.open("me1.mp4");  
  54.     //cap.open("me2.mp4");  
  55.     //cap.open("me3.mp4");  
  56.     while (true){  
  57.         for (int i = 0; i < 1; i++){  
  58.             cap >> frame;  
  59.         }  
  60.         if (!frame.empty())  
  61.         {  
  62.             resize(frame, frame2, Size(), 0.5, 0.5, INTER_LINEAR);  
  63.             Mat prediction = KF.predict();  
  64.             Point predict_pt = Point((int)prediction.at<float>(0), (int)prediction.at<float>(1));  
  65.             detectAndDisplay(frame2);  
  66.             measurement.at<float>(0) = (float)preFace.leftTop.x;  
  67.             measurement.at<float>(1) = (float)preFace.leftTop.y;  
  68.             KF.correct(measurement);  
  69.             //画卡尔曼的效果  
  70.             Point center(predict_pt.x + preFace.width*0.5, predict_pt.y + preFace.height*0.5);  
  71.             ellipse(frame2, center, Size(preFace.width*0.3, preFace.height*0.3), 0, 0, 360, Scalar(0, 0, 255), 4, 8, 0);  
  72.             circle(frame2, center, 3, Scalar(0, 0, 255), -1);  
  73.             imshow(window_name, frame2);  
  74.             waitKey(1);  
  75.         }  
  76.         else  
  77.         {  
  78.             printf(" --(!) No frame -- Break!");  
  79.             break;   
  80.         }  
  81.     }  
  82.     return 0;  
  83. }  
  84.   
  85. /** @函数 detectAndDisplay */  
  86. void detectAndDisplay(Mat& frame)  
  87. {  
  88.     std::vector faces;  
  89.     Mat frame_gray;  
  90.     int Max_area=0;  
  91.     int faceID=0;  
  92.   
  93.     cvtColor(frame, frame_gray, CV_BGR2GRAY);  
  94.     equalizeHist(frame_gray, frame_gray);  
  95.   
  96.     //-- 多尺寸检测人脸  
  97.     face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));  
  98.     //找出最大的脸,可以去除不是脸的误检,这些误检一般比较小  
  99.     for (int i = 0; i < faces.size(); i++)  
  100.     {  
  101.         if ((int)(faces[i].width*faces[i].height) > Max_area){  
  102.             Max_area =(int) faces[i].width*faces[i].height;  
  103.             faceID=i;  
  104.         }      
  105.     }  
  106.   
  107.     if (faces.size() > 0)//必须是检测到脸才绘制当前人脸圆圈,并且只能绘制最大的脸  
  108.     {  
  109.         preFace.leftTop.x = faces[faceID].x;  
  110.         preFace.leftTop.y = faces[faceID].y;  
  111.         preFace.height = faces[faceID].height;  
  112.         preFace.width = faces[faceID].width;  
  113.         Point center(faces[faceID].x + faces[faceID].width*0.5, faces[faceID].y + faces[faceID].height*0.5);  
  114.         ellipse(frame, center, Size(faces[faceID].width*0.5, faces[faceID].height*0.5), 0, 0, 360, Scalar(0, 255, 0), 1, 8, 0);  
  115.         circle(frame, center, 3, Scalar(0, 255,0), -1);  
  116.     }  
  117.     else{//没检测到人脸绘制之前的人脸  
  118.         Point center(preFace.leftTop.x + preFace.width*0.5, preFace.leftTop.y + preFace.height*0.5);  
  119.         ellipse(frame, center, Size(preFace.width*0.5, preFace.height*0.5), 0, 0, 360, Scalar(0, 255, 0), 1, 8, 0);  
  120.         circle(frame, center, 3, Scalar(0, 255, 0), -1);  
  121.     }  
  122.       
  123.       
  124. }  

你可能感兴趣的:(Demo)