OpenCV

【C++】OpenCVでカメラキャリブレーションを行う手順とサンプルコード

C++とOpenCVを使ったキャリブレーションは、チェスボード撮影→cv::findChessboardCornersでコーナー検出→cv::calibrateCameraで内部パラメータ推定→cv::undistortで歪み補正を一貫して実現し、精度の高い画像処理が可能になります。

チェスボードキャリブレーションの準備

チェスボードパターンと3Dポイントの定義

カメラキャリブレーションを行う際に最も一般的に使用されるパターンは、チェスボード(チェッカーボード)パターンです。

これは、白と黒の正方形が交互に並んだ格子状のパターンで、画像中のコーナー点を検出しやすいためです。

キャリブレーションの精度を高めるためには、パターンのサイズや配置を正確に定義し、対応する3D空間上の点も明確に設定しておく必要があります。

チェスボードパターンの選択と準備

OpenCVの公式資料や多くの実践例では、9×6のコーナー点(内部交点)を持つチェスボードパターンがよく使われます。

これは、9列と6行の白黒の正方形の格子の交点をコーナー点として検出しやすいためです。

  • パターンのサイズ:例えば、9×6のコーナー点を持つパターンは、横方向に9個、縦方向に6個の交点があります
  • 印刷と準備:このパターンはOpenCVの公式サイトや他のリソースからダウンロードでき、適切なサイズに印刷します。印刷時には、縮尺や歪みを避けるために、できるだけ正確に印刷し、平らな面に貼り付けることが重要です

3Dポイントの定義

キャリブレーションのためには、パターン上のコーナー点の3D座標を定義します。

これらは、カメラから見た2D画像のコーナー点と対応させるために必要です。

  • 内部座標系の設定:パターンの平面をZ=0としたときの、コーナー点の座標を定義します
  • 座標の計算例:一辺の長さをsquareSizeとした場合、コーナー点の座標は次のように設定できます
点番号X座標Y座標Z座標
(0,0)000
(1,0)squareSize00
(2,0)2 * squareSize00
(8,5)8 * squareSize5 * squareSize0

このように、各コーナー点の座標は、格子の位置に応じて計算され、すべての点が平面上に配置されます。

チェスボードパターンの選定と準備は、キャリブレーションの成功にとって非常に重要です。

パターンのサイズや印刷の正確さ、そして3D座標の定義を正確に行うことで、後のコーナー検出やパラメータ推定の精度が向上します。

次のステップでは、実際に撮影した画像からコーナー点を検出し、キャリブレーションを進めていきます。

コーナー検出の実装

グレースケール変換とコントラスト調整

画像からチェスボードのコーナー点を検出するためには、まず画像をグレースケールに変換します。

カラー画像は色情報がノイズとなる場合があるため、コーナー検出の精度を高めるためにグレースケール化を行います。

#include <opencv2/opencv.hpp>
#include <vector>
#include <string>
int main() {
    // 画像の読み込み
    cv::Mat colorImage = cv::imread("calibration_image.jpg");
    if (colorImage.empty()) {
        std::cerr << "画像が見つかりません。" << std::endl;
        return -1;
    }
    // グレースケール変換
    cv::Mat grayImage;
    cv::cvtColor(colorImage, grayImage, cv::COLOR_BGR2GRAY);
    // コントラスト調整(必要に応じて)
    // 例:ヒストグラム均等化
    cv::equalizeHist(grayImage, grayImage);
    // 以降のコーナー検出に使用
    // ...
}

コントラスト調整は、画像のコントラストが低い場合にコーナー検出の成功率を向上させるために有効です。

cv::equalizeHistを使うことで、画像の明暗差を強調し、コーナーの検出を安定させます。

findChessboardCornersの設定

cv::findChessboardCornersは、画像中のチェスボードのコーナー点を検出する関数です。

検出の成功率と精度を左右するパラメータ設定が重要です。

cv::Size patternSize(9, 6); // パターンのコーナー点数(横9、縦6)
std::vector<cv::Point2f> cornerPoints; // 検出されたコーナー点を格納するベクター
// コーナー検出の実行
bool patternFound = cv::findChessboardCorners(
    grayImage,
    patternSize,
    cornerPoints,
    cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE | cv::CALIB_CB_FAST_CHECK
);

