Reputation: 89
I am trying to calibrate a camera in python with the chessboard method.
This is the code I am using:
import numpy as np
import cv2
import glob
x = 3
y = 3
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((y*x,3), np.float32)
objp[:,:2] = np.mgrid[0:x,0:y].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('*.jpg')
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, (x,y),None)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
# Draw and display the corners
img = cv2.drawChessboardCorners(img, (x,y), corners2,ret)
cv2.imshow('img', img)
cv2.waitKey(500)
cv2.destroyAllWindows()
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
img = cv2.imread('pic0.jpg')
h, w = img.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# 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]
cv2.imwrite('calibresult.png',dst)
x and y are used for the size of the pattern.
This is the image I am working with.
The findChessboardCorners method seems to be unable to find a chessboard pattern beyond the size of 3x3. I already tried to binarize the image and to increase the contrast but I am unable to retrieve a bigger pattern.
Is the image I am working with too bad or am I doing something wrong?
Upvotes: 0
Views: 1446
Reputation: 4279
The (x,y)
in
cv2.findChessboardCorners(gray, (x,y),None)
is the shape of your board, which you specified as 3 by 3
reading the documentation I can see that you are supposed to count inner corners (where the black squares touch) so your board is actually (14,6)
Upvotes: 1
Reputation: 83
As Nullman says, you are defining the size of the chessboard inner corners as 3x3. In the sample image you provided, the inner corner size is 14x6. Therefore, the code would be:
ret, corners = cv2.findChessboardCorners(gray, (14,6),None)
Upvotes: 1