Fisheye 카메라의 외부 매개변수 계산

주로 cv::solvepnp 및 cv::solvePnPRansac을 사용하거나 보정하여 카메라 외부 매개변수를 해결하지만 어안 카메라의 외부 매개변수 계산을 호출합니다.

참조 링크:

(185 메시지) 어안 카메라의 외부 매개변수 계산 및 이미지의 원근 변환_어안 카메라의 외부 매개변수 해결_Mega_Li's Blog-CSDN Blog

나:

당신은 opencv 전문가입니다. fisheye 카메라의 외부 매개 변수를 계산하고 C++ 코드로 구현하는 방법을 가르쳐주십시오.

openai(chatgpt4):

어안 카메라의 외부 매개변수를 계산하려면 카메라 보정과 포즈 추정의 두 단계가 필요합니다. 다음은 몇 가지 기본 단계와 C++ 코드 구현입니다.

1. 카메라 보정

카메라 보정은 카메라의 고유 매개변수와 왜곡 계수를 추정하는 프로세스입니다. 이는 알려진 3D 세계 좌표와 해당 2D 이미지 좌표로 일련의 이미지를 촬영하여 달성할 수 있습니다. OpenCV는 어안 카메라를 보정하는 기능을 제공합니다 cv::fisheye::calibrate(). 샘플 코드는 다음과 같습니다.

cv::매트 카메라매트릭스, distCoeffs;
std::vector<std::vector<cv::Point3f>> objectPoints;
std::vector<std::vector<cv::Point2f>> imagePoints;
cv::크기 이미지 크기;
double rms = cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, cv::noArray(), cv::noArray());

그 중 캘리브레이션 플레이트의 모든 3차원 점의 좌표를 포함하는 objectPointsone 캘리브레이션 이미지에서 이러한 점의 2차원 좌표를 포함하는 one 이 있습니다. 보정 이미지의 크기입니다. 출력 카메라 고유 매개 변수 및 왜곡 계수입니다 . 교정 결과에서 계산된 교정 오류입니다.vector<vector<Point3f>>imagePointsvector<vector<Point2f>>imageSizecameraMatrixdistCoeffsrms

2. 포즈 추정

포즈 추정은 카메라를 초기 위치에서 새로운 위치로 이동하고 해당 위치에서 카메라의 회전 및 이동을 결정합니다. 여기서 포즈 추정을 위해 OpenCV의 solvePnP 함수를 사용할 수 있습니다. 샘플 코드는 다음과 같습니다.

cv::매트 rvec, tvec;
std::vector<cv::Point3f> objectPoints3D;
std::vector<cv::Point2f> imagePoints2D;
cv::매트 카메라매트릭스, distCoeffs;
cv::fisheye::projectPoints(objectPoints3D, rvec, tvec, cameraMatrix, distCoeffs, imagePoints2D);

objectPoints3D중에는 vector<Point3f>보정판의 3차원 점 좌표를 포함하는 와 현재 이미지에서 이러한 점의 2차원 좌표를 포함하는 가 imagePoints2D있습니다 . 카메라 보정에서 얻은 카메라 고유 매개 변수 및 왜곡 계수입니다 . 출력 회전 벡터 및 변환 벡터입니다 .vector<Point2f>cameraMatrixdistCoeffsrvectvec

solvePnP 함수를 사용하여 회전 벡터와 이동 벡터를 얻을 수 있습니다. 이를 회전 행렬과 평행 이동 행렬로 변환하면 카메라의 외부 매개변수를 얻을 수 있습니다. 샘플 코드는 다음과 같습니다.

cv::매트 R;
cv::Rodrigues(rvec, R);
이력서::매트 T = tvec;
 

3. 어안 카메라의 외부 매개변수 계산은 다음 단계로 나눌 수 있습니다.

1) 어안 카메라의 내부 매개변수와 왜곡 매개변수를 보정합니다. 이 단계는 OpenCV의 함수를 사용하여 수행할 수 있습니다 calibrateCamera.

