Skip to content

Instantly share code, notes, and snippets.

@TimSC
Last active March 9, 2022 17:10
Show Gist options
  • Save TimSC/bf14579149b4d36e3558 to your computer and use it in GitHub Desktop.
Save TimSC/bf14579149b4d36e3558 to your computer and use it in GitHub Desktop.
Hacked python camera calibration in opencv
import numpy as np
import cv2
import glob
import math
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
shape = (7,5)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((shape[0]*shape[1],3), np.float32)
objp[:,:2] = np.mgrid[0:shape[0],0:shape[1]].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('IMG*.jpg')
gray = None
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, shape, None)
print (fname, ret)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
imgpoints.append(corners)
#corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
#imgpoints.append(corners2)
# Draw and display the corners
cv2.drawChessboardCorners(img, shape, corners, ret)
cv2.imwrite('cal'+fname,img)
#cv2.destroyAllWindows()
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
print ("mtx", mtx)
print ("dist", dist)
img = cv2.imread(images[0])
h, w = img.shape[:2]
print ("(h, w)", (h, w))
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
print ("newcameramtx", newcameramtx)
print ("roi", roi)
# undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
cv2.imwrite('calibresult1.png',dst)
# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult2.png',dst)
#Reprojection error
tot_error = 0.0
tot_error_sq = 0.0
for i in range(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
tot_error += error
tot_error_sq += error * error
print ("mean absolute error: ", tot_error/len(objpoints))
print ("rms error: ", math.sqrt(tot_error_sq/len(objpoints)))
@Eyshika
Copy link

Eyshika commented Mar 27, 2019

I believe it should be tot_error += error*error

then print sqrt(tot_error/len(objpoints))

@vvolhejn
Copy link

Indeed it's wrong, it should be https://www.fatalerrors.org/a/0d511jg.html - then it matches ret from cv2.calibrateCamera.

@TimSC
Copy link
Author

TimSC commented Sep 10, 2021

I've tried to update the code based on comments and transition to python3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment