Rose-Hulman Robotics Team

Changeset 494

Show
Ignore:
Timestamp:
05/20/09 00:15:57 (3 years ago)
Author:
mosttw
Message:

Producing what looks like a reasonable K matrix!

Location:
trunk/software/scripts/calib
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/software/scripts/calib/Makefile

    r493 r494  
    2525        ctags -R 
    2626clean: 
    27         rm -f $(PROG) *.o *.so *.pyc core out*.jpeg *.out tags 
     27        rm -f $(PROG) *.o *.so *.pyc core corners.*.jpg *.out tags 
  • trunk/software/scripts/calib/calibrate.c

    r493 r494  
     1 
     2 
     3 
     4 
    15#include <stdio.h> 
     6#include <stdint.h> 
    27 
    38#include <cv.h> 
     
    1217#define BOARD_COLS 9 
    1318 
     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 
    1426 
    1527// Value for the flags argument of cvFindChessboardCorners 
    1628// for each image.  This is some combination of  
    1729// 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. 
     32int CORNER_FLAGS[NUM_INPUTS] = { 
    2033  CV_CALIB_CB_FILTER_QUADS, 
    2134  CV_CALIB_CB_ADAPTIVE_THRESH, 
     
    2437}; 
    2538 
     39 
     40 
     41// Print out a floating-point, single channel matrix 
     42void 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 
    2653int main(int argc, char* argv[]) 
    2754{ 
    28   // Initialize the array of 3D points 
    29   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   } 
    3855   
     56  ///////// Find chessboard corners //////// 
    3957  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   
    4164  for (int i = 0; i < NUM_INPUTS; i++) { 
    4265    // Figure out filenames and load the image 
     
    4972    // Attempt to find the chessboard 
    5073    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); 
    5375    int pattern_was_found = cvFindChessboardCorners(img, 
    5476                                                    pattern_size, 
    55                                                     corners, 
     77                                                    my_corners, 
    5678                                                    &corner_count, 
    5779                                                    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); 
    6081    cvSaveImage(out_fn, img); 
    6182    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    } 
    6290  } 
     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 
    63160} 
    64