OpenCV是否有类似Matlab的MaxBidirectionalError双向误差处理机制?
OpenCV中实现类似Matlab MaxBidirectionalError的KLT异常值剔除方法
OpenCV原生的calcOpticalFlowPyrLK没有直接对应MaxBidirectionalError的参数,但可以通过双向光流验证手动实现完全相同的逻辑,和Matlab的该参数原理一致。
实现步骤
- 先执行正向光流计算(即你当前已完成的步骤),得到从前一帧到当前帧的特征点。
- 基于正向得到的当前帧特征点,反向计算从当前帧到前一帧的光流,得到反向追踪的特征点。
- 计算原始前一帧特征点与反向追踪结果的欧氏距离,设定阈值(对应Matlab的
MaxBidirectionalError),剔除距离超过阈值的异常点。
示例代码
// 正向光流计算(你已有的代码逻辑) Size winSize(11, 11); int maxLevel = 4; TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 30, 0.01); int flags = 0; double minEigThreshold = 0.0001; vector<Point2f> previous_corners, current_corners; vector<uchar> status; vector<float> err; // 假设已初始化previous_corners及灰度图previous_gray、current_gray calcOpticalFlowPyrLK(previous_gray, current_gray, previous_corners, current_corners, status, err, winSize, maxLevel, termcrit, flags, minEigThreshold); // 第一步:过滤status==0的无效点 vector<Point2f> filtered_prev, filtered_curr; for (size_t i = 0; i < status.size(); ++i) { if (status[i]) { filtered_prev.push_back(previous_corners[i]); filtered_curr.push_back(current_corners[i]); } } // 第二步:反向光流计算 vector<Point2f> reversed_corners; vector<uchar> reverse_status; vector<float> reverse_err; calcOpticalFlowPyrLK(current_gray, previous_gray, filtered_curr, reversed_corners, reverse_status, reverse_err, winSize, maxLevel, termcrit, flags, minEigThreshold); // 第三步:双向误差校验,对应Matlab的MaxBidirectionalError double max_bidirectional_error = 0.5; // 和Matlab参数保持一致 vector<Point2f> final_prev, final_curr; for (size_t i = 0; i < reversed_corners.size(); ++i) { if (reverse_status[i]) { double dist = norm(filtered_prev[i] - reversed_corners[i]); if (dist < max_bidirectional_error) { final_prev.push_back(filtered_prev[i]); final_curr.push_back(filtered_curr[i]); } } } // final_prev和final_curr即为剔除异常值后的有效特征点对
补充说明
- 双向光流验证是KLT特征跟踪中剔除异常值的标准手段,Matlab的
MaxBidirectionalError本质就是封装了这个校验逻辑。 - 你可以根据实际场景调整
max_bidirectional_error的阈值,和Matlab设置的数值一致即可达到近似效果。 - 反向光流计算时务必使用正向过滤后的特征点,避免无效点干扰校验结果。
内容的提问来源于stack exchange,提问作者user3318590
相关产品推荐
相关产品推荐

