박민혀기

CMP Calibration 적용·검증 본문

CELLON Master Plan/Measurement of Dimensions

CMP Calibration 적용·검증

박민혀기 2023. 9. 7. 10:06

이전 포스팅에서 Calibration 매개변수 추출을 진행하였고, 이번에는 매개변수를 적용하고, 간단한 검증까지 해보려고 한다.

 

적용

적용 단계에서는 크게 두가지 단계가 있다.

  1. camera matrix와 distort coeff들로 transformation matrix값 추출
  2. transformation matrix를 이용하여 변환

이 두 개가 끝이다.

OpenCV에서는 위 두 가지를 한 번에 해주는 undistort() 함수를 제공한다.

하지만 1번 단계에서 transformation matrix 값은 보정 전과 후의 이미지 사이즈가 다르지 않다면 처음 한 번만 실행해주면 된다.(매번 실행시 속도 저하)

즉! undistort함수는 매번 쓸데없이 transformation matrix를 구하고 있다.

 

따라서 여기서는 initUndistortRectifyMap()함수로 camera matrix와 distort coeff이 두 값들을 구하하고, 프레임이 반복되는 구간에서는 remap()함수를 활용하여 변환한다.


검증

검증은 총 3가지 방법으로 이루어 졌다.

  1. Pixels Value Subtract
  2. MatchTemplate Compare
  3. Histogram Compare

결론부터 말하면 1번 방법이 가장 쉽고 좋은 검증 방법이었던 것 같다.

(2번이 가장 확실한 검증일 줄 알았는데..)

 

각각의 검증 방법은 소스코드에 주석으로 정리되어 있다.

 

1. Pixels Value Subtract(Good)

간단하게 변환 전 프레임과 변환 후 프레임을 빼준 값들을 이미지로 보여주면 된다.

만약 동일한 이미지일 경우 모든 픽셀이(0, 0, 0)일 것이고, 다르게 변환된 부분이 있다면

밝은 색으로 표현 될 것이다.

//Pixels Value Subtract
Mat result = frame - undistortedFrame;
imshow("result", result);

 

아래 결과를 보면 카메라 렌즈 특징인 중심부터 볼록한 형태로 왜곡된 걸 확인할 수 있다.(중심으로부터 멀어질 수록 차이가 커짐)

1
2

 

2. MatchTemplate Compare(??)

결과 값이 정상적으로 출력되지 않음.

다시 해봐야 될 듯.

 

3. Histogram Compare(Not Bad)

변환 전과 변환 후의 두 이미지를 Histogram를 비교하여 유사도 측정.

1에 가까울수록 동일한 이미지인데, 0.97~0.98 사이에서 측정됨.

하지만 1번과 다르게 이미지화 하기가 힘들고, 파라미터들 셋팅 값들도 설정 해줘야 한다.

 

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/calib3d.hpp>

using namespace std;
using namespace cv;

int main(){
        FileStorage fs("camera_calibration.xml", FileStorage::READ);
        Mat cameraMatrix, distortionCoeffs;

        fs["CameraMatrix"] >> cameraMatrix;
        fs["DistortionCoefficients"] >> distortionCoeffs;

        fs.release();

        Mat mapX, mapY;
        initUndistortRectifyMap(cameraMatrix, distortionCoeffs, Mat(), cameraMatrix,
                Size(640, 480), CV_32FC1, mapX, mapY);

        VideoCapture cap(0);
        if(!cap.isOpened()){
                cerr << "Could not open or find camera" << endl;
                return 0;
        }

        Mat frame, undistortedFrame;
        while(1){
                cap >> frame;
                if(frame.empty())       break;
                remap(frame, undistortedFrame, mapX, mapY, INTER_LINEAR);

                int key = waitKey(1);
                if(key == 27)   break;
                else if(key == 32){
//Pixels Subtract
                        Mat result = frame - undistortedFrame;
                        imshow("result", result);

//                      flip(undistortedFrame, undistortedFrame, 1);

//MatchTemplate Compare
/*                      Mat result;
                        double minVal, maxVal;
                        Point minLoc, maxLoc;
                        Point matchLoc;

                        matchTemplate(frame, undistortedFrame, result, 0);
                        normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
                        minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

                        cout << "Min value : " << minVal << endl;
                        cout << "Max value : " << maxVal << endl;

                        imshow("result", result);
*/

//Histogram Compare
/*                      int h_bins = 50, s_bins = 60;
                        int histSize[] = { h_bins, s_bins };
                        float h_range[] = { 0, 256 };
                        float s_range[] = { 0, 256 };
                        const float* ranges[] = { h_range, s_range };
                        MatND hist1, hist2;

                        int channels[] = { 0, 1 };
                        calcHist(&frame, 1, channels, Mat(), hist1, 2, histSize, ranges, true, false);
                        calcHist(&undistortedFrame, 1, channels, Mat(), hist2, 2, histSize, ranges, true, false);
*/

//                      double similarity = compareHist(hist1, hist2, HISTCMP_CORREL);
//                      cout << "Accuracy : " << similarity << endl;
                }

                imshow("Undistorted Frame", undistortedFrame);
                imshow("frame", frame);
        }

        cap.release();
        destroyAllWindows();

        return 0;
}

'CELLON Master Plan > Measurement of Dimensions' 카테고리의 다른 글

CMP Canny Object Detection  (0) 2023.09.13
CMP Calibration 매개변수 추출  (0) 2023.09.07