Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Assertion failure calling cv fisheye::calibrate

New to OpenCV so please bear with me. I have a 180' fisheye lens which I'm trying to calibrate using the methods in cv::fisheye. I tried to come up with an example program similar to the one that uses cv::calibrateCamera (but way less featured).

The problem I'm facing is that I get this assert failure when calling cv::fisheye::calibrate

OpenCV Error: Assertion failed (svd.w.at<double>(0) / svd.w.at<double>((int)svd.w.total() - 1) < thresh_cond) in CalibrateExtrinsics, file /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-3.0.0/modules/calib3d/src/fisheye.cpp, line 1379

The call itself looks like this:

            int flags = 0;                                                                  
            flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;                                
            flags |= cv::fisheye::CALIB_CHECK_COND;                                         
            flags |= cv::fisheye::CALIB_FIX_SKEW;                                           

            fisheye::calibrate(obj_points, img_points, frame.size(), K, D,                  
                    noArray(), noArray(), flags);

I noticed that removing CALIB_CHECK_COND gets rid of the assertion but my undistorted image looks wrong. Any help is appreciated, the full code is below.

If I can get this working I'd love to have such an example somewhere in opensource, I found it hard to find much documentation for this sort of thing.

#include <string>                                                                                   

#include <opencv2/opencv.hpp>                                                                       

using namespace cv;                                                                                 
using namespace std;                                                                                

int main(int argc, char** argv) {                                                                   
    VideoCapture camera(0);                                                                         
    if (!camera.isOpened()) {                                                                       
        cout << "Failed to open camera." << std::endl;                                              
        return -1;                                                                                  
    }                                                                                               

    const char* window_name = "output";                                                             
    namedWindow(window_name, WINDOW_NORMAL);                                                        

    Mat frame;                                                                                      
    Size boardSize;                                                                                 
    boardSize.width = 9;                                                                            
    boardSize.height = 6;                                                                           

    int remaining_frames = 10;                                                                      
    Mat K;                                                                                          
    Mat D;                                                                                          
    Mat identity = Mat::eye(3, 3, CV_64F);                                                          

    vector<vector<Point2f> > img_points;                                                            
    vector<vector<Point3f> > obj_points(1);                                                         

    int width = 9;                                                                                  
    int height = 6;                                                                                 
    int sq_sz = 50;                                                                                 

    for (int i = 0; i < width; i++) {                                                               
        for (int j = 0; j < height; j++) {                                                          
            obj_points[0].push_back(Point3f(float(j * sq_sz), float(i * sq_sz), 0));                
        }                                                                                           
    }                                                                                               
    obj_points.resize(remaining_frames, obj_points[0]);

    while (1) {                                                                                     
        if (!camera.read(frame)) {                                                                  
            cout << "Failed to read frame" << std::endl;                                            
            break;                                                                                  
        }                                                                                           

        if (remaining_frames > 0) {                                                                 
            vector<Point2f> corners;                                                                
            bool found = findChessboardCorners(frame, boardSize, corners,                           
                    CALIB_CB_ADAPTIVE_THRESH|CALIB_CB_NORMALIZE_IMAGE|CALIB_CB_FAST_CHECK);         
            drawChessboardCorners(frame, boardSize, corners, found);                                
            if (found) {                                                                            
                img_points.push_back(corners);                                                      
                remaining_frames--;                                                                 
                cout << remaining_frames << " frames to calibration." << endl;                      

                if (remaining_frames == 0) {                                                        
                    cout << "Computing distortion" << endl;                                         

                    int flags = 0;                                                                  
                    flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;                                
                    flags |= cv::fisheye::CALIB_CHECK_COND;                                         
                    flags |= cv::fisheye::CALIB_FIX_SKEW;                                           

                    fisheye::calibrate(obj_points, img_points, frame.size(), K, D,                  
                            noArray(), noArray(), flags);                                           
                    cout << "Finished computing distortion" << endl;                                
                }                                                                                   
            }                                                                                       

            imshow(window_name, frame);                                                             
        } else {                                                                                    
            Mat output;                                                                             
            fisheye::undistortImage(frame, output, K, D, identity);                                 
            imshow(window_name, output);                                                            
        }                                                                                           

        if (waitKey(30) > 0) {                                                                      
            break;                                                                                  
        }                                                                                           
    }                                                                                               

    return 0;                                                                                       
}