calcOpticalFlowPyrLK()光流法找特征点

本文介绍了一个使用OpenCV实现的角点检测与光流跟踪的程序。该程序通过读取视频文件,利用角点检测算法寻找特征点,并采用Lucas-Kanade光流跟踪算法来跟踪这些特征点在连续帧间的变化。当跟踪特征点数量不足时,程序会提示背景图像已完全改变。
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>
#include<string>
#include<opencv.hpp>

using namespace cv;
using namespace std;

int main() {

	
	int maxCount = 50;//最大特征点数
	double minDis = 20;//:对于初选出的角点而言,如果
	//在其周围minDis范围内存在其他更强角点,则将此角点删除
	double qLevel = 0.01;//角点的品质因子

	string filename = "result0.avi";
	VideoCapture cap(filename);

	Mat pre, cur;
	Mat pre_gray, cur_gray;
	vector<uchar> status;
	vector<float> err;
	cap >> pre;
	
	cvNamedWindow("cur", CV_WINDOW_NORMAL);
	while (cap.read(cur)) {
		vector<Point2f>pre_points, cur_points;//保存检测出的角点
		cvtColor(pre, pre_gray, CV_RGB2GRAY);
		goodFeaturesToTrack(pre_gray, pre_points, maxCount, qLevel, minDis);//角点识别

		calcOpticalFlowPyrLK(pre, cur, pre_points, cur_points, status, err);//LK金字塔  
		int tr_num = 0;

		for (int i = 0; i < status.size(); i++)
		{
			if (status[i] == 1)
				tr_num++;
		}
		if (tr_num < 6) {//由于是仿射变换,有六个自由度,需要六对特征点解六个方程组
			cout << "you need to change the feat-img because the background-img was all changed" << endl;
			getchar();
			return -1;
		}

		for (int i = 0; i < cur_points.size(); i++)
		{
			circle(cur, cur_points[i], 3, Scalar(0, 255, 0), 2);
			line(cur, pre_points[i], cur_points[i], Scalar(255, 0, 0), 2);//画出两帧之间的光流变化
		}
		
		imshow("cur", cur);
		waitKey(10);

		//pre_points = cur_points;
		pre = cur.clone();//不能用 pre = cur,这是浅拷贝

	}

	waitKey(0);
	return 0;

}

### 稀疏光流法特征点提取的方法实现 在稀疏光流法中,特征点的提取通常依赖于图像的关键位置,这些位置具有较高的梯度变化或其他显著性质。对于LK稀疏光流法而言,在每一帧图像上都会寻特定类型的特征点作为追踪目标。 #### 使用Shi-Tomasi角检测器进行特征点选取 为了有效地执行LK算法,首先需要从当前帧中挑选出合适的特征点。OpenCV库提供了`cv2.goodFeaturesToTrack()`函数来完成这一任务[^1]: ```python import cv2 import numpy as np def detect_features(image, max_corners=100, quality_level=0.01, min_distance=10): gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Shi-Tomasi corner detection parameters corners = cv2.goodFeaturesToTrack(gray_image, maxCorners=max_corners, qualityLevel=quality_level, minDistance=min_distance) return np.intp(corners) if corners is not None else [] ``` 此代码片段展示了如何利用Shi-Tomasi算法到最佳角落点并将其转换成整数坐标形式返回给调用者。通过调整参数可以控制所选特征的数量以及它们之间的最小间距等属性。 #### 应用LK光流向量计算运动方向 一旦获得了初始帧内的特征点集合,则可以在后续帧之间应用LK算法以估计这些点的位置偏移情况。这一步骤涉及到对相邻两帧间像素强度模式匹配的过程,从而得出各个特征点的新坐标位置[^3]: ```python old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) new_gray = cv2.cvtColor(new_frame, cv2.COLOR_BGR2GRAY) # Parameters for lucas kanade optical flow lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) # Calculate Optical Flow using LK method points_new, status, err = cv2.calcOpticalFlowPyrLK(old_gray, new_gray, points_old, None, **lk_params) ``` 上述Python脚本说明了怎样基于前一时刻已知的特征点集(`points_old`)去预测新一时刻相同对象对应点所在之处(`points_new`)。同时还会获得一个状态向量(`status`)用来指示哪些配对成功到了良好解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值