OpenCV 断言因 SolvePnP 而失败

OpenCV Assertion Failed with SolvePnP

本文关键字:失败 SolvePnP 断言 OpenCV      更新时间:2023-10-16

我正在尝试在检测视频流中的棋盘的C++程序中使用 solvePnP。每次校准完成后,我都会尝试运行solvePnP,但我不断收到我认为与平移和旋转矢量相关的错误。这是错误:错误

这是我的代码:

    #include <cstdio>
    #include <cstdlib>
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/calib3d/calib3d.hpp>
    #include <opencv2/highgui/highgui.hpp>
    using namespace cv;
    using namespace std;
    //Global variables
    vector<vector<Point2f> > corner_list;
    vector<vector<Point3f> > point_list;
    vector<Mat> rotation_vecs, translation_vecs;
    int i = 0;
    bool calibMode = true, drawMode = false, drawMode2 = false, camMatrixInit = false, calibrated = false;
    Mat originalCameraMatrix, cameraMatrix, distCoefficients, frame, gray, rvec, tvec;
    //Function declarations
    vector<Point3f> genWorldPoints(int cols, int rows);
    void printCameraMatrix();
    void printDistCoeff();
    void printRotVecs();
    /*Generates the world points (0, 0, 0), (1, 0, 0), etc. for the camera calibration.*/
    vector<Point3f> genWorldPoints(int cols, int rows){
        vector<Point3f> ret;
        for (int i=0; i<rows; i++) {
            for (int j=0; j<cols; j++) {
                int tempi = i*(-1);
                ret.push_back(Point3f((float)j, (float)tempi, 0.0));
            }
        }
        return ret;
    }
    /*Print the camera matrix*/
    void printCameraMatrix(){
        cout << "Original Camera Matrix" << endl << originalCameraMatrix << endl;
        cout << "Current Camera Matrix" << endl << cameraMatrix << endl;
    }
    /*Prints the distortion coefficients*/
    void printDistCoeff(){
        cout << "Distortion Coefficients:"<< endl << distCoefficients << endl;
    }

    int main(int argc, char *argv[]){
        VideoCapture *capdev;
cameraMatrix = Mat::eye(3, 3, CV_64F);
distCoefficients = Mat::zeros(8, 1, CV_64F);
// open the video device
capdev = new VideoCapture(0);
if (!capdev->isOpened()) {
    printf("Unable to open video devicen");
    return(-1);
}
namedWindow("Video", 1);
bool found;
*capdev >> frame;
rvec = Mat::zeros(3, 1, CV_64F);
tvec = Mat::zeros(3, 1, CV_64F);
//Initialize camera matrix
cameraMatrix.at<double>(0,2) = (frame.size().width)/2;
cameraMatrix.at<double>(1,2) = (frame.size().height)/2;
cameraMatrix.copyTo(originalCameraMatrix);
printCameraMatrix();
for(;;){
    *capdev >> frame;
    if (!found) {
        imshow("Video", frame);
    }
    Size patternsize(9,6);
    vector<Point2f> corner_set;
    vector<Point3f> point_set;
    int code = waitKey(10);
    cvtColor(frame, gray, CV_BGR2GRAY);
    found = findChessboardCorners(gray, patternsize, corner_set, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
    //Code to add a calibration frame
    if (found && calibMode) {
        cornerSubPix(gray, corner_set, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
        drawChessboardCorners(frame, patternsize, Mat(corner_set), found);
        //s key press
        if (code == 115){
            printf("Adding calibration framen");
            printf("Number of corners found: %lun", corner_set.size());
            printf("Point 0 x: %fty: %fn", corner_set[0].x, corner_set[1].y);
            //Add the corner set
            corner_list.push_back(corner_set);
            //Generate point set
            vector<Point3f> point_set = genWorldPoints(9,6);
            //Add point set to point set list
            point_list.push_back(point_set);
            //Save the image
            string filename = "../data/images/p4_calib_image_"+to_string(i)+".jpeg";
            imwrite(filename, frame);
            //if there are more than 5 saved calibration images, run calibration procedure
            if (i>4) {
                //Calculate the reprojection error by running calibrateCamera
                double rpe = calibrateCamera(point_list, corner_list, frame.size(), cameraMatrix,
                                             distCoefficients, rotation_vecs, translation_vecs,
                                             CV_CALIB_FIX_ASPECT_RATIO | CV_CALIB_FIX_K4);
                //Print the camera matrix
                printCameraMatrix();
                printDistCoeff();
                //Print the reprojection error
                cout << "Reprojection error: " << rpe << endl;
                calibrated = true;
            }
            //Increment i
            i++;
        }
        imshow("Video", frame);
    }

    else if (found && drawMode){
        cout << "Draw mode" << endl;
        bool solved = solvePnP(point_list, corner_list, cameraMatrix, distCoefficients,
                               rvec, tvec);
                               //rotation_vecs.front(), translation_vecs.front());
    }
    else if (found && drawMode2){
        cout << "Draw mode 2" << endl;
        bool solved = solvePnP(point_list, corner_list, cameraMatrix, distCoefficients,
                               rvec, tvec);
                               //rotation_vecs.front(), translation_vecs.front());
    }
    //Switching between drawing modes
    if (calibrated && code == 49) {
        calibMode = false;
        drawMode2 = false;
        drawMode = true;
    }
    else if (calibrated && code == 50){
        calibMode = false;
        drawMode = false;
        drawMode2 = true;
    }
    //Switch back to calibration mode
    else if (calibrated && code == 51){
        drawMode = false;
        drawMode2 = false;
        calibMode = true;
    }
    if (code == 27) {
        printf("Terminatingn");
        delete capdev;
        return(0);
    }
}
capdev = new VideoCapture(0);
printf("Terminatingn");
delete capdev;
return(0);
    }

请原谅缩进...

问题是 sovlePnP 需要 vector<Point2/3f> 作为输入,而不是 vector<vector<Point2/3f> > 。在你的代码中,"point_list"是vector<vector<Point3f> >,"corner_list"是vector<vector<Point2f> >

solvePnP 的文档可以在这里找到:http://docs.opencv.org/3.0-beta/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html