2) 어안 카메라의 이미지를 수집하고 모서리 감지 알고리즘(예: findChessboardCornersOpenCV의 기능)을 사용하여 보정 보드의 모서리를 감지합니다.

3) 보정 보드의 알려진 공간 포인트와 해당 이미지 포인트에 따라 어안 카메라의 외부 매개변수를 계산합니다. 이 단계는 OpenCV의 함수를 사용하여 수행할 수 있습니다 solvePnP.

4) 얻어진 회전 벡터와 병진 벡터를 회전 행렬과 병진 행렬로 변환하여 어안 카메라의 외부 매개변수 행렬을 얻는다.

다음은 C++ 코드에서 위의 단계를 구현하는 예입니다.

#include <opencv2/opencv.hpp>
#include <iostream>

네임스페이스 표준 사용;
네임스페이스 cv 사용;

int main()
{     // 캘리브레이션 보드 이미지 읽기     Mat boardImg = imread("board.png");     // 캘리브레이션 보드 크기 및 공간 포인트 좌표 설정     Size boardSize = Size(9, 6);     vector<Point3f> objectPoints ;     for (int i = 0; i < boardSize.height; i++)     {         for (int j = 0; j < boardSize.width; j++)         {             objectPoints.push_back(Point3f(i, j, 0));         }     }











    // 标定相机内参和畸变参数
    Mat cameraMatrix, distCoeffs;
    벡터<벡터<Point2f>> imagePoints;
    vector<Mat> rvecs, tvecs;
    vector<float> reprojErrs;
    double rms = calibrateCamera(vector<vector<Point3f>>{objectPoints}, vector<vector<Point2f>>{imagePoints},
        boardImg.size(), cameraMatrix, distCoeffs, rvecs, tvecs);


    // 캘리브레이션 보드 벡터<Point2f> 코너     의 코너 감지
    bool found = findChessboardCorners(boardImg, boardSize, corners);

    // 카메라 외부 매개변수 계산
    Mat rvec, tvec;
    solvePnP(objectPoints, corners, cameraMatrix, distCoeffs, rvec, tvec);

    // 회전 및 이동 벡터를 회전 및 이동 행렬로 변환
    Mat R;
    Rodrigues(rvec, R);
    Mat T = tvec.reshape(1, 3);

    // 카메라의 외부 행렬
    Mat 가져오기 extrinsicMat = Mat::eye(4, 4, CV_32F);
    R.copyTo(extrinsicMat(Rect(0, 0, 3, 3)));
    T.copyTo(extrinsicMat(Rect( 3 , 0, 1, 3)));

    cout << "카메라 내부 매개변수:" << endl << cameraMatrix << endl;
    cout << "카메라 왜곡 매개변수: " << endl << distCoeffs << endl;
    cout << "카메라 외부 매개변수:" << endl < < 외부 매트 << endl;

    0을 반환합니다.
}

4. 어안 카메라의 외부 매개변수 계산은 다음 단계로 나눌 수 있습니다.

1) 이미지와 해당 3D 좌표를 획득합니다. 보정 플레이트와 알려진 3D 좌표를 사용하여 여러 이미지와 해당 3D 좌표를 얻을 수 있습니다.

2) 카메라 보정을 수행하여 내부 참조 매트릭스 및 왜곡 계수를 얻습니다. 이는 OpenCV의 calibrateCamera 기능을 사용하여 달성할 수 있습니다.

3) 다시점 기하학 이론을 통해 3차원 좌표를 카메라 좌표계로 변환한다.

4) 외부 매개변수 행렬을 풀어 카메라 좌표계의 3D 점을 세계 좌표계로 변환합니다.

다음은 어안 카메라의 외부 매개변수를 계산하기 위해 C++로 구현된 샘플 코드입니다.

#include <iostream>
#include <opencv2/opencv.hpp>

네임스페이스 표준 사용;
네임스페이스 cv 사용;

