OpenCV —— 跟踪与运动

理解物体运动主要包含两个部分:识别和建模

识别在视频流后续的帧中找出之前某帧镇南关的感兴趣物体

 

寻找角点

可跟踪的特征点都称为角点,从直观上讲,角点(而非边缘)是一类含有足够信息且能从当前帧和下一帧中都能提取出来的点

Harris 角点位于图像二阶导数的自相关矩阵有两个最大特征值的地方,这在本质上表示以此点为中心周围存在至少两个不同方向的纹理,正如实际的角点是由至少两个边缘相交于一点而产生

cvGoodFeaturesToTrack 采用Shi 和Tomasi提出的方法,先计算二阶导数,在计算特征值,返回满足易于跟踪的定义的一系列点(角点数组)

void cvGoodFeaturesToTrack(

const CvArrr* image,   8为或32位单通道图像

CvArr* eigImage,   每个元素包含了输入图像中对应点的最小特征值

CvArr* tempImage,   临时变量

CvPoint2D32f* corners,   输出

int * corner_count,   可以返回的最大角点数目

double quality_level,   认为是角点的可接受的最小特征值,不应超过1

double min_distance,  剔除距离较近的角点

const CvArr* mask = NULL,

int block_size=3,

int use_harris=0,

double k=0.4

);



亚像素级角点

cvFindCornerSubPix 用于发现亚像素精度的角点位置

实际计算亚像素级的角点位置时,解的是一个点积的表达式为0的方程组,其中每一个方程都是由q邻域的一个点产生。

搜索窗口的中心是整数坐标值的角点并从中心点在每个方向上扩展窗口尺寸指定的像素



不变特征

SIFT 在一点处检测主要梯度方向,根据这个方向记录局部梯度直方图结果,拥有旋转不变性

 



光流

可以将图像中的每个像素与速度关联,或者等价地,与表示像素在连续两帧之间的位移关联。这样得到的是稠密光流 —— 每个像素都与速度关联

稀疏光流的计算需要在被跟踪之前指定一组点 —— 角点

Lucas – Kanade 方法

LK算法只需要每个兴趣点周围小窗口的局部信息,所以它可以应用于稀疏内容。

不足 —— 较大的运动会将点移出这个小窗口

解决 —— 金字塔,跟踪图像金字塔允许小窗口捕获较大的运动

算法原理

1,亮度恒定 —— 场景中物体被跟踪部分的亮度不变

2,时间连续或者运动是“小运动” —— 运动相对于帧率是缓慢的

3,空间一致 —— 相邻的店保持相邻

 

在图像金字塔的最高层计算光流,用得到的运动估计结果作为下一层金字塔的起始点,重复这个过程直到到达金字塔的最底层,这样就将不满足运动假设的可能性降到最小。

cvCalcOpticalFlowLK —— 非金字塔的LK稠密光流算法

cvCalcOpticalFlowPyrLK —— 金字塔的LK代码

  图像金字塔的计算量较大,计算得到的图像对的后面一帧被作为下次计算的图像对的初始帧

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

const int MAX_CORNERS=500;

