ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • camera calibration
    영상처리/Camera Calibration 2022. 12. 10. 23:40
    728x90

    camera calibration 코드를 아래와 같이 구현하였다.

    (전체 frame work은 https://learnopencv.com/camera-calibration-using-opencv/ 이곳을 참조하였다)

    (scipy의 rotation은 Rodriguess vector를 euler로 보기편하게 바꾸기 위해 import 하였다)

     

    import cv2
    import numpy as np
    from scipy.spatial.transform import Rotation
    
    # image load
    image_stack = []
    image_stack =image_stack+ [cv2.imread('test/20221125_210056.jpg')]
    image_stack =image_stack+ [cv2.imread('test/20221125_210103.jpg')]
    
    # Defining the dimensions of checkerboard
    wc = 10
    hc = 7
    CHECKERBOARD = (wc, hc)
    
    # Creating vector to store vectors of 3D points for each checkerboard image
    objpoints = []
    # Creating vector to store vectors of 2D points for each checkerboard image
    imgpoints = []
    
    # Defining the world coordinates for 3D points
    objp = np.zeros((1, CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32)
    objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
    objp =objp*25 # real size of the pattern is multiplied. (25mm)
    
    for image in image_stack:
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
        ret, corners = cv2.findChessboardCorners(gray, (10, 7), None)
        if ret ==True:
            objpoints.append(objp)
            criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
            corners2 = cv2.cornerSubPix(gray,corners, (11,11),(-1,-1),criteria)
            imgpoints.append(corners2)
            print(corners2)
            cv2.drawChessboardCorners(image,(wc,hc),corners2,ret)
    
        im_resized=cv2.resize(image,(1000,1000))
        cv2.imshow('im_dot',im_resized)
        cv2.waitKey(0)
    
    h,w = image.shape[:2]
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
    
    print("Camera matrix : \n")
    print(mtx)
    print("dist : \n")
    print(dist)
    print("rvecs : \n")
    print(rvecs)
    
    euler_angles=[(Rotation.from_rotvec(np.reshape(rvec,(3,)))).as_euler('xyz') for rvec in rvecs]
    print(euler_angles)
    print("tvecs : \n")
    print(tvecs)

    사용한 image와 checkerboard, 좌표 scheme은 아래와 같다. (두 장 찍었다...)

    첫번째 image와 camera 좌표, world 좌표이다. 카메라 좌표는 opencv에서 오른쪽과 아래를 각 x,y축으로 설정한다. world는 내가 놓은 pattern의 방향이 180° 회전하여 있었다...ㅠ
    카메라를 옆에서 tilt하여 찍은 영상

    위의 코드의 결과는 아래와 같다.

    Camera matrix : 
    
    [[1.55886092e+03 0.00000000e+00 1.44960326e+03]
     [0.00000000e+00 1.56194338e+03 1.51739150e+03]
     [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
    dist : 
    
    [[ 0.00248049 -0.02369158  0.00338128  0.00027106  0.02457948]]
    rvecs : 
    
    (array([[-0.04265218],
           [-0.2304544 ],
           [-3.12405447]]), array([[-0.55392259],
           [ 0.00740088],
           [ 3.03685208]]))
    [array([ 0.1471751 , -0.02780024, -3.13485831]), array([-0.00543348,  0.36069007,  3.08507378])]
    tvecs : 
    
    (array([[130.88752492],
           [ 89.24066989],
           [201.13685001]]), array([[155.29332579],
           [ 62.36786661],
           [194.59657592]]))
    
    Process finished with exit code 0

    camera matrix와 distortion parameter가 출력되었지만, 두장만 가지고 정확하길 기대하긴 어려울듯하다.

     

    rvecs가 잘 나왔는지 보겠다.

    rvec을 통해, 계산한 euler angle을 보면, z축에 pi에 가까운 회전이 있다. (내가 패턴을 뒤집어놓아서...)

    첫째 image는 z에만 회전이 크게 있지만, 두번째 이미지는 y축에 0.36radian(20°정도)의 회전이 보인다.

     

    728x90

    '영상처리 > Camera Calibration' 카테고리의 다른 글

    reprojection error (camera calibration)  (0) 2023.03.03
    checkerboard corner detector  (0) 2022.12.01
    camera calibration pattern 생성  (0) 2022.11.25
Designed by Tistory.