int main()
{     // 캘리브레이션 보드 이미지와 해당 3D 좌표 읽기     vector<vector<Point3f>> objectPoints;     vector<vector<Point2f>> imagePoints;     // ...



    // 카메라 캘리브레이션 수행
    Mat cameraMatrix, distCoeffs;
    vector<Mat> rvecs, tvecs;
    calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);

    // 3D 포인트와 2D 포인트 정의
    vector<Point3f> objectPoints3D;
    vector<Point2f> imagePoints2D;
    // ...

    // 3D 점을 카메라 좌표계로 변환
    Mat objectPointsMat(objectPoints3D);
    Mat rvec, tvec;
    solvePnP(objectPointsMat, imagePoints2D, cameraMatrix, distCoeffs, rvec, tvec);

    // 카메라 좌표계의 3D 점을 세계 좌표계로 변환
    Mat R;
    Rodrigues(rvec, R);
    Mat extrinsicMat(3, 4, CV_64FC1);
    hconcat(R, tvec, extrinsicMat);

    // 외부 행렬 출력
    cout << extrinsicMat << endl;

    0을 반환합니다.
}
 

그 중 solvePnP 함수는 외부 매개변수 행렬을 풀기 위해 사용되고, Rodrigues 함수는 회전 벡터를 회전 행렬로 변환하는 데 사용되며, hconcat 함수는 회전 행렬과 병진 벡터를 결합하여 3×4 외부 행렬로 변환하는 데 사용됩니다. 매개변수 행렬. 실제 상황에 따라 코드의 변수와 매개변수를 수정하십시오.

5 어안 카메라의 외부 매개변수를 계산하려면 다음 단계가 필요합니다.

1) 초점 거리, 주점 및 왜곡 계수와 같은 매개 변수를 포함하여 카메라의 내부 참조 행렬을 계산합니다. 이러한 매개변수는 일반적으로 카메라 제조업체 또는 카메라 보정에서 제공하는 문서를 통해 얻을 수 있습니다.

2) 최소 4개의 서로 다른 위치에서 이미지를 수집하고 각 위치는 서로 다른 방향에서 최소 3개의 이미지를 가져와야 합니다. 이러한 이미지를 사용하여 카메라의 외재성을 계산할 수 있습니다.

3) 각 이미지에서 특징점을 추출하기 위해 ORB나 SURF와 같은 특징점 검출 알고리즘을 사용할 수 있다.

4) 각 특징점에 대해 어안 모델을 통해 구형 표면에 투영합니다. 자세한 내용은 OpenCV의 fisheye 모듈을 참조하십시오.

5) RANSAC과 같은 알고리즘을 사용하여 각 이미지의 외부 매개변수를 추정합니다. 자세한 내용은 OpenCV의 solvePnP 기능을 참조하십시오.

6) 모든 이미지의 외부 매개변수를 결합하고 Bundle Adjustment와 같은 알고리즘을 사용하여 결과를 최적화합니다.

다음은 어안 카메라의 외부 매개변수를 계산할 수 있는 간단한 C++ 코드 예제입니다.

#include <iostream>
#include <벡터>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/core/types.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/core/eigen.hpp>

네임스페이스 표준 사용;
네임스페이스 cv 사용;
using namespace cv::xfeatures2d;

void calculateExtrinsics(const vector<vector<Point2f>>& imagePoints,
                         const vector<vector<Point3f>>& objectPoints,
                         const Mat& cameraMatrix,
                         const Mat& distCoeffs,
                         Mat& R,
                         Mat& t)
{     vector<Mat> rvecs, tvecs;     solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvecs, tvecs);     로드리게스(rvecs[0], R);     t = tvecs[0]; }




