马春杰杰 Exit Reader Mode

[mcj]利用python-opencv进行相机标定(多张图片,附完整代码及图片)

之前已经有一个用python-opencv做标定的程序,https://www.machunjie.com/visual/60.html

不过有点问题,只是单张图片而已,这次的程序是多个图片一起进行标定,结果会增加不少。

代码如下:

import numpy as np
import cv2
#import os
#import time
from matplotlib import pyplot as plt
LeftorRight = 'L'

numer = 9
chx = 6
chy = 9
chd = 25
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, numer, 0.001)

# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((chy*chx,3), np.float32)
objp[:,:2] = np.mgrid[0:chy,0:chx].T.reshape(-1,2)

# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space, (x25mm)
imgpoints = [] # 2d points in image plane.

enum = 1

while(enum<=numer):
    img=cv2.imread('left/left'+str(enum)+'.jpg')
    cv2.imshow("ww",img)
    #cv2.waitKey(0)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    # Find the chess board corners
    ret, corners = cv2.findChessboardCorners(gray, (chy,chx),None)
    #cv2.imshow('Calibration',img)

    # If found, add object points, image points (after refining them)
    if  ret == True and enum <= numer:

        objpoints.append(objp*chd)

        cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        imgpoints.append(corners)

        # Draw and display the corners
        cv2.drawChessboardCorners(img, (chy,chx),corners,ret)
        cv2.imshow('Calibration',img)
        cv2.imwrite('left/calibrated_L{0}.jpg'.format(enum),img)
        # print(enum)

        #time.sleep(2)
        # time.sleep(2)
        if enum == numer:
            ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

            img = cv2.imread('left/left'+str(enum)+'.jpg')
            gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
            h, w = img.shape[:2]  # a (1 to see the whole picture)
            newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))
            if (np.size(roi) == 4 and np.mean(roi) != 0):
                # undistort
                mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w, h), 5)
                dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)

                # crop the image
                x, y, w, h = roi
                dst = dst[y:y + h, x:x + w]
                dst = cv2.cvtColor(dst, cv2.COLOR_RGB2BGR)

                cv2.imwrite('result.jpg',dst)
                np.savetxt('mtxL.txt',mtx)
                np.savetxt('distL.txt',dist)
            else:
                np.disp('Something Went Wrong')
        enum += 1
'''
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break
'''
cv2.destroyAllWindows()

这里的result.jpg其实就是校准后的图像,可以看到,线条已经变的很直了。