int main(int argc,char** argv)
{
    IplImage* imgA=cvLoadImage("image0.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    IplImage* imgB=cvLoadImage("image1.jpg",CV_LOAD_IMAGE_GRAYSCALE);

    CvSize img_sz=cvGetSize(imgA);
    int win_size=10;

    IplImage* imgC=cvLoadImage("",CV_LOAD_IMAGE_UNCHANGED);

    // get the features

    IplImage* eig_image=cvCreateImage(img_sz,IPL_DEPTH_32F,1);
    IplImage* tmp_image=cvCreateImage(img_sz,IPL_DEPTH_32F,1);

    int corner_count=MAX_CORNERS;
    CvPoint2D32f* cornersA=new CvPoint2D32f[MAX_CORNERS];

    cvGoodFeaturesToTrack(
        imgA,
        eig_image,
        tmp_image,
        cornersA,
        &corner_count,
        0.01,
        5.0,
        0,
        3,
        0,
        0.04);

    cvFindCornerSubPix(
        imgA,
        cornersA,
        corner_count,
        cvSize(win_size,win_size),
        cvSize(-1,-1),
        cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03);
        );

        // LK

        char features_found[MAX_CORNERS];
        float fearture_errors[MAX_CORNERS];

        CvSize pyr_sz=cvSize(imgA->width+8,imgB->height/3);

        IplImage* pyrA=cvCreateImage(pyr_sz,IPL_DEPTH_32F,1);
        IplImage* pyrB=cvCreateImage(pyr_sz,IPL_DEPTH_32F,1);

        CvPoint2D32f* cornersB=new CvPoint2D32f[MAX_CORNERS];

        cvCalcOpticalFlowPyrLK(
            imgA,
            imgB,
            pyrA,
            pyrB,
            cornersA,
            cornersB,
            corner_count,
            cvSize(win_size,win_size),
            5,
            features_found,
            fearture_errors,
            cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.3),
            0
            );

        // 结果显示
        for (int i=0;i<corner_count;i++)
        {
            if (features_found[i]==0||fearture_errors[i]>550)
            {
                printf("Error is %f\n",fearture_errors[i]);
                continue;
            }
            printf("Got it\n");
            CvPoint  p0=cvPoint(cvRound(cornersA[i].x),cvRound(cornersA[i].y));

            cvPoint p1=cvPoint(cvRound(cornersB[i].x),cvRound(cornersB[i].y));

            cvLine(imgC,p0,p1,CV_RGB(255,0,0),2);
        }

}

稠密跟踪方法

亮度恒定假设,速度的平滑约束 (通过对光流速度分量的二阶导数进行规则化获得)

与LK算法一样,HornSchunck方法也要通过迭代来解微分方程

cvCalcOpticalFlowHS



mean – shift

在一组数据的密度分布中寻找局部极值的稳定的方法

mean – shift 等价于先对连续分布用 mean-shift核进行卷积,然后再应用爬山算法

cvMeanShift

反向投影图 —— 概率密度图,用输入图像的某一位置上像素值对应直方图bin上的值来代替该像素值

 

Camshift 搜索窗口会自我调整尺寸

cvCamShift



运动模板

可应用于姿态识别

运动模板需要知道物体的轮廓

运动历史图像

OpenCV 中完成运动模板构建的函数是 cvUpdateMotionHistory

一旦运动模板记录了不同时间的物体轮廓,就可以用计算运动模板图像的梯度来获取全局运动信息

cvCalcMotionGradient 计算梯度 (输入有允许的最小和最大的梯度值)

cvCalcGlobalOrientation 计算有效梯度方向矢量和来获取全局运动方向

cvSegmentMotion 分割和计算局部运动



预估器

预测阶段 —— 用从过去得到的信息进一步修正模型以取得下一个将会出现的位置

矫正阶段 —— 获得一个测量,然后与基于前一次测量的预期值进行调整

Kalman 滤波器

若有一组强而合理的假设,给出系统的历史测量值,则可以建立最大化这些早前测量值的后验概率的系统状态模型

假设:1,被建模的系统是线性的;2,影响测量的噪声属于白噪声;3,噪声本质上是高斯分布的

额,这个内容挺多的,应该专门看一下

OpenCV —— 跟踪与运动

时间: 06-30

OpenCV —— 跟踪与运动的相关文章

如何用OpenCV跟踪鼠标操作

转载:如何用OpenCV跟踪鼠标操作 http://blog.skyoung.org/2014/05/01/how-to-track-mouse/ 在视频第一帧手动标记出目标的位置是在线视觉跟踪中最基本的一个操作,实现这个操作需要检测鼠标的移动和点击事件.OpenCV提供了setMouseCallback这个函数来响应鼠标的动作,并返回鼠标在绑定窗口上的坐标位置.下面就这个函数的使用做一个简单的介绍. 首先,setMouseCallback的C++函数声明如下: 1 void onMouse(i

opencv实现运动追踪(2)

简介 本篇继续讲解opencv上使用BackgroundSubtractorGMG,进行运动物体跟踪,并将跟踪到运动物体用圆框选起来.本篇是基于opecncv官方实例: bgfg_gmg.cpp,进行讲解和修改. BackgroundSubtractorGMG使用 具体代码 #include <opencv2/opencv.hpp> #include <iostream> #include "opencv2/core/core.hpp" #include &qu

【麦子学院】OpenCV教程函数总结