int main()
{     // 이미지와 해당 객체 포인트를 로드합니다     . vector<vector<Point2f>> imagePoints;     벡터<벡터<Point3f>> objectPoints;     // TODO: 파일에서 imagePoints 및 objectPoints 로드 또는 카메라에서 캡처



    // 카메라 매트릭스 및 왜곡 계수 계산
    Mat cameraMatrix, distCoeffs;
    // TODO: 보정 데이터를 사용하여 cameraMatrix 및 distCoeffs를 계산합니다.

    // 각 이미지에 대한 외인성 계산
    vector<Mat> Rs, ts;
    for (int i = 0; i < imagePoints.size(); i++) {         Mat R, t;         calculateExtrinsics(imagePoints[i], objectPoints, cameraMatrix, distCoeffs, R, t);         Rs.push_back(R);         ts.push_back(t);     }




    // 외부 기능을 개선하기 위한 번들 조정
    TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, 100, 1e-5);
    벡터<Mat> Rs_opt, ts_opt;
    벡터<벡터<Point2f>> imagePoints_opt;
    bundleAdjustment(objectPoints, imagePoints, cameraMatrix, distCoeffs, Rs, ts, Rs_opt, ts_opt, imagePoints_opt, criteria);

    // 결과 출력
    (int i = 0; i < Rs_opt.size(); i++) { 5.
       

어안 카메라의 외부 매개변수를 계산하려면 카메라의 내부 매개변수와 일부 알려진 장면 정보를 알아야 합니다. 다음은 C++에서 어안 카메라의 외부 매개변수 계산을 실현하는 단계입니다.

1) 이미지를 로드하고 이미지의 특징점을 추출합니다. OpenCV에서 cv::KeyPoint 및 cv::FeatureDetector를 사용하여 이미지의 특징점을 추출할 수 있습니다.

2) 장면에서 알려진 여러 3D 점을 선택하고 카메라 좌표계에서 좌표를 계산합니다. 이러한 3D 포인트는 정적이어야 하며 카메라에 표시되어야 합니다. OpenCV의 cv::solvePnP 함수를 사용하여 카메라 좌표계와 이미지 좌표계 간의 변환 관계 즉, 카메라의 외부 매개변수를 계산할 수 있습니다.

3) 카메라의 왜곡 매개변수를 계산합니다. OpenCV의 cv::calibrateCamera 함수를 사용하여 카메라의 내부 매개변수 및 왜곡 매개변수를 계산할 수 있습니다. 알려진 3D 포인트 세트와 이미지의 프로젝션, 카메라의 내부 매개변수를 제공해야 합니다.

4) 카메라의 내부 및 외부 매개변수를 결합하여 카메라의 투영 매트릭스를 얻습니다.

5) 카메라의 프로젝션 매트릭스를 이용하여 장면의 3D 포인트를 이미지에 투영하고 실제 추출된 특징점과 매칭한다. OpenCV의 cv::findHomography 함수를 사용하여 카메라의 투영 행렬과 특징점 간의 변환 관계를 계산할 수 있습니다.

다음은 어안 카메라의 외부 매개변수를 계산하기 위한 샘플 코드입니다.

#include <opencv2/opencv.hpp>

네임스페이스 cv 사용;

