OpenCV(cv::findChessboardCorners())

做梦当财神發表於2024-08-30

目錄
  • 1. 函式原型
  • 2. 使用場景
  • 3. 工作原理
  • 4. 示例
    • 4.1 角點精細化
    • 4.2 附加標誌
  • 5. 注意事項



cv::findChessboardCorners() 是 OpenCV 提供的一個函式,常用於計算機視覺中的棋盤影像角點檢測,特別是相機標定(calibration)和三維重建相關的任務中。



1. 函式原型

bool cv::findChessboardCorners(
    InputArray image, 
    Size patternSize, 
    OutputArray corners, 
    int flags = 0
);

引數:

  1. image:輸入影像,通常是灰度圖(單通道)。如果是彩色影像,需要先將其轉換為灰度圖才能傳遞給該函式。

  2. patternSize:棋盤的內角點數目,表示為 Size(columns, rows),其中:

    • columns 是棋盤影像中角點的列數(即內部方格數量 - 1)。
    • rows 是棋盤影像中角點的行數(即內部方格數量 - 1)。
  3. corners:檢測到的棋盤內角點的亞畫素級座標。該輸出引數是一個 OutputArray,其內容是一個 vector<Point2f> 型別的角點座標列表。

  4. flags(可選):用於調整檢測過程的附加引數(標誌位)。一些可選的標誌如下:

    • cv::CALIB_CB_ADAPTIVE_THRESH:自適應閾值化。
    • cv::CALIB_CB_NORMALIZE_IMAGE:歸一化影像亮度,通常和 ADAPTIVE_THRESH 一起使用。
    • cv::CALIB_CB_FILTER_QUADS :篩選出只有四個頂點的四邊形。
    • cv::CALIB_CB_FAST_CHECK:快速檢查模式,不做角點精確檢測,用於減少計算時間。適合用於初步篩選。

返回值:

  • 返回值為 bool 型別。如果成功檢測到角點,返回 true;否則返回 false。這個值表明函式是否成功找到了指定數量的棋盤角點。


2. 使用場景

cv::findChessboardCorners() 主要用於:

  • 相機標定:檢測棋盤的角點,用於後續標定過程中計算相機的內參、外參和畸變係數。
  • 立體視覺中的校正:在左右兩個攝像頭影像中找到匹配的棋盤角點,進行立體校正。
  • 3D 重建:透過多視角的角點資訊,推斷棋盤相對於相機的 3D 位姿。


3. 工作原理

cv::findChessboardCorners() 使用影像處理和模式識別的方法來檢測棋盤影像中的角點。這些角點是棋盤中黑白格子交界的內角點,因此角點的數量是基於指定的 patternSize,即棋盤中內部的格子數。



4. 示例

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image = imread("chessboard.jpg", IMREAD_GRAYSCALE);
    Size patternSize(7, 7);  // 假設棋盤有 7x7 個內角點

    std::vector<Point2f> corners;
    bool found = findChessboardCorners(image, patternSize, corners, CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);

    if (found) {
        // 角點精細化
        cornerSubPix(image, corners, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));

        // 繪製檢測到的角點
        drawChessboardCorners(image, patternSize, Mat(corners), found);
        imshow("Corners", image);
        waitKey(0);
    }

    return 0;
}

在這個示例中,程式載入棋盤影像並呼叫 findChessboardCorners() 查詢 7x7 個內角點,然後繪製這些角點。還呼叫了 cornerSubPix() 進行角點的亞畫素級精度最佳化。

4.1 角點精細化

角點檢測完成後,通常會對角點位置進行精細化(sub-pixel refinement),這可以進一步提高角點位置的準確性。cornerSubPix() 函式用於這個目的,它基於影像的灰度級別對角點進行二次調整,提供亞畫素級的精度。

4.2 附加標誌

  • CALIB_CB_ADAPTIVE_THRESH:自適應閾值化可以更好地處理光照不均勻的情況,特別是在高對比度條件下。
  • CALIB_CB_NORMALIZE_IMAGE:歸一化影像亮度可以消除光照差異的影響,通常和自適應閾值化結合使用。


5. 注意事項

  1. 棋盤的設計findChessboardCorners() 假設棋盤是由交替的黑白方塊組成,因此必須保證棋盤圖案規則、清晰且光照均勻。
  2. 影像預處理:在某些情況下,可能需要對輸入影像進行一些預處理(如平滑、銳化、直方圖均衡化)以提高角點檢測的精度。
  3. 標定影像質量:對於相機標定任務,輸入影像中的棋盤角點越多,拍攝的角度越豐富(不同的視角),標定精度會越高。

透過上述介紹可以看出,cv::findChessboardCorners() 是一個功能強大且重要的函式,特別適用於相機標定和立體視覺中的角點檢測。



相關文章