opencv关于摄像机标定的一段代码

    技术2022-05-20  28

    网上没有现成的,OPENCV也没有提供完整的示例,自己整理了一下,贴出来记录。

    但是这里cvFindChessboardCorners非常不稳定,不能工作, 是否要自己写呢?

    #include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <string.h>// OpenCV#include <cxcore.h>#include <cv.h>#include <highgui.h>#include <cvaux.h>

    void InitCorners3D(CvMat *Corners3D, CvSize ChessBoardSize, int Nimages, float SquareSize);

    /* uncomment the following to drop frames to prevent delays */#define DROP_FRAMES 1#define MAX_PORTS 3#define MAX_CAMERAS 1#define NUM_BUFFERS 8

    /* declarations for OpenCV */IplImage                 *current_frame_rgb,grid;IplImage                 *current_frame_gray;IplImage                 *readOnlyImg;

    int                       freeze = 0;

    int image_width = 640;int image_height = 480;

    bool                      verbose = false;

    // Calibration stuffbool   calibration_done = false;const CvSize    ChessBoardSize = cvSize(4,4);float    SquareWidth = 101.6f; //in millimetersconst int    NImages = 20; //Number of images to collectconst   int NPoints = 4*4;

    CvMat *intrinsics;CvMat *distortion_coeff;CvMat *rotation_vectors;CvMat *translation_vectors;CvMat *object_points;CvMat *point_counts;CvMat *image_points;

    intmain(int argc, char *argv[]){

      int counter = 0;  int find_corners_result = 0;  int captured_frames = 0;

      CvPoint2D32f corners[NImages*NPoints];  int corner_count[NImages];

      CvFont font;  cvInitFont( &font, CV_FONT_VECTOR0,5, 5, 0, 7, 8);    intrinsics   = cvCreateMat(3,3,CV_32FC1);  distortion_coeff  = cvCreateMat(1,4,CV_32FC1);  rotation_vectors  = cvCreateMat(NImages,3,CV_32FC1);  translation_vectors  = cvCreateMat(NImages,3,CV_32FC1);

      point_counts   = cvCreateMat(NImages,1,CV_32SC1);

      object_points  = cvCreateMat(NImages*NPoints,3,CV_32FC1);  image_points   = cvCreateMat(NImages*NPoints,2,CV_32FC1);

      // Function to fill in the real-world points of the checkerboard  InitCorners3D(object_points, ChessBoardSize, NImages, SquareWidth);

          CvCapture* capture = 0;        if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))        capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );    else if( argc == 2 )        capture = cvCaptureFromAVI( argv[1] );

        if( !capture )    {        fprintf(stderr,"Could not initialize capturing.../n");        return -1;    }    // Initialize all of the IplImage structures  current_frame_rgb = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);  IplImage *current_frame_rgb2 = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);  current_frame_gray = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 1);  readOnlyImg   = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);  IplImage *tempimg = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 1);  CvScalar e;  e.val[0] =1.0;  cvSet(tempimg,e,0);

      /* make the window */  //cvZero(readOnlyImg);  e.val[0] =255;  e.val[1] =255;  e.val[2] =255;  cvSet(readOnlyImg,e,0);  for(int i = 0;i<ChessBoardSize.width;i++)   for(int j = 0;j<ChessBoardSize.height;j++)   {    int w =image_width/(ChessBoardSize.width);    int h = image_height/(ChessBoardSize.height);

      if((i+j)%2==1)     cvRectangle( readOnlyImg, cvPoint(w*i,h*j),cvPoint(w*(i+1)-1,h*(j+1)-1), CV_RGB(0,0,0),CV_FILLED, 8, 0 );   }

      cvNamedWindow( "grid", 0);  cvNamedWindow( "Window 0", 0);    cvResizeWindow( "grid", 500,500);  cvMoveWindow("Window 0", 100, 100);

      printf("WHEN THE COUNTER HITS 20, YOU'RE DONE /n");

      while (!calibration_done)  {    while (captured_frames < NImages)    {      if (verbose) printf("%d /n", counter);      counter++;

     

       current_frame_rgb = cvQueryFrame( capture );   //current_frame_rgb = cvLoadImage( "c://BoardStereoL3.jpg" );

       if( !current_frame_rgb )    break;

         cvCvtColor(current_frame_rgb, current_frame_gray, CV_BGR2GRAY);

     //cvMul(current_frame_gray,tempimg,current_frame_gray,1.5); //cvAdaptiveThreshold( current_frame_gray, current_frame_gray,255,CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 5 );  //cvThreshold( current_frame_gray, current_frame_gray,90,255,CV_THRESH_BINARY_INV); //cvThreshold( current_frame_gray, current_frame_gray,90,255,CV_THRESH_BINARY);

     int pos = 1; IplConvKernel* element = 0; const int element_shape = CV_SHAPE_ELLIPSE; element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, 0 ); cvDilate(current_frame_gray,current_frame_gray,element,1); cvErode(current_frame_gray,current_frame_gray,element,1); cvReleaseStructuringElement(&element);

     cvShowImage("grid",current_frame_gray);         find_corners_result = cvFindChessboardCorners(current_frame_gray,                                          ChessBoardSize,                                          &corners[captured_frames*NPoints],                                          &corner_count[captured_frames],                                          0);

          if (find_corners_result !=0)      {            cvDrawChessboardCorners(current_frame_rgb, ChessBoardSize, &corners[captured_frames*NPoints], NPoints, find_corners_result);

            if (counter == 0)        // I do this to give you time to move the checkerboard around between captures        {          CvTermCriteria corner_criteria = cvTermCriteria(CV_TERMCRIT_ITER, 100, 0.1);              cvFindCornerSubPix( current_frame_gray,&corners[captured_frames*NPoints],                              NPoints, cvSize(3,3), cvSize(-1,-1),                              corner_criteria );                                  cvPutText(current_frame_rgb, "FLASH!" , cvPoint(100, 300), &font, CV_RGB(255,0,0));          printf("%d ... /n", captured_frames+1);          // NOTE: I put the little "FLASH" thing in here so that you know when it takes the snapshot          //       I'd gotten used to the little flash when using DirectShow for intrinsic calibration          captured_frames++;        }      }        cvShowImage("Window 0",current_frame_rgb);            cvWaitKey(100);

          find_corners_result = 0;    }         printf("/n");        cvSetData( image_points, corners, sizeof(CvPoint2D32f));    cvSetData( point_counts, corner_count, sizeof(int));          cvCalibrateCamera2( object_points,                        image_points,                        point_counts,                        cvSize(640,480),                        intrinsics,                        distortion_coeff,                        rotation_vectors,                        translation_vectors,                        0);                          calibration_done = true;                          }

      //  // All this below is used for dumping the parameters to the screen  //

      float intr[3][3] = {0.0};  float dist[4] = {0.0};  float tranv[3] = {0.0};  float rotv[3] = {0.0};

      for ( int i = 0; i < 3; i++)  {    for ( int j = 0; j < 3; j++)    {      intr[i][j] = ((float*)(intrinsics->data.ptr + intrinsics->step*i))[j];    }      dist[i] = ((float*)(distortion_coeff->data.ptr))[i];      tranv[i] = ((float*)(translation_vectors->data.ptr))[i];      rotv[i] = ((float*)(rotation_vectors->data.ptr))[i];  }  dist[3] = ((float*)(distortion_coeff->data.ptr))[3];

      printf("-----------------------------------------/n");  printf("INTRINSIC MATRIX: /n");  printf("[ %6.4f %6.4f %6.4f ] /n", intr[0][0], intr[0][1], intr[0][2]);  printf("[ %6.4f %6.4f %6.4f ] /n", intr[1][0], intr[1][1], intr[1][2]);  printf("[ %6.4f %6.4f %6.4f ] /n", intr[2][0], intr[2][1], intr[2][2]);  printf("-----------------------------------------/n");  printf("DISTORTION VECTOR: /n");  printf("[ %6.4f %6.4f %6.4f %6.4f ] /n", dist[0], dist[1], dist[2], dist[3]);  printf("-----------------------------------------/n");  printf("ROTATION VECTOR: /n");  printf("[ %6.4f %6.4f %6.4f ] /n", rotv[0], rotv[1], rotv[2]);  printf("TRANSLATION VECTOR: /n");  printf("[ %6.4f %6.4f %6.4f ] /n", tranv[0], tranv[1], tranv[2]);  printf("-----------------------------------------/n");

      exit(0);  cvDestroyAllWindows();}

    void InitCorners3D(CvMat *Corners3D, CvSize ChessBoardSize, int NImages, float SquareSize){  int CurrentImage = 0;  int CurrentRow = 0;  int CurrentColumn = 0;  int NPoints = ChessBoardSize.height*ChessBoardSize.width;  float * temppoints = new float[NImages*NPoints*3];

      // for now, assuming we're row-scanning   for (CurrentImage = 0 ; CurrentImage < NImages ; CurrentImage++)   {     for (CurrentRow = 0; CurrentRow < ChessBoardSize.height; CurrentRow++)     {       for (CurrentColumn = 0; CurrentColumn < ChessBoardSize.width; CurrentColumn++)       {     temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + CurrentColumn)*3]=(float)CurrentRow*SquareSize;     temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + CurrentColumn)*3+1]=(float)CurrentColumn*SquareSize;     temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + CurrentColumn)*3+2]=0.f;       }     }   }   (*Corners3D) = cvMat(NImages*NPoints,3,CV_32FC1, temppoints); }


    最新回复(0)