int main()
{     // 이미지 로드     Mat image = imread("image.jpg");

    // 이미지에서 특징점 추출
    Ptr<FeatureDetector> detector = FastFeatureDetector::create();
    std::vector<KeyPoint> keypoints;
    detector->detect(image, keypoints);

    // 장면에서 알려진 여러 3D 점 선택
    std::vector<Point3f> objectPoints;
    objectPoints.push_back(Point3f(0, 0, 0));
    objectPoints.push_back(Point3f(1, 0, 0));
    objectPoints.push_back (Point3f(0, 1, 0));
    objectPoints.push_back(Point3f(0, 0, 1));

    // 카메라의 외부 매개변수 계산
    Mat cameraMatrix = Mat::eye(3, 3, CV_64F); // 카메라 내부 매개변수
    Mat distCoeffs = Mat::zeros(1, 5, CV_64F); // 왜곡 매개변수
    Mat rvec, tvec ;
    solvePnP(objectPoints, keypoints, cameraMatrix, distCoeffs, rvec, tvec);

    // 카메라의 투영 행렬 계산
    Mat R;
    Rodrigues(rvec, R);
    Mat projectionMatrix = Mat::zeros(3, 4, CV_64F);
    hconcat(R, tvec, projectionMatrix.rowRange(0, 3).colRange(0 , 4));

    // 3D 포인트를 그래프에 투영
 

6.

어안 카메라의 외부 매개변수를 계산하기 위해서는 먼저 카메라의 내부 매개변수와 왜곡 계수를 구해야 하며, 이러한 매개변수는 카메라 보정을 통해 얻을 수 있다. 이러한 매개변수를 얻었다고 가정하면 OpenCV 라이브러리의 함수를 사용하여 어안 카메라의 외부 매개변수를 계산할 수 있습니다.

먼저 2D 포인트와 3D ​​포인트 사이의 대응 세트를 최소 6세트 준비해야 합니다. 이러한 대응은 다른 알고리즘(예: SIFT, SURF 등)에 의해 감지된 특징점을 수동으로 표시하거나 사용하여 얻을 수 있습니다. 여기서는 이러한 대응 관계가 이미 존재한다고 가정합니다.

다음은 OpenCV 라이브러리 함수를 사용하여 어안 카메라의 외부 매개변수를 계산하는 샘플 코드입니다.

#include <opencv2/opencv.hpp>
#include <iostream>

네임스페이스 표준 사용;
네임스페이스 cv 사용;

int main()
{     // 카메라 내부 파라미터 및 왜곡 계수 읽기     Mat K, D;     FileStorage fs("calibration.xml", FileStorage::READ);     fs["K"] >> K;     fs["D"] >>D;




    // 3D 포인트와 2D 포인트 간의 대응 관계 읽기
    vector<Point3f> objectPoints;
    vector<Point2f> imagePoints;
    FileStorage fs2("points.xml", FileStorage::READ);
    fs2["objectPoints"] >> objectPoints;
    fs2[ "imagePoints"] >> 이미지포인트;

    // 외부 매개변수 계산
    Mat rvec, tvec;
    solvePnP(objectPoints, imagePoints, K, D, rvec, tvec);

    // 회전 벡터와 이동 벡터 출력
    cout << "회전 벡터: " << rvec << endl;
    cout << "변환 벡터: " << tvec << endl;

    0을 반환합니다.
}

이 샘플 코드에서는 먼저 카메라의 내부 매개변수와 왜곡 계수를 읽은 다음 3D 포인트와 2D 포인트 간의 대응 관계를 읽습니다. 다음으로 OpenCV의 함수를 사용하여 solvePnP카메라의 외부 매개변수를 계산하고 마지막으로 회전 벡터와 변환 벡터를 출력합니다.

카메라 내부 매개변수와 왜곡 계수 및 3D 포인트와 2D 포인트 간의 해당 관계를 읽을 때 자신의 파일 형식에 따라 수정해야 합니다. 또한 어안 카메라의 왜곡이 상대적으로 크기 때문에 외부 매개변수를 계산하기 위해 최소 10세트의 대응을 사용하는 것이 좋습니다.

요약하다:

어안 카메라의 외부 매개변수를 찾기 전에 어안 카메라의 내부 매개변수 + 왜곡 매개변수를 결정해야 합니다. solvePnP 인터페이스를 사용하여 3d 좌표, 2d 좌표, 내부 매개변수 + 왜곡 매개변수를 사용하여 어안 카메라의 외부 매개변수를 찾거나 먼저 undistortPoints를 사용하여 내부 매개변수 + 왜곡 매개변수를 사용하여 2d 좌표를 먼저 왜곡 해제할 수 있습니다. 그런 다음 왜곡되지 않은 2d 좌표와 3d 좌표를 사용합니다. solvePnP 인터페이스를 통해 어안 카메라의 외부 매개변수를 찾습니다.

추천

출처blog.csdn.net/Fan0920/article/details/129438433