首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

OpenCV Stereo Matching 入門:從理論到代碼實戰

     編輯:程式設計綜合問答

什麼是 Stereo Matching?

雙目立體匹配透過左右兩顆相機拍攝同一場景,利用視差原理計算像素深度,生成深度圖/點雲,是 3D 重建、自動駕駛、機器人導航的核心技術。

OpenCV 核心類別與流程

  1. 校正 — stereoCalibrate, stereoRectify,獲得校正映射表 map1x, map1y, map2x, map2y。
  2. 校正應用 — remap 將原圖校正為極線對齊 (同一掃描線對應同一 3D 點)。
  3. 匹配算法 —
    • StereoBM (Block Matching) — 快速、適合紋理豐富場景,參數 numDisparities (16 倍數)、blockSize (奇數 5~21)。
    • StereoSGBM (Semi-Global Block Matching) — 半全域優化,邊緣銳利、抗噪強,參數較多 (P1, P2, uniquenessRatio, speckleWindowSize 等)。
  4. 後處理 — filterSpeckles 去噪、normalize 視覺化、reprojectImageTo3D 獲取點雲。

最小可運行範例 (C++)

#include 
using namespace cv;

int main() {
    Mat imgL = imread("left.png", IMREAD_GRAYSCALE);
    Mat imgR = imread("right.png", IMREAD_GRAYSCALE);
    if (imgL.empty() || imgR.empty()) return -1;

    // 假設已完成校正,直接匹配
    Ptr sgbm = StereoSGBM::create(0, 96, 9);
    sgbm->setP1(8*9*9);
    sgbm->setP2(32*9*9);
    sgbm->setUniquenessRatio(10);
    sgbm->setSpeckleWindowSize(100);
    sgbm->setSpeckleRange(32);

    Mat disp;
    sgbm->compute(imgL, imgR, disp); // 16-bit signed, 值 = 視差 * 16
    disp.convertTo(disp, CV_32F, 1.0/16.0); // 真實視差

    // 視覺化
    Mat dispVis;
    normalize(disp, dispVis, 0, 255, NORM_MINMAX, CV_8U);
    imshow("Disparity", dispVis);
    waitKey(0);
    return 0;
}

關鍵參數調試心法

  • numDisparities:覆蓋最近/最遠物體視差範圍,必須為 16 的倍數,過大費時、過小丟失遠近物體。
  • blockSize:越大越平滑但邊緣模糊,越小越銳利但噪點多。典型 7~11。
  • P1, P2 (SGBM):懲罰視差變化,P2 > P1,經驗公式 P1=8*channels*blockSize^2, P2=32*channels*blockSize^2。
  • uniquenessRatio:最佳代價比次佳代價優勢百分比,5~15 平衡誤匹配與漏匹配。

進階資源

  • OpenCV 官方範例:samples/cpp/stereo_match.cpp
  • 中文教學部落格:OpenCV Stereo Matching 詳細講解
  • 經典論文:Stereo Processing by Semiglobal Matching and Mutual Information (Hirschmüller, 2007)

總結

OpenCV 提供完整的 StereoBM/SGBM 流程,關鍵在於精準校正與參數微調。建議先用官方範例跑通流程,再針對具體場景 (室內/室外、紋理貧瘠/豐富) 逐步優化參數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved