☰
OpenCV opencv_contrib 中的 Quasi Dense Stereo(准稠密立体匹配)模块实战指南
2026/9/25 3:24:49 网站建设 项目流程
  • 计算机视觉
  • 图像处理
  • 机器学习

【免费下载链接】opencv_contrib

项目地址:https://gitcode.com/gh_mirrors/ope/opencv_contrib
点击查看免费下载

Quasi Dense Stereo(准稠密立体匹配)是 opencv_contrib 仓库中stereo模块提供的一种稠密立体匹配方法,它先用 "Good Features to Track"(GFT)与金字塔 Lucas-Kanade 光流获得稀疏种子匹配,再通过区域生长(growing scheme)把这些种子逐步传播为稠密对应点,最终输出稠密视差图与匹配点集合。本文将围绕 Quasi Dense Stereo 教程入口 及其两篇子教程展开:读者读完可以掌握QuasiDenseStereo类的创建与配置、如何对一对立体图像计算稠密对应关系并可视化视差图、如何导出并调优参数模板文件,并理解其底层实现原理(ZNCC 相关度量、积分图加速、纹理描述符过滤等)。

方法概述:从稀疏种子到稠密传播

QuasiDenseStereo是cv::stereo命名空间下实现准稠密立体匹配的类。其核心思想分两步(见 类注释):

  1. 稀疏匹配(种子获取):在左图中用 Shi-Tomasi 角点(OpenCV 的goodFeaturesToTrack)提取显著特征,再以金字塔 Lucas-Kanade 光流(calcOpticalFlowPyrLK)在右图中跟踪这些特征点,得到初始的稀疏对应关系,作为传播的种子。
  2. 稠密传播(区域生长):对每个种子对,在左右图对应的小邻域内计算零均值归一化互相关(Zero-mean Normalized Cross-Correlation,ZNCC)作为匹配质量度量。种子按 ZNCC 值存入优先级队列(priority queue),算法每次弹出质量最高的匹配,在其邻域内检索超过纹理阈值且未被计算过的新对应点,形成新匹配并再次入队作为种子,直到无法再检索到新匹配为止。

该方法是 Stoyanov 等人工作的代码实现(引用见头文件@cite Stoyanov2010),原始区域生长思想源自@cite Lhuillier2000。整个传播过程由 quasi_dense_matching 实现 中的主循环完成。

核心数据结构与公共 API

匹配结构MatchQuasiDense

一个基本的匹配结构,包含左图点p0、右图点p1以及相关值corr(即 ZNCC 值),并重载了<运算符以便按corr排序(见 MatchQuasiDense)。

参数结构PropagationParameters

传播过程所需的全部可调参数,分为三类(见 PropagationParameters):

  • 相似度窗口:corrWinSizeX、corrWinSizeY,ZNCC 计算使用的窗口尺寸;
  • 匹配过滤:borderX、borderY(忽略的图像边界)、correlationThreshold(相关阈值)、textrureThreshold(纹理阈值)、neighborhoodSize(邻域尺寸)、disparityGradient(视差梯度阈值);
  • Lucas-Kanade 光流参数:lkTemplateSize、lkPyrLvl、lkTermParam1、lkTermParam2;
  • GFT 特征参数:gftQualityThres(质量阈值)、gftMinSeperationDist(最小间隔距离)、gftMaxNumFeatures(最大特征数)。