フラグと基準点数の指定

  • フラグの選択
    • cv::CALIB_CB_ADAPTIVE_THRESH:適応的閾値処理を行い、コーナー検出の安定性を向上させます
    • cv::CALIB_CB_NORMALIZE_IMAGE:画像の正規化を行い、照明条件の変動に対応
    • cv::CALIB_CB_FAST_CHECK:高速化のために簡易的な検出を行います
  • 基準点数の指定

パターンのコーナー点数(例:9×6)をcv::Sizeで指定します。

これにより、検出すべきコーナーの数が決まります。

cornerSubPixによる精度向上

コーナー点の検出後、その位置をより正確に特定するためにcv::cornerSubPixを使用します。

これにより、サブピクセルレベルの位置補正が可能となり、キャリブレーションの精度が向上します。

if (patternFound) {
    // コーナー点のサブピクセル補正
    cv::cornerSubPix(
        grayImage,
        cornerPoints,
        cv::Size(11, 11), // ウィンドウサイズ
        cv::Size(-1, -1), // センターからの探索範囲(デフォルト)
        cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.001)
    );
}

収束条件の調整

cv::TermCriteriaは、サブピクセル補正の収束条件を設定します。

  • cv::TermCriteria::EPS:補正の変化が閾値以下になったら終了
  • cv::TermCriteria::COUNT:一定回数の反復後に終了
  • 例:cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.001)は、最大30回の反復または変化が0.001以下になった時点で終了します

この設定により、コーナー点の位置が安定し、検出結果の信頼性が高まります。

コーナー検出の工程では、まず画像をグレースケールに変換し、必要に応じてコントラストを調整します。

次に、cv::findChessboardCornersを適切なフラグとともに呼び出し、コーナー点を検出します。

最後に、cv::cornerSubPixを用いて検出点の位置をサブピクセルレベルに補正し、キャリブレーションの精度を高めます。

これらの工程を丁寧に行うことで、正確なカメラパラメータ推定に繋がります。

カメラキャリブレーションの実行

calibrateCameraの呼び出し

cv::calibrateCameraは、キャリブレーションの核心となる関数であり、複数の画像から得られたコーナー点と対応する3Dポイントをもとに、カメラの内部パラメータと歪み係数を推定します。

#include <opencv2/opencv.hpp>
#include <vector>
#include <string>
int main() {
    // 事前に検出したコーナー点と3Dポイントの準備
    std::vector<std::vector<cv::Point3f>> objectPoints; // 3D空間の点
    std::vector<std::vector<cv::Point2f>> imagePoints;  // 画像中の点
    // 例:複数画像のコーナー点と3Dポイントを格納
    // objectPointsとimagePointsにデータを格納しておく
    cv::Mat cameraMatrix, distCoeffs;
    std::vector<cv::Mat> rvecs, tvecs;
    // キャリブレーションの実行
    double rms = cv::calibrateCamera(
        objectPoints,    // 3Dポイントの配列
        imagePoints,     // 2Dコーナー点の配列
        cv::Size(imageWidth, imageHeight), // 画像サイズ
        cameraMatrix,    // 出力:カメラ行列
        distCoeffs,      // 出力:歪み係数
        rvecs,           // 出力:回転ベクトル
        tvecs,           // 出力:並進ベクトル
        cv::CALIB_FIX_K4 | cv::CALIB_FIX_K5 // オプション(必要に応じて)
    );
}

入力配列の構成

  • objectPoints:各画像ごとに検出されたコーナー点の3D座標を格納したベクトルの配列。各要素は、cv::Point3fのリストで、パターンの平面上の点の座標を定義します
  • imagePoints:各画像ごとに検出されたコーナー点の2D座標を格納したベクトルの配列。各要素は、cv::Point2fのリストです
  • Size:画像の解像度(幅と高さ)を指定します

これらの配列は、キャリブレーションに必要な対応点の情報を提供し、複数画像からの平均的なパラメータ推定を可能にします。

出力されるカメラ行列と歪み係数

  • cameraMatrix:3×3の行列で、焦点距離と主点の位置を表します。一般的な形式は次の通りです

[fx0cx0fycy001]

  • distCoeffs:歪み係数のベクトルで、一般的に次のパラメータを含みます

distCoeffs=[k1,k2,p1,p2,k3,]

