Subversion Repositories seema-scanner

Rev

Rev 27 | Rev 31 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
27 jakw 1
#include "SMCalibrationWorker.h"
2
#include "SMCalibrationParameters.h"
22 jakw 3
 
4
#include <QSettings>
5
 
27 jakw 6
void SMCalibrationWorker::performCalibration(std::vector<SMCalibrationSet> calibrationData){
22 jakw 7
 
8
    // Number of saddle points on calibration pattern
9
    cv::Size patternSize(10, 9);
10
 
25 jakw 11
    int nSets = calibrationData.size();
22 jakw 12
 
13
    std::vector< std::vector< std::vector<cv::Point2f> > > qc(2);
14
 
15
    // Loop through calibration sets
16
    for(int i=0; i<nSets; i++){
17
 
27 jakw 18
        SMCalibrationSet SMCalibrationSetI = calibrationData[i];
25 jakw 19
 
27 jakw 20
        if(!SMCalibrationSetI.checked)
22 jakw 21
            continue;
25 jakw 22
 
23
        // Camera 0
24
        std::vector<cv::Point2f> qci0;
25
        // Extract checker corners
27 jakw 26
        bool success0 = cv::findChessboardCorners(SMCalibrationSetI.frame0, patternSize, qci0, cv::CALIB_CB_ADAPTIVE_THRESH);
25 jakw 27
        if(success0){
26 jakw 28
            cv::Mat gray;
27 jakw 29
            cv::cvtColor(SMCalibrationSetI.frame0, gray, CV_RGB2GRAY);
30
            cv::cornerSubPix(gray, qci0, cv::Size(5, 5), cv::Size(-1, -1),cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 20, 0.001));
25 jakw 31
            // Draw colored chessboard
27 jakw 32
            SMCalibrationSetI.frame0Result = SMCalibrationSetI.frame0.clone();
33
            cv::drawChessboardCorners(SMCalibrationSetI.frame0Result, patternSize, qci0, success0);
22 jakw 34
        }
35
 
29 jakw 36
        emit newFrameResult(i, 0, success0, SMCalibrationSetI.frame0Result);
37
 
25 jakw 38
        // Camera 1
39
        std::vector<cv::Point2f> qci1;
40
        // Extract checker corners
27 jakw 41
        bool success1 = cv::findChessboardCorners(SMCalibrationSetI.frame1, patternSize, qci1, cv::CALIB_CB_ADAPTIVE_THRESH);
25 jakw 42
        if(success1){
26 jakw 43
            cv::Mat gray;
27 jakw 44
            cv::cvtColor(SMCalibrationSetI.frame1, gray, CV_RGB2GRAY);
45
            cv::cornerSubPix(gray, qci1, cv::Size(5, 5), cv::Size(-1, -1),cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 20, 0.001));
25 jakw 46
            // Draw colored chessboard
27 jakw 47
            SMCalibrationSetI.frame1Result = SMCalibrationSetI.frame1.clone();
48
            cv::drawChessboardCorners(SMCalibrationSetI.frame1Result, patternSize, qci1, success1);
22 jakw 49
        }
50
 
29 jakw 51
        emit newFrameResult(i, 1, success1, SMCalibrationSetI.frame1Result);
52
 
27 jakw 53
        SMCalibrationSetI.success = success0 && success1;
25 jakw 54
 
22 jakw 55
        // Add to whole set
27 jakw 56
        if(SMCalibrationSetI.success){
25 jakw 57
            qc[0].push_back(qci0);
58
            qc[1].push_back(qci1);
22 jakw 59
        }
60
 
27 jakw 61
        // Show progress
62
        emit newSetProcessed(i);
22 jakw 63
    }
64
 
65
    int nValidSets = qc[0].size();
27 jakw 66
    if(nValidSets < 2){
22 jakw 67
        std::cerr << "Not enough valid calibration sequences!" << std::endl;
29 jakw 68
        emit done();
22 jakw 69
        return;
70
    }
71
 
72
    // Generate world object coordinates [mm]
73
    std::vector<cv::Point3f> Qi;
74
    for (int h=0; h<patternSize.height; h++)
75
        for (int w=0; w<patternSize.width; w++)
76
            Qi.push_back(cv::Point3f(5 * w, 5* h, 0.0)); // 5mm chess field size
77
    std::vector< std::vector<cv::Point3f> > Q;
78
    for(int i=0; i<qc[0].size(); i++)
79
        Q.push_back(Qi);
80
 
81
    // calibrate the cameras
25 jakw 82
    cv::Size frameSize(calibrationData[0].frame0.cols, calibrationData[0].frame0.rows);
83
//    cv::Size frameSize(640, 480);
22 jakw 84
    int flags = 0; //cv::CALIB_FIX_K3 + cv::CALIB_FIX_INTRINSIC;
85
 
86
    std::vector< std::vector<cv::Point2f> > qc0 = qc[0];
87
    std::vector< std::vector<cv::Point2f> > qc1 = qc[1];
88
 
27 jakw 89
    SMCalibrationParameters cal;
90
 
22 jakw 91
    std::vector<cv::Mat> cam_rvecs0, cam_tvecs0;
25 jakw 92
    cv::Mat K0, k0;
27 jakw 93
    cal.cam0_error = cv::calibrateCamera(Q, qc0, frameSize, cal.K0, cal.k0, cam_rvecs0, cam_tvecs0);
22 jakw 94
 
95
    std::vector<cv::Mat> cam_rvecs1, cam_tvecs1;
25 jakw 96
    cv::Mat K1, k1;
27 jakw 97
    cal.cam1_error = cv::calibrateCamera(Q, qc1, frameSize, cal.K1, cal.k1, cam_rvecs1, cam_tvecs1);
22 jakw 98
 
99
    // stereo calibration (don't change K0, K1, k0, k1)
100
    int flags_stereo = flags + cv::CALIB_FIX_INTRINSIC;
101
    cv::Mat E, F, R1, T1;
27 jakw 102
    cal.stereo_error = cv::stereoCalibrate(Q, qc[0], qc[1], K0, k0, K1, k1,
22 jakw 103
                                              frameSize, R1, T1, E, F,
104
                                              cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 50, DBL_EPSILON),
105
                                              flags_stereo);
106
 
27 jakw 107
    // Print to std::cout
108
    cal.print();
109
 
110
    // save to (reentrant qsettings object)
111
    QSettings settings;
112
    settings.setValue("calibration", QVariant::fromValue(cal));
113
 
114
    emit done();
115
 
22 jakw 116
}