QuasiDenseStereo类方法

  • static Ptr<QuasiDenseStereo> create(cv::Size monoImgSize, cv::String paramFilepath = ...):工厂方法,第一个参数为单目图像尺寸,第二个可选参数为 YAML 配置文件路径,缺省时加载默认参数;
  • int loadParameters(cv::String filepath):从 YAML 文件加载参数。返回1表示成功加载文件参数,0表示路径为空而加载默认参数,-1表示文件无效并回退默认参数(见 loadParameters);
  • int saveParameters(cv::String filepath):把当前参数写入 YAML 文件,不传参数时默认写入根目录下名为qds_parameters.yaml的文件,可用于生成调参模板;
  • void process(const cv::Mat& imgLeft, const cv::Mat& imgRight):主流程,内部先转灰度,再依次调用稀疏匹配与稠密匹配;彩色输入按 BGR 假设转换;
  • void getSparseMatches(...)/void getDenseMatches(...):分别取出稀疏与稠密对应点向量(返回的匹配元素不使用corr成员);
  • cv::Point2f getMatch(int x, int y):给定左图像素坐标,返回右图对应位置;无匹配时返回Point(0,0)(NO_MATCH)。必须在process()之后调用;
  • cv::Mat getDisparity():基于process()得到的对应关系计算并返回视差图(灰度,默认量化等级 50)。

实战一:对立体图像对计算稠密对应与视差图

对应教程为 qds_quasi_dense_stereo.markdown,完整示例代码见 dense_disparity.cpp。

1. 加载立体图像对

程序先加载左右两幅图像(彩色模式读取):

cv::Mat rightImg, leftImg; leftImg = imread("./imgLeft.png", IMREAD_COLOR); rightImg = imread("./imgRight.png", IMREAD_COLOR);

2. 创建QuasiDenseStereo对象

需要单张图像的尺寸来构造对象。不指定第二个参数,对象将加载默认参数:

cv::Size frameSize = leftImg.size(); Ptr<stereo::QuasiDenseStereo> stereo = stereo::QuasiDenseStereo::create(frameSize);

3. 执行主流程

把左右图传入process方法,完成稀疏种子计算与稠密传播:

stereo->process(leftImg, rightImg);

4. 获取并显示视差图

process()之后即可取视差图并显示:

cv::Mat disp; disp = stereo->getDisparity(); cv::namedWindow("disparity map"); cv::imshow("disparity map", disp);

示例中还同时显示左右通道原图,并等待按键(cv::waitKey(0))。

5. 导出稠密对应点

通过getDenseMatches()取出全部稠密匹配并写入文本文件,每一行输出左图点与右图点坐标:

vector<stereo::MatchQuasiDense> matches; stereo->getDenseMatches(matches); std::ofstream dense("./dense.txt", std::ios::out); for (uint i=0; i< matches.size(); i++) { dense << matches[i].p0 << matches[i].p1 << endl; } dense.close();

实战二:导出参数模板文件

对应教程为 qds_export_parameters.markdown,完整示例见 export_param_file.cpp。

QuasiDenseStereo支持通过loadParameters()从 YAML 文件加载配置,便于在视频处理等场景中动态微调参数。先用以下代码生成一份参数模板:

Ptr<stereo::QuasiDenseStereo> stereo = stereo::QuasiDenseStereo::create(cv::Size(5,5));
std::string parameterFileLocation = "./parameters.yaml"; if (argc > 1) parameterFileLocation = argv[1]; stereo->saveParameters(parameterFileLocation);

运行后可把parameters.yaml模板作为起点,编辑其中的阈值后通过loadParameters()加载。

参数详解与默认值(源码级)

下表整理了loadParameters在无配置文件时设定的全部默认参数(来源:quasi_dense_stereo.cpp),以及它们在源码中的用途:

参数默认值作用
borderX/borderY15 / 15忽略的图像边界宽度,种子与候选匹配靠近边界会被丢弃(CheckBorder)
corrWinSizeX/corrWinSizeY5 / 5ZNCC 计算窗口尺寸
correlationThreshold0.5ZNCC 相关阈值,低于该值的候选匹配被丢弃
textrureThreshold200纹理描述符阈值,用于过滤平坦/无纹理区域
neighborhoodSize5种子周围待搜索的邻域半径,实际为2*N+1的方形区域
disparityGradient1候选匹配在右图的视差梯度搜索范围
lkTemplateSize3Lucas-Kanade 模板尺寸
lkPyrLvl3金字塔层数
lkTermParam13LK 迭代终止条件(MAX_ITER)
lkTermParam20.003LK 迭代终止条件(EPS)
gftQualityThres0.01GFT 质量阈值
gftMinSeperationDist10GFT 特征最小间隔距离
gftMaxNumFeatures500GFT 最大特征数量