これらのパラメータは、画像の歪みを補正するために使用され、キャリブレーション後の画像補正や計測の精度向上に役立ちます。

再投影誤差の算出と評価

キャリブレーションの結果の信頼性を評価するために、再投影誤差を計算します。

これは、推定されたカメラパラメータを用いて、3Dポイントを画像平面に再投影し、実際に検出された2Dコーナー点と比較することで求められます。

meanErrorの計算方法

double totalError = 0;
int totalPoints = 0;
for (size_t i = 0; i < objectPoints.size(); ++i) {
    std::vector<cv::Point2f> projectedPoints;
    // 3D点を画像平面に再投影
    cv::projectPoints(
        objectPoints[i], // 3Dポイント
        rvecs[i],        // 回転ベクトル
        tvecs[i],        // 並進ベクトル
        cameraMatrix,    // カメラ行列
        distCoeffs,      // 歪み係数
        projectedPoints  // 出力:再投影された2D点
    );
    // 実測値と再投影値の距離の合計
    double err = 0;
    for (size_t j = 0; j < objectPoints[i].size(); ++j) {
        err += cv::norm(imagePoints[i][j] - projectedPoints[j]);
    }
    totalError += err;
    totalPoints += static_cast<int>(objectPoints[i].size());
}
// 平均誤差(ピクセル単位)
double meanError = totalError / totalPoints;

このmeanErrorは、全ての画像のコーナー点についての平均的な再投影誤差を示します。

精度評価の基準

  • 良好なキャリブレーションmeanErrorが1ピクセル以下であれば、かなり正確なパラメータが得られていると考えられます
  • 許容範囲:2ピクセル以内であれば、実用上問題ない場合が多いです
  • 改善ポイント:誤差が大きい場合は、画像のコーナー検出の精度向上や、パターンの多様な角度からの撮影、画像枚数の増加を検討します

cv::calibrateCameraを呼び出す際には、対応点の配列を正確に準備し、画像サイズを指定します。

結果として得られるカメラ行列と歪み係数は、画像の歪み補正や計測の基準となります。

キャリブレーションの信頼性は、再投影誤差の平均値で評価し、必要に応じて撮影条件や検出精度の改善を行います。

これにより、より正確なカメラパラメータを得ることができ、画像処理や計測の精度向上に役立ちます。

歪み補正の適用

undistortによる補正手順

cv::undistort関数は、キャリブレーションで得られた歪み係数とカメラ行列を用いて、歪んだ画像を補正し、歪みのない画像を生成します。

以下に具体的な手順を示します。

#include <opencv2/opencv.hpp>
#include <string>
int main() {
    // 例:歪み補正に使用する画像
    cv::Mat distortedImage = cv::imread("distorted_image.jpg");
    if (distortedImage.empty()) {
        std::cerr << "画像が見つかりません。" << std::endl;
        return -1;
    }
    // 事前にキャリブレーションで得たカメラ行列と歪み係数
    cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) <<
        1000, 0, 640,
        0, 1000, 360,
        0, 0, 1);
    cv::Mat distCoeffs = (cv::Mat_<double>(5,1) << -0.2, 0.1, 0, 0, 0);
    // 補正後の画像を格納するMat
    cv::Mat undistortedImage;
    // 歪み補正の実行
    cv::undistort(distortedImage, undistortedImage, cameraMatrix, distCoeffs);
    // 補正前後の画像を表示
    cv::imshow("歪み補正前", distortedImage);
    cv::imshow("歪み補正後", undistortedImage);
    cv::waitKey(0);
}

この例では、cv::undistortに入力画像、カメラ行列、歪み係数を渡すだけで、歪みの補正画像を得ることができます。

マッピング関数の生成

cv::initUndistortRectifyMapを使うと、補正に必要なマッピング関数(マップ)を事前に生成し、複数の画像に対して効率的に歪み補正を適用できます。

これにより、リアルタイム処理や連続画像処理に適しています。

