I am trying to calibrate and find the location and rotation of one virtual camera in Blender 3d using homography. I use Blender to double check my results before moving into the real world, where it will be more difficult.
I took ten pictures of the chessboard in different places and turns in the field of view of my stationary camera. In OpenCV Python, I used cv2.calibrateCamera to find the internal matrix from the detected corners of the chessboard in ten images, and then used it in cv2.solvePnP to find the external parameters (translation and rotation).
However, although the estimated parameters were close to the actual, something suspicious is happening. My initial translation estimate was (-0.11205481,-0.0490256,8.13892491) . The actual location was (0,0,8.07105) . Pretty close, right?
But when I moved the camera a bit, rotated it and displayed the images again, the proposed translation went even further. Estimated: (-0.15933154,0.13367286,9.34058867) . In fact: (-1.7918,-1.51073,9.76597) . The value of Z is close, but X and Y are not.
I am completely baffled. If anyone can help me figure this out, I would really appreciate it. Here is the code (based on the Python2 calibration example that ships with OpenCV):
#imports left out USAGE = ''' USAGE: calib.py [--save <filename>] [--debug <output path>] [--square_size] [<image mask>] ''' args, img_mask = getopt.getopt(sys.argv[1:], '', ['save=', 'debug=', 'square_size=']) args = dict(args) try: img_mask = img_mask[0] except: img_mask = '../cpp/0*.png' img_names = glob(img_mask) debug_dir = args.get('--debug') square_size = float(args.get('--square_size', 1.0)) pattern_size = (5, 8) pattern_points = np.zeros( (np.prod(pattern_size), 3), np.float32 ) pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2) pattern_points *= square_size obj_points = [] img_points = [] h, w = 0, 0 count = 0 for fn in img_names: print 'processing %s...' % fn, img = cv2.imread(fn, 0) h, w = img.shape[:2] found, corners = cv2.findChessboardCorners(img, pattern_size) if found: if count == 0: