#!/usr/bin/env python ''' This is a modified version of opencv's calibrate.py that stores the camera parameters in the YAML format required by ArUco. an example of this format is given by: %YAML:1.0 calibration_time: "Sa 08 Aug 2015 16:32:35 CEST" nr_of_frames: 30 image_width: 752 image_height: 480 board_width: 8 board_height: 6 square_size: 24. fix_aspect_ratio: 1. # flags: +fix_aspect_ratio +fix_principal_point +zero_tangent_dist flags: 14 camera_matrix: !!opencv-matrix rows: 3 cols: 3 dt: d data: [ 418.164617459, 0., 372.480325679, 0., 417.850564673, 229.985538918, 0., 0., 1.] distortion_coefficients: !!opencv-matrix rows: 5 cols: 1 dt: d data: [ -0.3107371474, 0.1187673445, -0.0002552599, -0.0001158436, -0.0233324616] (Reference: https://wiki.mpi-inf.mpg.de/d2/ArUco) How to use: - Copy and paste this in //samples/python2 - Run it like python calibrate_and_save.py --save "//camera.yml" "//*.png" - Then you can use ArUco like .//build/utils/aruco_test_gl live //camera.yml 0.039 More on calibration: http://www.janeriksolem.net/2014/05/how-to-calibrate-camera-with-opencv-and.html UPDATE: Alternatively, you can follow the steps below - After disabling integrated webcam: echo "0" > /sys/bus/usb/devices/2-1.6/bConfigurationValue (need to first find which usb device corresponds to your webcam) - Plug in pupil tracker and use the official precompiled cpp script like: //build/bin/cpp-example-calibration -w 8 -h 6 -s 0.039 -o camera.yml -op ''' import time import numpy as np import cv2, cv import os from common import splitfn def saveCameraParams(save_dir, nframes, w, h, bw, bh, square_size, camera_matrix, distortion_coefficients, fix_aspect_ratio = None, flags = 0): time_str = time.strftime('%a %d %b %Y %H:%M:%S %Z') lines = [] lines.append('%YAML:1.0') lines.append('calibration_time: "%s"' %time_str) lines.append('nframes: %s' %nframes) lines.append('image_width: %s' %w) lines.append('image_height: %s' %h) lines.append('board_width: %s' %bw) lines.append('board_height: %s' %bh) lines.append('square_size: %s' %square_size) if fix_aspect_ratio: lines.append('fix_aspect_ratio: %s' %fix_aspect_ratio) lines.append('flags: %s' %flags) lines.append('camera_matrix: !!opencv-matrix') lines.append(' rows: 3') lines.append(' cols: 3') lines.append(' dt: d') lines.append(' data: %s' %repr(camera_matrix.reshape(1,9)[0])[6:-1]) # [6:-1] removes "array(" and ")" lines.append('distortion_coefficients: !!opencv-matrix') lines.append(' rows: 5') lines.append(' cols: 1') lines.append(' dt: d') lines.append(' data: %s' %repr(distortion_coefficients)[6:-1]) with open(save_dir, 'w') as f: f.writelines(map(lambda l: l+'\n', lines)) def readCameraParams(cam_mat = None): ''' Reads an openCV camera.yml file and returns camera_matrix and distortion_coefficients ''' if not cam_mat: cam_mat = CAMERA_MATRIX data = ''.join(open(cam_mat.strip(), 'r').readlines()).replace('\n', '').lower() try: ind1 = data.index('[', data.index('camera_matrix')) ind2 = data.index(']', ind1) camera_matrix = eval(data[ind1:ind2+1]) camera_matrix = np.array([camera_matrix[:3], camera_matrix[3:6], camera_matrix[6:]]) ind1 = data.index('[', data.index('distortion_coefficients')) ind2 = data.index(']', ind1) dist_coeffs = np.array(eval(data[ind1:ind2+1])) return camera_matrix, dist_coeffs except Exception: print 'Could not load camera parameters' print 'Invalid camera.yml file.' if __name__ == '__main__': import sys, getopt from glob import glob 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/left*.jpg' # print 'mask is', img_mask # img_mask = img_mask.replace('10.png', '*.png') img_names = glob(img_mask) debug_dir = args.get('--debug') square_size = float(args.get('--square_size', 1.0)) square_size = 0.00122 save_dir = args.get('--save') pattern_size = (8, 6) 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 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: term = ( cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1 ) cv2.cornerSubPix(img, corners, (5, 5), (-1, -1), term) if debug_dir: vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2.drawChessboardCorners(vis, pattern_size, corners, found) path, name, ext = splitfn(fn) cv2.imwrite('%s/%s_chess.bmp' % (debug_dir, name), vis) if not found: print 'chessboard not found' continue img_points.append(corners.reshape(-1, 2)) obj_points.append(pattern_points) print 'ok' # rms, camera_matrix, dist_coefs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (w, h)) root_dir = '/home/mmbrian/Pictures/eye_camera_images/' cameraMatrixguess, distCoeffsguess = readCameraParams(os.path.join(root_dir,'_camera.yml')) print "cameraM: ", cameraMatrixguess print "dist: ", distCoeffsguess cameraMatrixguess[1][1] = cameraMatrixguess[0][0] cameraMatrixguess[0][2] = 320 cameraMatrixguess[1][2] = 180 # Calibrate camera intrinsics rms, camera_matrix, dist_coefs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (w,h), cameraMatrixguess, distCoeffsguess, None, None, flags = \ cv.CV_CALIB_USE_INTRINSIC_GUESS + cv.CV_CALIB_FIX_PRINCIPAL_POINT + cv.CV_CALIB_FIX_ASPECT_RATIO) np.save(os.path.join(root_dir,'dist.npy'), dist_coefs) np.save(os.path.join(root_dir,'cameraMatrix.npy'), camera_matrix) np.savetxt(os.path.join(root_dir,'dist.csv'),np.asarray(dist_coefs), delimiter=";", fmt="%s") np.savetxt(os.path.join(root_dir,"cameraMatrix.csv"),np.asarray(camera_matrix), delimiter=";", fmt="%s") print "RMS:", rms print "camera matrix:\n", camera_matrix print "distortion coefficients: ", dist_coefs.ravel() print 'Width:', w, 'Height:', h print 'nframes:', len(img_names) print 'square_size:', square_size print 'board_width:', pattern_size[0] print 'board_height:', pattern_size[1] saveCameraParams(save_dir, len(img_names), w, h, pattern_size[0], pattern_size[1], square_size, camera_matrix, dist_coefs.ravel()) print "Saved camera matrix to", save_dir cv2.destroyAllWindows()