OpenCV视频序列操作实例

本文详细介绍了如何使用OpenCV库进行视频读取、处理等操作,通过封装的类实现对视频序列的便捷操作。
摘要由CSDN通过智能技术生成
本文章代码基于《OpenCV 2 计算机视觉 编程手册》第10章 处理视频序列。同时对于书中的一些错误代码予以纠正。

由于该章内容基本自成体系,并以类封装了常用的视频读取、处理等操作,故共享于此。

#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//帧处理的接口
//在面向对象的上下文中,更适合使用帧处理类,而非帧处理函数
class FrameProcessor
{
public:
	//处理方法
	virtual void process(Mat &input, Mat &ouput) = 0;
};

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

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

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

	//决定哪些点应该跟踪
	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(Mat &frame, Mat &output)
	{
		//遍历所有跟踪点
		for (int i = 0; i < points[1].size(); i++)
		{
			//绘制直线与圆
			line(output,
					initial[i],		//初始位置
					points[1][i],//新位置
					Scalar(255, 255, 255));
			circle(output, points[1][i], 3, Scalar(255, 255, 255), -1);
		}
	}
	void process(Mat &frame, Mat &output)
	{
		//转换为灰度图像
		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.跟踪特征点
		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++)
		{
			//是否需要保留该点࿱
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值