在C

时间:2017-11-30 23:32:47

标签: c opencv ubuntu-16.04

我已尝试过 cvCalibrateCamera2 的所有可能实现,但我一直遇到此错误:

  

函数'cvCalibrateCamera2'的参数太少

我正在研究here的解决方案,我总是遇到同样的错误。

系统:Ubuntu 16.04 |编程语言:C(对我来说至关重要)| gcc版本:5.4

的CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(main)
set(CMAKE_BUILD_TYPE Debug)
find_package( OpenCV REQUIRED )
set(SOURCE_FILES main.c)

# Executable
add_executable( ${PROJECT_NAME} ${SOURCE_FILES} )
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} )

add_definitions(-O4 -g)

非常感谢任何输入。谢谢。

供参考,整个代码:

#include <opencv2/core/core_c.h>
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/calib3d/calib3d_c.h"
#include "opencv2/videoio/videoio_c.h"
#include <stdio.h>

int main(){

    int n_boards = 0;
    int board_dt = 15;
    int board_w;
    int board_h;

    CvCapture* capture;
    board_w  = 8;//atoi(argv[1]);
    board_h  = 5;//atoi(argv[2]);
    n_boards = 8;//atoi(argv[3]);

    CvSize board_sz = cvSize( board_w, board_h );
    capture = cvCreateCameraCapture( 0 );
    if(!capture) { printf("\nCouldn't open the camera\n"); return -1;}

    cvNamedWindow( "Calibration" , CV_WINDOW_AUTOSIZE);
    IplImage *image = cvQueryFrame( capture );

    int board_n  = board_w * board_h;

    //ALLOCATE STORAGE
    CvMat* image_points      = cvCreateMat(n_boards*board_n,2,CV_32FC1);
    CvMat* object_points     = cvCreateMat(n_boards*board_n,3,CV_32FC1);
    CvMat* point_counts      = cvCreateMat(n_boards,1,CV_32SC1);
    CvMat* intrinsic_matrix  = cvCreateMat(3,3,CV_32FC1);
    CvMat* distortion_coeffs = cvCreateMat(5,1,CV_32FC1);

    CvPoint2D32f* corners = (CvPoint2D32f*) malloc(board_n);
    int corner_count;
    int successes = 0;
    int step, frame = 0;

    IplImage *gray_image = cvCreateImage(cvGetSize(image),8,1);//subpixel

    // CAPTURE CORNER VIEWS LOOP UNTIL WE'VE GOT n_boards
    // SUCCESSFUL CAPTURES (ALL CORNERS ON THE BOARD ARE FOUND)
    while (successes < n_boards) {
        //Skip every board_dt frames to allow user to move chessboard
        if((frame++ % board_dt) == 0) {
            //Find chessboard corners:
            int found = cvFindChessboardCorners(
                    image, board_sz, corners, &corner_count,
                    CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS
                    );

            //Get Subpixel accuracy on those corners
            cvCvtColor(image, gray_image, CV_BGR2GRAY);
            cvFindCornerSubPix(gray_image, corners, corner_count,
                    cvSize(11,11),cvSize(-1,-1), cvTermCriteria(
                        CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

            //Draw it
            cvDrawChessboardCorners(image, board_sz, corners,
                    corner_count, found);
            cvShowImage( "Calibration", image );

            if( corner_count == board_n ) {
                step = successes*board_n;
                for( int i=step, j=0; j<board_n; ++i,++j ) {
                    CV_MAT_ELEM(*image_points, float,i,0) = corners[j].x;
                    CV_MAT_ELEM(*image_points, float,i,1) = corners[j].y;
                    CV_MAT_ELEM(*object_points,float,i,0) = j/board_w;
                    CV_MAT_ELEM(*object_points,float,i,1) = j%board_w;
                    CV_MAT_ELEM(*object_points,float,i,2) = 0.0f;
                }
                CV_MAT_ELEM(*point_counts, int,successes,0) = board_n;
                successes++;
            }

        }

        //Handle pause/unpause and ESC
        int c = cvWaitKey(15);
        if (c == 'p'){
            c = 0;
            while(c != 'p' && c != 27){
                c = cvWaitKey(250);
            }
        }
        if(c == 27)
            return 0;
        image = cvQueryFrame( capture ); //Get next image

    }


    //ALLOCATE MATRICES ACCORDING TO HOW MANY CHESSBOARDS FOUND
    CvMat* object_points2 = cvCreateMat(successes*board_n,3,CV_32FC1);
    CvMat* image_points2 = cvCreateMat(successes*board_n,2,CV_32FC1);
    CvMat* point_counts2 = cvCreateMat(successes,1,CV_32SC1);

    //TRANSFER THE POINTS INTO THE CORRECT SIZE MATRICES
    for(int i = 0; i<successes*board_n; ++i) {
        CV_MAT_ELEM( *image_points2, float, i, 0) = CV_MAT_ELEM( *image_points, float, i, 0);
        CV_MAT_ELEM( *image_points2, float, i, 1) = CV_MAT_ELEM( *image_points, float, i, 1);
        CV_MAT_ELEM( *object_points2, float, i, 0) = CV_MAT_ELEM( *object_points, float, i, 0) ;
        CV_MAT_ELEM( *object_points2, float, i, 1) = CV_MAT_ELEM( *object_points, float, i, 1) ;
        CV_MAT_ELEM( *object_points2, float, i, 2) = CV_MAT_ELEM( *object_points, float, i, 2) ;
    }
    for(int i=0; i<successes; ++i){ //These are all the same number
        CV_MAT_ELEM( *point_counts2, int, i, 0) = CV_MAT_ELEM( *point_counts, int, i, 0);
    }


    // Initialize the intrinsic matrix such that the two focal
    // lengths have a ratio of 1.0
    CV_MAT_ELEM( *intrinsic_matrix, float, 0, 0 ) = 1.0f;
    CV_MAT_ELEM( *intrinsic_matrix, float, 1, 1 ) = 1.0f;

    //CALIBRATE THE CAMERA! -- **** PROBLEM LIES HERE ****
    cvCalibrateCamera2(
      object_points2, image_points2,
      point_counts2, cvGetSize( image ),
      intrinsic_matrix, distortion_coeffs,
      NULL, NULL,0);    //CV_CALIB_FIX_ASPECT_RATIO



    printf("Done!\n\n");
    return 0;



}

1 个答案:

答案 0 :(得分:1)

将cvCalibrateCamera2实现为:

cvCalibrateCamera2(object_points2,image_points2,point_counts‌​2,cvGetSize( image), intrinsic_matrix, distortion_coeffs, rot_vects, trans_vects,0,cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EP‌​S,30,DBL_EPSILON) );

修正了

的错误
  

参数太少

可以找到文献here