您的位置:首页 > 理论基础

《OpenCV2 计算机视觉编程手册》视频处理二

2015-01-06 21:01 309 查看
本文结合上文《OpenCV2 计算机视觉编码手册》视频处理一的基础上,添加视频跟踪类,来对视频中运动对象进行跟踪。

1. 添加特征跟踪类

#ifndef FTRACKER
#define FTRACKER

#include "head.h"
#include "videoprocessor.h"
#include <opencv2/video/tracking.hpp>
#include <opencv2/features2d/features2d.hpp>

class FeatureTracker : public FrameProcessor
{
private:
cv::Mat gray;			            // 当前灰度图像
cv::Mat gray_prev;		            // 前一个灰度图像
std::vector<cv::Point2f> points[2]; // 两幅图像跟踪特征 0->1
std::vector<cv::Point2f> initial;   // 跟踪点的初始化
std::vector<cv::Point2f> features;  // 检测到的特征
int max_count;	                    // 需要跟踪的最大特征数目
double qlevel;                      // 特征检测中的质量等级
double minDist;                     // 两特征点之间的最小距离
std::vector<uchar> status;          // 跟踪的特征状态
std::vector<float> err;             // 跟踪错误

public:
// 构造函数
FeatureTracker() : max_count(500), qlevel(0.01), minDist(10.) {}

// 处理方法
void process(cv:: Mat &frame, cv:: Mat &output)
{
cv::cvtColor(frame, gray, CV_BGR2GRAY);  // 转换为灰度图像
frame.copyTo(output);

// 1. 如果需要添加新的特征点
if(addNewPoints())
{
detectFeaturePoints();                                            // 检测特征点
points[0].insert(points[0].end(),features.begin(),features.end());// 添加检测的特征到当前跟踪的特征
initial.insert(initial.end(),features.begin(),features.end());
}

// 对应视频序列中的第一幅图像
if(gray_prev.empty())
gray.copyTo(gray_prev);

// 2.跟踪特征
cv::calcOpticalFlowPyrLK(gray_prev, gray, // 两幅连续图像
points[0],                            // 图1中的输入点坐标
points[1],                            // 图2中的输出点坐标
status,                               // 跟踪成功
err);                                 // 跟踪失败

// 2. 遍历所有跟踪点进行筛选
int k=0;
for( int i= 0; i < points[1].size(); i++ )
{
// 是否需要保留该跟踪点?
if (acceptTrackedPoint(i))
{
// 保留该跟踪点到vector
initial[k]= initial[i];
points[1][k++] = points[1][i];
}
}

// 去除不成功点
points[1].resize(k);
initial.resize(k);

// 3. 处理接受的跟踪点
handleTrackedPoints(frame, output);

// 4. 当前的点和图像变为它之前的点和图像
std::swap(points[1], points[0]);
cv::swap(gray_prev, gray);
}

// 特征点检测
void detectFeaturePoints()
{	// 检测特征
cv::goodFeaturesToTrack(gray, // 图像
features,   // 检测到的特征
max_count,  // 特征的最大数目
qlevel,     // 质量等级
minDist);   // 两个特征之间的最小距离
}

// 决定是否添加新点
bool addNewPoints()
{
// 如果点的数量太少
return points[0].size()<=10;
}

// 决定哪些点应该跟踪
bool acceptTrackedPoint(int i)
{
return status[i] &&
// 如果它移动了
(abs(points[0][i].x-points[1][i].x)+
(abs(points[0][i].y-points[1][i].y))>2);
}

// 处理当前跟踪点
void handleTrackedPoints(cv:: Mat &frame, cv:: Mat &output)
{
// 遍历所有跟踪点
for(int i= 0; i < points[1].size(); i++ )
{
// 绘制直线和圆
cv::line(output,
initial[i],            // 初始位置
points[1][i],          // 新位置
cv::Scalar(255,255,255)// 白色
);

cv::circle(output,          // 输出图像
points[1][i],           // 圆心
3,                      // 半径
cv::Scalar(255,255,255),// 白色
-1                      // 负数表示填充圆圈, 整数表示线条厚度
);
}
}
};

#endif


2. main函数

#include "featuretracker.h"

int main()
{
VideoProcessor processor;                           // 创建一个视频处理实例
FeatureTracker tracker;                             // 创建一个特征跟踪实例
processor.setInput("../bike.avi");                  // 打开视频文件
processor.setFrameProcessor(&tracker);              // 设置帧处理器为一个特征跟踪实例tracker
processor.displayOutput("Tracked Features");        // 声明跟踪特征显示窗口
processor.setDelay(1000./processor.getFrameRate()); // 设置视频播放帧率为原始帧率
processor.run();                                    // 开始处理
cv::waitKey();                                      // 等待按键响应

return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算机视觉 视频
相关文章推荐