#include <opencv2/opencv.hpp>
#include <string>
int main() {
    // 画像サイズ
    cv::Size imageSize(1280, 720);
    // 事前にキャリブレーションで得たカメラ行列と歪み係数
    cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) <<
        1000, 0, 640,
        0, 1000, 360,
        0, 0, 1);
    cv::Mat distCoeffs = (cv::Mat_<double>(5,1) << -0.2, 0.1, 0, 0, 0);
    // マップを格納する変数
    cv::Mat map1, map2;
    // マッピング関数の生成
    cv::initUndistortRectifyMap(
        cameraMatrix,
        distCoeffs,
        cv::Mat(),
        cameraMatrix,
        imageSize,
        CV_16SC2,
        map1,
        map2
    );
    // 画像の読み込み
    cv::Mat distortedImage = cv::imread("distorted_image.jpg");
    if (distortedImage.empty()) {
        std::cerr << "画像が見つかりません。" << std::endl;
        return -1;
    }
    // マップを用いて補正
    cv::Mat undistortedImage;
    cv::remap(distortedImage, undistortedImage, map1, map2, cv::INTER_LINEAR);
    // 結果の表示
    cv::imshow("歪み補正前", distortedImage);
    cv::imshow("歪み補正後(マップ使用)", undistortedImage);
    cv::waitKey(0);
}

この方法では、一度マップを生成すれば、複数の画像に対して効率的に歪み補正を行えます。

補正結果の可視化と比較

歪み補正の効果を確認するために、補正前後の画像を並べて比較します。

以下のポイントに注意します。

  • 歪みの除去:補正後の画像は、歪みの影響を受けていた部分が直線的になり、幾何学的に正しい形状に近づきます
  • エッジのシャープさ:歪み補正により、直線や角のエッジがよりシャープに見えることが多いです
  • コーナーの位置:キャリブレーションに使ったコーナー点の位置が、補正後の画像ではより正確に配置されていることを確認します
cv::imshow("歪み補正前", distortedImage);
cv::imshow("歪み補正後", undistortedImage);
cv::waitKey(0);

また、画像の一部を拡大して比較したり、直線の歪み具合を測定したりすることで、補正の効果を定量的に評価できます。

cv::undistortは、キャリブレーションで得たパラメータを用いて画像の歪みを補正します。

initUndistortRectifyMapを使えば、補正用のマッピング関数を事前に生成でき、効率的に複数の画像に適用可能です。

補正結果は、歪みの除去や直線の復元といった視覚的な改善だけでなく、計測や画像解析の精度向上にも寄与します。

補正前後の画像を比較し、その効果を確認することが重要です。

キャリブレーション結果の保存と読み込み

XML/YAML形式でのファイル書き出し

OpenCVでは、キャリブレーションで得られたカメラ行列や歪み係数をファイルに保存し、後で再利用できるようにすることが可能です。

これにはcv::FileStorageクラスを使用します。

#include <opencv2/opencv.hpp>
#include <string>
int main() {
    // キャリブレーション結果の例
    cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) <<
        1000, 0, 640,
        0, 1000, 360,
        0, 0, 1);
    cv::Mat distCoeffs = (cv::Mat_<double>(5,1) << -0.2, 0.1, 0, 0, 0);
    // ファイルに書き出し
    cv::FileStorage fs("calibration_params.yaml", cv::FileStorage::WRITE);
    // YAML形式で保存
    fs << "cameraMatrix" << cameraMatrix;
    fs << "distCoeffs" << distCoeffs;
    fs.release();
    // もしくはXML形式で保存
    // cv::FileStorage fs("calibration_params.xml", cv::FileStorage::WRITE);
    // fs << "cameraMatrix" << cameraMatrix;
    // fs << "distCoeffs" << distCoeffs;
    // fs.release();
    return 0;
}

このコードでは、cv::FileStorageを使ってcameraMatrixdistCoeffscalibration_params.yamlに保存しています。

保存形式は拡張子によって自動的に決まり、.yaml.xmlを指定できます。

再利用のための読み込み処理

保存したキャリブレーションパラメータは、cv::FileStorageを使って簡単に読み込むことができます。

#include <opencv2/opencv.hpp>
#include <string>
int main() {
    cv::Mat cameraMatrix, distCoeffs;
    // YAMLファイルから読み込み
    cv::FileStorage fs("calibration_params.yaml", cv::FileStorage::READ);
    if (!fs.isOpened()) {
        std::cerr << "ファイルを開けませんでした。" << std::endl;
        return -1;
    }
    fs["cameraMatrix"] >> cameraMatrix;
    fs["distCoeffs"] >> distCoeffs;
    fs.release();
    // 読み込んだパラメータを使って補正や計測を行う
    // 例:歪み補正
    // cv::undistort(image, undistortedImage, cameraMatrix, distCoeffs);
    return 0;
}