调参要点:correlationThreshold控制匹配严格程度,越大匹配越少但更可靠;neighborhoodSize与disparityGradient决定传播的搜索范围,直接影响稠密程度与计算量;gftMaxNumFeatures决定初始种子数量,影响最终覆盖率。

源码级原理深入

稀疏匹配:GFT + 金字塔 LK

在 sparseMatching 中,先以gftMaxNumFeatures、gftQualityThres、gftMinSeperationDist为参数调用goodFeaturesToTrack提取左图特征,再以lkTemplateSize、lkPyrLvl及TermCriteria(MAX_ITER|EPS, lkTermParam1, lkTermParam2)调用calcOpticalFlowPyrLK在右图跟踪;跟踪失败(featureStatus[i]==0)的特征会被剔除,保证左右特征向量一一对应。

稠密传播:优先级队列 + ZNCC + 积分图

process()内部先把输入转为灰度,再调用sparseMatching与 quasiDenseMatching。传播阶段的关键环节:

  • 纹理描述符:buildTextureDescriptor为每个像素计算其与上下左右四邻域的绝对灰度差最大值,作为纹理描述符;超过textrureThreshold的像素(边缘/强纹理处)不参与匹配,避免错误传播;
  • 积分图加速:cv::integral同时生成灰度积分图与灰度平方积分图(sum0/ssum0、sum1/ssum1),使任意尺寸窗口的和与平方和都能在常数时间内取得(patchSumSum2),ZNCC 计算因此与窗口大小无关;
  • 种子队列:extractSparseSeeds对每个稀疏匹配计算 ZNCC,超过correlationThreshold的才入种子队列并登记到refMap/mtcMap;
  • 传播主循环:每次弹出 ZNCC 最高的种子,在左图2*neighborhoodSize+1邻域内、右图2*disparityGradient+1视差范围内搜索候选;候选通过iZNCC_c1计算相关值,超过阈值后先入局部队列,再从局部队列按质量降序弹出,只有当左右图均未登记该点时(唯一性约束)才注册为正式匹配并重新入种子队列,直至队列为空。

视差计算

computeDisparity遍历整幅左图,对每个有匹配的像素计算其与右图对应点的欧氏距离sqrt(dx*dx+dy*dy)作为视差值,无匹配像素置为NAN(见 computeDisparity)。

使用前提与注意事项

  • 该模块属于 opencv_contrib,需要以opencv_contrib方式构建 OpenCV 后通过#include <opencv2/stereo.hpp>使用,示例中同时依赖opencv2/highgui.hpp用于显示;
  • 输入图像尺寸需一致,create时的monoImgSize应取单张图像尺寸;
  • getMatch、getDisparity、getDenseMatches必须在process()之后调用,否则结果不正确;
  • 彩色输入会被按 BGR 假设转为灰度处理;
  • 无匹配的像素在视差图中为NAN,导出匹配点时会自动跳过。

进一步可参考仓库内其余资料:stereo 模块教程目录、stereo 模块 CMake 配置 以及 Python 示例,以便在不同语言与构建环境下快速上手。

  • 计算机视觉
  • 图像处理
  • 机器学习

【免费下载链接】opencv_contrib

项目地址:https://gitcode.com/gh_mirrors/ope/opencv_contrib
点击查看免费下载

相关推荐

上一篇:android-audio-visualizer扩展开发:自定义可视化效果的完整指南
下一篇:深入探索GoMock:轻松掌握mockgen的类型解析与反射机制

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询