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

原创 2015年11月21日 15:58:22
#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);
    }
    
    
}

卡尔曼滤波之目标跟踪

本文目录: 1.关于卡尔曼滤波理论学习 2.卡尔曼滤波的两个简单使用示例 3. 卡尔曼滤波二维平面目标跟踪中的应用1.关于卡尔曼滤波理论学习之前的博文有关于卡尔曼滤波的资料,通俗易懂。这里总结一...
  • NNNNNNNNNNNNY
  • NNNNNNNNNNNNY
  • 2017年01月01日 10:10
  • 6566

卡尔曼滤波器跟踪

1. 什么是卡尔曼滤波器 (What is the Kalman Filter?) 在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”。跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡...
  • lien0906
  • lien0906
  • 2015年12月31日 14:27
  • 2971

跟踪算法(二)Kalman filter跟踪

COPY FROM:http://www.cnblogs.com/feisky/archive/2009/11/09/1599247.html . 什么是卡尔曼滤波器 (What is the Kal...
  • tracyliang223
  • tracyliang223
  • 2014年12月05日 18:47
  • 3422

matlab实现的人体跟踪(kalman滤波)

  • 2016年11月07日 00:28
  • 4.81MB
  • 下载

使用MATLAB机器视觉工具箱实现人脸的检测和跟踪

跟图像处理、机器人视觉相关的MATLAB工具箱有: Image Processing Toolbox (图像处理工具箱) Computer Vision System Toolbox (计算机...
  • qq_25022433
  • qq_25022433
  • 2015年04月28日 10:27
  • 2475

【安卓随笔】使用OpenCV进行人脸跟踪和自动拍照

众所周知,其实在安卓原生的方法里,已经具备谷歌的人脸检测算法,只需要传入一张图片,即可获取其中人脸的个数以及两眼之间的距离等信息,如果这些谷歌的算法真的非常强大的话,也就没有必须写这篇博文了,用过的同...
  • vicemiami
  • vicemiami
  • 2017年01月10日 15:15
  • 4314

OpenCV目标跟踪(五)-kalman滤波器

在实际的运动跟踪中,由于环境因素或者别的原因总会有一些噪声的存在,这样的跟踪效果就会变差,人们想到尽可能多的去利用测量结果来估计运动。这样,任务就可以分为两个阶段:第一阶段,即预测阶段,用过去得到的信...
  • w12345_ww
  • w12345_ww
  • 2015年04月13日 20:06
  • 2104

opencv--读取摄像头识别人脸并跟踪

VS上的程序 #include "stdafx.h" #include "cv.h" #include "highgui.h" #include "windows.h" #include ...
  • imxiangzi
  • imxiangzi
  • 2016年04月28日 22:37
  • 4972

OpenCV与Compressive Tracking实现人脸的实时检测与跟踪

最近一直在关注压缩传感方面的东西,正好看到一篇新论文《Real-Time Compressive Tracking》。作者将压缩感知与图像跟踪结合起来,实现了有效的降维,最后只用一个简单的朴素贝叶斯分...
  • yiwei_david
  • yiwei_david
  • 2015年07月14日 15:46
  • 3599

opencv人脸检测和跟踪

一、我的分类训练器的xml文件路径如下: D://opencv//sources//data//haarcascades//haarcascade_frontalface_alt.xml 每个人的安...
  • qq_29540745
  • qq_29540745
  • 2016年07月18日 11:14
  • 999
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:卡尔曼滤波+opencv 实现人脸跟踪 小demo
举报原因:
原因补充:

(最多只允许输入30个字)