この例では、cv::FileStorageを使って保存したcalibration_params.yamlからcameraMatrixdistCoeffsを読み込み、変数に格納しています。

これにより、キャリブレーション結果を再利用して、画像の歪み補正や計測処理を効率的に行えます。

キャリブレーション結果はcv::FileStorageを使ってYAMLやXML形式のファイルに保存できます。

保存したパラメータは、後から簡単に読み込み可能で、画像補正や計測処理の再利用に役立ちます。

これにより、キャリブレーション作業の効率化と、複数の画像やセッションでの一貫したパラメータ管理が実現します。

応用と最適化

追加画像による精度向上

キャリブレーションの精度を高めるためには、より多くの画像を使用することが効果的です。

異なる角度や距離から撮影された画像を追加することで、カメラの内部パラメータや歪み係数の推定において、より安定した結果が得られます。

// 複数画像のコーナー検出と対応点の収集例
std::vector<std::vector<cv::Point3f>> objectPoints; // 3Dポイント
std::vector<std::vector<cv::Point2f>> imagePoints;  // 2Dコーナー点
// 画像リスト
std::vector<std::string> imageFiles = {"img1.jpg", "img2.jpg", "img3.jpg", ...};
for (const auto& filename : imageFiles) {
    cv::Mat img = cv::imread(filename);
    if (img.empty()) continue;
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    std::vector<cv::Point2f> corners;
    bool found = cv::findChessboardCorners(gray, patternSize, corners,
        cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE);
    if (found) {
        cv::cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1),
            cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.001));
        // 3Dポイントの追加
        objectPoints.push_back(objectPointsTemplate);
        // 2Dポイントの追加
        imagePoints.push_back(corners);
    }
}
// 追加画像を用いたキャリブレーション実行
double rmsError = cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);

複数の画像を用いることで、キャリブレーションの結果の信頼性と精度が向上します。

特に、異なる角度や距離からの画像を多く収集することが重要です。

パターン種類の変更とその影響

チェスボード以外にも、円形格子やアスティグマ(ARマーカー)などのパターンもキャリブレーションに利用できます。

パターンの種類を変更することで、検出の難易度や精度に影響を与えます。

  • 円形格子:コーナー検出が容易で、照明条件に対して比較的頑健です。ただし、円の中心点の検出精度に依存します
  • アスティグマ:高精度な位置検出が可能で、特に動的シーンや広範囲のキャリブレーションに適しています。ただし、専用の検出アルゴリズムが必要です

パターンの選択は、使用環境や目的に応じて最適なものを選びます。

例えば、屋外や動きの多いシーンでは、円形格子やアスティグマの方が適している場合があります。

// 例:円形格子パターンの検出
bool foundCircles = cv::findCirclesGrid(gray, patternSize, centers,
    cv::CALIB_CB_SYMMETRIC_GRID);

パターンの種類を変更することで、検出の成功率やキャリブレーションの精度に影響を与えるため、事前に十分な検証を行うことが重要です。

動的シーンにおけるリアルタイム補正

静止したシーンだけでなく、動的なシーンやリアルタイム映像に対しても歪み補正を行うことが求められる場合があります。

これには、キャリブレーション済みのパラメータを用いて、映像ストリームに対してリアルタイムで補正処理を適用します。

