홍든램지의 보일러실

카메라 내부파라미터와 cpp, python 코드 본문

AI 와 딥러닝

카메라 내부파라미터와 cpp, python 코드

예비보일 2023. 3. 8. 16:48
반응형

카메라의 내부 매개변수는 카메라가 2D 이미지 평면에 3D 점을 투영하는 방법을 설명하는 고유 매개변수를 나타냅니다. 이러한 매개변수에는 다음이 포함됩니다.

  1. 초점 거리(f): 렌즈가 무한대로 초점이 맞춰졌을 때 카메라 렌즈와 이미지 면 사이의 거리입니다. 이미지의 배율을 결정하고 이미지의 개체 크기에 영향을 줍니다.
  2. 주점(c): 카메라 렌즈의 광학 중심에 해당하는 이미지 평면의 점입니다. 광축과 이미지 평면의 교차점입니다.
  3. 왜곡 계수(s): 이것은 이미지 평면이 카메라의 광축에 대해 얼마나 비수직인지를 측정한 것입니다. 일반적으로 대부분의 카메라에서 0에 가깝습니다.
  4. 종횡비(a): 이미지의 너비와 높이의 비율입니다. 이미지의 개체 모양에 영향을 줍니다.
  5. 왜곡 계수: 이 매개변수는 이미지 포인트가 실제 위치에서 벗어나게 만드는 카메라 렌즈의 왜곡을 설명합니다. 일반적으로 두 가지 유형의 왜곡이 있습니다. 점이 이미지 중심에서 더 멀리 나타나게 하는 방사형 왜곡과 점이 기울어져 나타나게 하는 접선 왜곡입니다.

카메라 고유의 매개변수는 초점 거리, 주점, 스큐 계수 및 종횡비를 결합한 3x3 매트릭스인 카메라 매트릭스를 사용하여 나타낼 수 있습니다. 카메라 매트릭스는 종종 K로 표시됩니다.

왜곡 계수는 일반적으로 d로 표시되는 왜곡 벡터를 사용하여 나타낼 수 있습니다.

카메라의 내부 매개변수는 물체 감지, 3D 재구성 및 카메라 보정과 같은 많은 컴퓨터 비전 작업에 중요합니다. 이러한 매개변수를 정확하게 추정함으로써 이미지의 왜곡을 수정하고 3D 포인트를 해당 2D 이미지 포인트에 정확하게 매핑할 수 있습니다.

카메라 캘리브레이션이라고도 하는 카메라의 내부 매개변수를 얻는 프로세스에는 알려진 물체 또는 패턴의 일련의 이미지를 촬영하고 이미지를 사용하여 카메라의 고유 매개변수를 추정하는 작업이 포함됩니다. 다음은 OpenCV 및 Python을 사용하여 카메라를 보정하는 방법에 대한 단계별 가이드입니다.

  1. 이미지 캡처: 다양한 각도와 거리에서 알려진 개체 또는 패턴의 일련의 이미지를 캡처합니다. 이상적으로는 개체 또는 패턴에 컴퓨터 비전 알고리즘으로 쉽게 감지할 수 있는 구별 가능한 기능이 있어야 합니다.
  2. 모서리 감지: OpenCV의 모서리 감지 기능을 사용하여 각 이미지에서 패턴의 모서리를 감지합니다. 이는 cv2.findChessboardCorners() 또는 cv2.findCirclesGrid()와 같은 함수를 사용하여 수행할 수 있습니다.
  3. 보정 매개변수 계산: 감지된 모서리를 사용하여 초점 거리, 주점 및 왜곡 계수와 같은 카메라 고유 매개변수를 계산합니다. 이는 cv2.calibrateCamera() 또는 cv2.calibrateCameraExtended()와 같은 OpenCV의 보정 기능을 사용하여 수행할 수 있습니다.
  4. 보정 평가: cv2.calibrationMatrixValues() 또는 cv2.projectPoints()와 같은 OpenCV의 보정 평가 기능을 사용하여 보정의 정확성을 평가하고 필요한 조정을 수행합니다.

다음은 OpenCV를 사용하여 카메라를 보정하는 방법을 보여주는 Python 코드 예입니다.

 

import cv2

# Load images
img1 = cv2.imread('img1.jpg')
img2 = cv2.imread('img2.jpg')

# Define calibration pattern
pattern_size = (9, 6) # chessboard pattern
obj_points = [] # 3D points of pattern corners
img_points = [] # 2D points of pattern corners

# Detect corners in images
found1, corners1 = cv2.findChessboardCorners(img1, pattern_size)
found2, corners2 = cv2.findChessboardCorners(img2, pattern_size)

# Add points to lists if corners were detected
if found1 and found2:
    obj_points.append(np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32))
    obj_points[-1][:,:2] = np.mgrid[0:pattern_size[0],0:pattern_size[1]].T.reshape(-1,2)
    img_points.append(corners1)
    img_points.append(corners2)

# Calibrate camera
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, img1.shape[1::-1], None, None)

# Print intrinsic parameters
print("Camera Matrix:")
print(mtx)
print("Distortion Coefficients:")
print(dist)

 

cpp 예제

#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char** argv)
{
    // Load images
    Mat img1 = imread("img1.jpg");
    Mat img2 = imread("img2.jpg");

    // Define calibration pattern
    Size patternSize(9, 6); // chessboard pattern
    std::vector<std::vector<Point3f>> objectPoints; // 3D points of pattern corners
    std::vector<std::vector<Point2f>> imagePoints; // 2D points of pattern corners

    // Detect corners in images
    std::vector<Point2f> corners1, corners2;
    bool found1 = findChessboardCorners(img1, patternSize, corners1);
    bool found2 = findChessboardCorners(img2, patternSize, corners2);

    // Add points to lists if corners were detected
    if (found1 && found2)
    {
        std::vector<Point3f> obj;
        for (int i = 0; i < patternSize.height; i++)
            for (int j = 0; j < patternSize.width; j++)
                obj.push_back(Point3f(j, i, 0));
        objectPoints.push_back(obj);
        imagePoints.push_back(corners1);
        imagePoints.push_back(corners2);
    }

    // Calibrate camera
    Mat cameraMatrix, distCoeffs;
    std::vector<Mat> rvecs, tvecs;
    double rms = calibrateCamera(objectPoints, imagePoints, img1.size(), cameraMatrix, distCoeffs, rvecs, tvecs);

    // Print intrinsic parameters
    std::cout << "Camera Matrix:" << std::endl;
    std::cout << cameraMatrix << std::endl;
    std::cout << "Distortion Coefficients:" << std::endl;
    std::cout << distCoeffs << std::endl;

    return 0;
}

 

반응형
Comments