opencv 2.4.4版本共100个自带例子. parter 1: No1. adaptiveskindetector.cpp 利用HSV空间的色调信息的皮肤检测,背景不能有太多与肤色相似的颜色.效果不是特别好. No2. bagofwords_classification.cpp 好大一串--目前还看不懂. No3. bgfg_codebook.cpp 前后背景分离.开启摄像头或读取视频. No4. bgfg_gmg.cpp 摄像头捕捉,根据运动进行前后背景分离. No5. bgfg_seg

visual tracking------object tracking &amp;&amp; video tracking

key words:   motion estimation and compensation ,  motion analysis,video encode 今天突然有这样的想法:我的研究方向是计算机视觉,但是我这一年来研究的都是在静态场景中,去理解分析,包括opencv处理图像,pcl处理点云,都是静态的,,还没有正经的去处理过动态的,也就是从视频中直接获取想要处理的内容,比如目标检测与跟踪,运动历史及预测轨迹等等.其实,opencv处理对象从内容获取来分类的话,就是两大块:图片和视频.op

工作多年精通C++该具备哪些技能,你会了吗?(进阶C++职业规划)

一.C++服务器程序员(流媒体后台,游戏后台,高性能服务器后台) 精通C++,STL,Linux等,熟悉设计模式: 熟练掌握一门脚本语言(Lua, Python, Perl等): 对多线程环境编程有一定的理解,能独立完成服务器端模块的开发.维护和优化: 熟练掌握MySQL数据库的开发维护.性能优化: 最后,如果大家如果在自学遇到困难,想找一个C++的学习环境,可以加入我们的C++学习圈,点击我加入吧,会节约很多时间,减少很多在学习中遇到的难题.1.精通C++编程,3年以上服务器开发经验: 2.有

opencv-活体检测

▲项目目的:识别真实人脸和照片,实现“识真”而不止“识脸”. ▲使用工具:opencv,python,matlab 首先 1. 构建图像数据集 2. 实现一个能够进行活体检测的卷积神经网络(我们称之为「LivenessNet」) 3. 训练活体检测网络 4. 创建一个能够使用我们训练好的活体检测模型并将其应用于实时视频的 Python+OpenCV 的脚本 (效果图) 活体检测的方法有很多,包括: 纹理分析,包括在人脸区域上计算局部二值模式(LBP,)和使用支持向量机(SVM)将人脸分类为真实的

人类的视觉能力基本上是出生后逐渐习得的

人类的视觉能力基本上是出生后逐渐习得的,婴儿不是眼睛发育不足,而是头脑暂时还不会很好运用眼睛去观察世界,就好比蹩脚的摄影师,拿着顶级单反也拍不出好片. 婴儿开始看世界的过程,就是对视觉处理神经元网络进行训练的过程.初生婴儿需要学习的第一课是分辨物体轮廓,最初他们看到的世界只是各种颜色和明暗的块块,经过学习才知道其中一些总是在一起运动,这部分色彩和明暗变化形成一个固定模式,而另一些则没有这种模式,当这种情况一再重复,最终神经元网络会演化出识别这种模式的算法,于是世界不再是色块,而是一个个物体了,以

Unity 5实战 使用C#和Unity开发多平台游戏pdf

下载地址:城通网盘 作者简介 编辑 Joseph Hocking是一位交互式媒体开发方面的软件工程师.他就职于Synapse Games公司并在芝加哥哥伦比亚学院教授游戏开发课程.[1] " src="/CuteSoft_Client/CuteEditor/Images/anchor.gif"> 目 录 编辑 " src="/CuteSoft_Client/CuteEditor/Images/anchor.gif"> 第Ⅰ部分 起 步

Gears of Programmer--运动篇

运动 平时都在健身房锻炼,早些时候也去游泳,但是路上太麻烦就放弃了,主要聊下健身房里的设备. 一天做下来,在哑铃,跑步机上挥汗如雨也是痛快. Plantronics BackBeat Fit 运动蓝牙耳机 运动时候,对于普通人来说看来,耳机是顶重要的,节奏感比较强力的音乐可以有效地增加兴奋度,让运动的效果更好,或者听一些广播自媒体什么的,让一些枯燥的有氧一会就过去了. 早先是用bose qc20的有线耳机,运动时候用,各种绷挂太多,实在不便. 而在健身房里,还是比较吵杂的,音质特别好的耳机也要大