// カメラキャプチャの設定
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
    std::cerr << "カメラを開けません。" << std::endl;
    return -1;
}
// 事前にキャリブレーション済みのパラメータ
cv::Mat cameraMatrix, distCoeffs;
cv::FileStorage fs("calibration_params.yaml", cv::FileStorage::READ);
fs["cameraMatrix"] >> cameraMatrix;
fs["distCoeffs"] >> distCoeffs;
fs.release();
// マッピング関数の生成
cv::Mat map1, map2;
cv::Size frameSize(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
cv::initUndistortRectifyMap(cameraMatrix, distCoeffs, cv::Mat(), cameraMatrix, frameSize, CV_16SC2, map1, map2);
cv::Mat frame, undistortedFrame;
while (true) {
    cap >> frame;
    if (frame.empty()) break;
    // リアルタイム補正
    cv::remap(frame, undistortedFrame, map1, map2, cv::INTER_LINEAR);
    cv::imshow("歪み補正リアルタイム", undistortedFrame);
    if (cv::waitKey(1) == 27) break; // ESCキーで終了
}

この方法により、ライブ映像に対しても歪み補正をリアルタイムで適用でき、ロボットビジョンやARアプリケーションなどに応用できます。

追加画像を用いることでキャリブレーションの精度を向上させたり、パターンの種類を変更して検出の安定性や適用範囲を広げたり、リアルタイム処理に最適化したりといった応用と最適化が可能です。

これらの工夫により、さまざまな環境や用途に対応した高精度なキャリブレーションと画像補正を実現できます。

トラブルシューティング

コーナー検出失敗への対応

コーナー検出が失敗する原因はさまざまです。

まず、画像の品質やパターンの見やすさを確認します。

照明不足や反射、歪み、パターンの摩耗や汚れが原因となることが多いため、撮影条件を改善します。

  • 画像の明るさとコントラストを調整:適切な露出とコントラスト調整を行い、コーナーのコントラスト差を明確にします
  • 画像の前処理:ノイズ除去やシャープ化を行うことで、コーナー検出の成功率を向上させます
// 例:ノイズ除去とコントラスト調整
cv::Mat gray, denoised, contrastEnhanced;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
cv::fastNlMeansDenoising(gray, denoised);
cv::equalizeHist(denoised, contrastEnhanced);
  • パターンのサイズや角度を調整:パターンが見えにくい場合は、角度や距離を変えて複数の画像を撮影します
  • 検出パラメータの調整findChessboardCornersのフラグや閾値を変更し、検出の閾値を緩める
bool found = cv::findChessboardCorners(
    gray, patternSize, corners,
    cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE | cv::CALIB_CB_FAST_CHECK
);
  • 失敗した場合の再試行:検出に失敗した画像は除外し、成功した画像だけを用いてキャリブレーションを行います

過補正・低補正の対策

キャリブレーション結果において、過補正や低補正が生じる場合は、以下の対策を検討します。

  • 画像の多様性を増やす:異なる角度や距離からの画像を追加し、パターンの見え方のバリエーションを増やす
  • パターンのサイズや配置を見直す:パターンのサイズや配置を調整し、検出の安定性を高める
  • キャリブレーションの設定を調整cv::calibrateCameraのフラグや制約条件を変更し、パラメータの推定に影響を与えます
// 例:歪み係数の制約を設定
double rms = cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, cv::CALIB_FIX_K4 | cv::CALIB_FIX_K5);
  • 結果の再評価:再投影誤差や画像の歪み具合を確認し、必要に応じてパターンや画像を見直します

画像ノイズやぼけの影響を軽減

ノイズやぼけはコーナー検出やキャリブレーションの精度に悪影響を及ぼします。

これらを軽減するための方法は次の通りです。

  • 適切な撮影条件:十分な照明と安定したカメラ設定を行い、手ブレや反射を避けます
  • 画像の前処理
    • ノイズ除去:cv::fastNlMeansDenoisingcv::GaussianBlurを使用してノイズを除去します
    • シャープ化:cv::Laplaciancv::filter2Dを用いて画像のエッジを強調します
// 例:ガウシアンブラーによるノイズ除去
cv::GaussianBlur(gray, denoised, cv::Size(5, 5), 1.5);
  • 高解像度のカメラを使用:高解像度の画像は、ノイズの影響を受けにくくなります
  • 適切な焦点距離とレンズの選択:ぼけや歪みを最小限に抑えるために、レンズの特性に注意します

これらの対策を講じることで、ノイズやぼけによる検出失敗や誤差を軽減し、より正確なキャリブレーション結果を得ることが可能です。

まとめ

この記事では、OpenCVを用いたカメラキャリブレーションの基本手順と応用方法について解説しました。

パターンの準備やコーナー検出、パラメータ推定、歪み補正の実践的な手法を紹介し、精度向上やトラブル対策も詳述しています。

これらを理解することで、正確な画像補正や計測が可能となり、さまざまな応用シーンに役立てられます。

関連記事

Back to top button
目次へ