Changeset 494
- Timestamp:
- 05/20/09 00:15:57 (3 years ago)
- Location:
- trunk/software/scripts/calib
- Files:
-
- 2 modified
-
Makefile (modified) (1 diff)
-
calibrate.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/software/scripts/calib/Makefile
r493 r494 25 25 ctags -R 26 26 clean: 27 rm -f $(PROG) *.o *.so *.pyc core out*.jpeg *.out tags27 rm -f $(PROG) *.o *.so *.pyc core corners.*.jpg *.out tags -
trunk/software/scripts/calib/calibrate.c
r493 r494 1 2 3 4 1 5 #include <stdio.h> 6 #include <stdint.h> 2 7 3 8 #include <cv.h> … … 12 17 #define BOARD_COLS 9 13 18 19 // The size of the squares on the chessboard, in whatever units 20 // you want the calibration to be related to. 21 #define SQUARE_SIZE 1.0 22 23 // The size of the images from which you are calibrating. 24 #define IMAGE_WIDTH 2592 25 #define IMAGE_HEIGHT 1936 14 26 15 27 // Value for the flags argument of cvFindChessboardCorners 16 28 // for each image. This is some combination of 17 29 // CV_CALIB_CB_{ADAPTIVE_THRESH,NORMALIZE_IMAGE,FILTER_QUADS} 18 // -- experiment a bit to find what works for each image. 19 int CORNER_FLAGS[] = { 30 // -- experiment a bit to find what works for each image. The 31 // length of this array must match NUM_INPUTS. 32 int CORNER_FLAGS[NUM_INPUTS] = { 20 33 CV_CALIB_CB_FILTER_QUADS, 21 34 CV_CALIB_CB_ADAPTIVE_THRESH, … … 24 37 }; 25 38 39 40 41 // Print out a floating-point, single channel matrix 42 void print_matrix(CvMat *mat) 43 { 44 for (int r = 0; r < mat->rows; r++) { 45 for (int c = 0; c < mat->cols; c++) { 46 printf("%11.3f ", cvmGet(mat, r, c)); 47 } 48 printf("\n"); 49 } 50 } 51 52 26 53 int main(int argc, char* argv[]) 27 54 { 28 // Initialize the array of 3D points29 CvMat *corners_3d = cvCreateMat(3, BOARD_ROWS * BOARD_COLS, CV_32FC1);30 for (int row = 0; row < BOARD_ROWS; row++) {31 for (int col = 0; col < BOARD_COLS; col++) {32 int m_col = row * BOARD_ROWS + col;33 cvmSet(corners_3d, 0, m_col, row);34 cvmSet(corners_3d, 1, m_col, col);35 cvmSet(corners_3d, 2, m_col, 1);36 }37 }38 55 56 ///////// Find chessboard corners //////// 39 57 CvSize pattern_size = cvSize(BOARD_COLS, BOARD_ROWS); 40 58 59 // Find the chessboard corners 60 int success = 1; 61 int total_corners = BOARD_COLS * BOARD_ROWS * NUM_INPUTS; 62 CvPoint2D32f* corners = calloc(total_corners, sizeof(CvPoint2D32f)); 63 41 64 for (int i = 0; i < NUM_INPUTS; i++) { 42 65 // Figure out filenames and load the image … … 49 72 // Attempt to find the chessboard 50 73 int corner_count = 0; 51 CvPoint2D32f *corners = calloc(BOARD_ROWS * BOARD_COLS, sizeof(CvPoint2D32f)); 52 74 CvPoint2D32f* my_corners = corners + (BOARD_COLS * BOARD_ROWS * i); 53 75 int pattern_was_found = cvFindChessboardCorners(img, 54 76 pattern_size, 55 corners,77 my_corners, 56 78 &corner_count, 57 79 CORNER_FLAGS[i]); 58 cvDrawChessboardCorners(img, pattern_size, corners, corner_count, pattern_was_found); 59 80 cvDrawChessboardCorners(img, pattern_size, my_corners, corner_count, pattern_was_found); 60 81 cvSaveImage(out_fn, img); 61 82 cvReleaseImage(&img); 83 84 printf("%s for %s: found %d corners\n", (pattern_was_found ? "success" : "failure"), 85 in_fn, 86 corner_count); 87 if (!pattern_was_found) { 88 success = 0; 89 } 62 90 } 91 92 if (!success) { 93 printf("Didn't find all the corners. Try tweaking CORNER_FLAGS.\n"); 94 exit(1); 95 } 96 97 ///////// Calculate K ////////// 98 99 // Initialize the array of 3D coordinates 100 // We just set it to a grid, with the top left starting at (0, 0). 101 // There is no Z coordinate because we are using a planar calibration 102 // pattern. 103 CvMat *corners_3d = cvCreateMat(total_corners, 2, CV_32FC1); 104 for (int i = 0; i < NUM_INPUTS; i++) { 105 for (int row = 0; row < BOARD_ROWS; row++) { 106 for (int col = 0; col < BOARD_COLS; col++) { 107 int m_row = (i * BOARD_ROWS * BOARD_COLS) + (row * BOARD_ROWS) + col; 108 cvmSet(corners_3d, m_row, 0, row * SQUARE_SIZE); 109 cvmSet(corners_3d, m_row, 1, col * SQUARE_SIZE); 110 } 111 } 112 } 113 114 // Convert the array of 2D points to a matrix. 115 CvMat *corners_2d = cvCreateMat(total_corners, 2, CV_32FC1); 116 for (int row = 0; row < total_corners; row++) { 117 cvmSet(corners_2d, row, 0, corners[row].x); 118 cvmSet(corners_2d, row, 1, corners[row].y); 119 } 120 121 // point_counts is a vector that contains the number of points 122 // in each image. 123 int32_t *point_count_data = malloc(NUM_INPUTS * sizeof(int32_t)); 124 for (int i = 0; i < NUM_INPUTS; i++) { 125 point_count_data[i] = BOARD_ROWS * BOARD_COLS; 126 } 127 CvMat point_counts = cvMat(1, NUM_INPUTS, CV_32S, point_count_data); 128 129 // Output parameters 130 131 // K is the camera matrix. K_1,1 and K_2,2 contain the focal length 132 // and K_1,3 and K_2,3 contain the camera center, which should be half 133 // the image dimensions. 134 float K_data[] = {0.0, 0.0, IMAGE_WIDTH / 2.0, 135 0.0, 0.0, IMAGE_HEIGHT / 2.0, 136 0.0, 0.0, 1.0}; 137 CvMat K = cvMat(3, 3, CV_32FC1, &K_data); 138 printf("original K:\n"); 139 print_matrix(&K); 140 141 CvMat *distortion_coeffs = cvCreateMat(4, 1, CV_32FC1); 142 143 144 printf("calibrating...\n"); 145 cvCalibrateCamera2(corners_3d, 146 corners_2d, 147 &point_counts, 148 cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), 149 &K, 150 distortion_coeffs, 151 NULL, // rotation_vectors 152 NULL, // translation_vectors 153 0); 154 155 printf("\nK:\n"); 156 print_matrix(&K); 157 printf("\ndistortion_coeffs:\n"); 158 print_matrix(distortion_coeffs); 159 63 160 } 64

