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

来源:互联网 发布:云计算现状 编辑:程序博客网 时间:2024/04/30 13:24
#include "opencv2/objdetect/objdetect.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/video/tracking.hpp"#include <iostream>#include <stdio.h>using namespace std;using namespace cv;/** 函数声明 */void detectAndDisplay(Mat& frame);/** 全局变量 */string face_cascade_name = "haarcascade_frontalface_alt.xml";//string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";CascadeClassifier face_cascade;//CascadeClassifier eyes_cascade;string window_name = "Face detection with Kalman";RNG rng(12345);struct face{    Point leftTop=0;    int width=0;    int height=0;};face preFace;/** @主函数 */int main(){    //kalman参数设置        int stateNum = 4;    int measureNum = 2;    KalmanFilter KF(stateNum, measureNum, 0);    //Mat processNoise(stateNum, 1, CV_32F);    Mat measurement = Mat::zeros(measureNum, 1, CV_32F);    KF.transitionMatrix = *(Mat_<float>(stateNum, stateNum) << 1, 0, 1, 0,//A 状态转移矩阵        0, 1, 0, 1,        0, 0, 1, 0,        0, 0, 0, 1);    //这里没有设置控制矩阵B,默认为零    setIdentity(KF.measurementMatrix);//H=[1,0,0,0;0,1,0,0] 测量矩阵    setIdentity(KF.processNoiseCov, Scalar::all(1e-5));//Q高斯白噪声,单位阵    setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));//R高斯白噪声,单位阵    setIdentity(KF.errorCovPost, Scalar::all(1));//P后验误差估计协方差矩阵,初始化为单位阵    randn(KF.statePost, Scalar::all(0), Scalar::all(0.1));//初始化状态为随机值    //读入视频        if (!face_cascade.load(face_cascade_name)){ cout << "--(!)Error loading\n" << endl; };    Mat frame, frame2;    VideoCapture cap;    cap.open("me1.mp4");    //cap.open("me2.mp4");    //cap.open("me3.mp4");    while (true){        for (int i = 0; i < 1; i++){            cap >> frame;        }        if (!frame.empty())        {            resize(frame, frame2, Size(), 0.5, 0.5, INTER_LINEAR);            Mat prediction = KF.predict();            Point predict_pt = Point((int)prediction.at<float>(0), (int)prediction.at<float>(1));            detectAndDisplay(frame2);            measurement.at<float>(0) = (float)preFace.leftTop.x;            measurement.at<float>(1) = (float)preFace.leftTop.y;            KF.correct(measurement);            //画卡尔曼的效果            Point center(predict_pt.x + preFace.width*0.5, predict_pt.y + preFace.height*0.5);            ellipse(frame2, center, Size(preFace.width*0.3, preFace.height*0.3), 0, 0, 360, Scalar(0, 0, 255), 4, 8, 0);            circle(frame2, center, 3, Scalar(0, 0, 255), -1);            imshow(window_name, frame2);            waitKey(1);        }        else        {            printf(" --(!) No frame -- Break!");            break;         }    }    return 0;}/** @函数 detectAndDisplay */void detectAndDisplay(Mat& frame){    std::vector<Rect> faces;    Mat frame_gray;    int Max_area=0;    int faceID=0;    cvtColor(frame, frame_gray, CV_BGR2GRAY);    equalizeHist(frame_gray, frame_gray);    //-- 多尺寸检测人脸    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));    //找出最大的脸,可以去除不是脸的误检,这些误检一般比较小    for (int i = 0; i < faces.size(); i++)    {        if ((int)(faces[i].width*faces[i].height) > Max_area){            Max_area =(int) faces[i].width*faces[i].height;            faceID=i;        }        }    if (faces.size() > 0)//必须是检测到脸才绘制当前人脸圆圈,并且只能绘制最大的脸    {        preFace.leftTop.x = faces[faceID].x;        preFace.leftTop.y = faces[faceID].y;        preFace.height = faces[faceID].height;        preFace.width = faces[faceID].width;        Point center(faces[faceID].x + faces[faceID].width*0.5, faces[faceID].y + faces[faceID].height*0.5);        ellipse(frame, center, Size(faces[faceID].width*0.5, faces[faceID].height*0.5), 0, 0, 360, Scalar(0, 255, 0), 1, 8, 0);        circle(frame, center, 3, Scalar(0, 255,0), -1);    }    else{//没检测到人脸绘制之前的人脸        Point center(preFace.leftTop.x + preFace.width*0.5, preFace.leftTop.y + preFace.height*0.5);        ellipse(frame, center, Size(preFace.width*0.5, preFace.height*0.5), 0, 0, 360, Scalar(0, 255, 0), 1, 8, 0);        circle(frame, center, 3, Scalar(0, 255, 0), -1);    }        }

0 0
原创粉丝点击