Я делаю 9 калибровочных снимков шахматной доски 12x18 углов, запрещаю объективы типа «рыбий глаз» k3=0 и уточняю найденные углы до субпиксельных позиций. Минимально достигаемая погрешность составляет около 0,2 при разрешении 640х480. Я предлагаю искать CornerSubpix(), TermCritiria и флаги для стереокалибровки() в документе opencv. Код выглядит так:
namedWindow( "Webcaml", CV_WINDOW_AUTOSIZE );
namedWindow( "Webcamr", CV_WINDOW_AUTOSIZE );
int successes=0;
int n_boards=9;
while(successes<n_boards)
{
video_l.read( frame_l );
video_r.read( frame_r );
if( framenumber++ % board_dt == 0 && framenumber != 0)
{
bool patternfoundl = findChessboardCorners( frame_l, Size( board_w, board_h ), corners_l, CV_CALIB_CB_FILTER_QUADS + CV_CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_FAST_CHECK );
bool patternfoundr = findChessboardCorners( frame_r, Size( board_w, board_h ), corners_r, CV_CALIB_CB_FILTER_QUADS + CV_CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_FAST_CHECK );
if(patternfoundl && patternfoundr)
{
cvtColor(frame_l,frame_l_grey,CV_RGB2GRAY);
cvtColor(frame_r,frame_r_grey,CV_RGB2GRAY);
cornerSubPix(frame_l_grey,corners_l,Size(6,6),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,50000000000,0.0000000000001));
cornerSubPix(frame_r_grey,corners_r,Size(6,6),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,50000000000,0.0000000000001));
}
drawChessboardCorners( frame_l, Size( board_w, board_h ), corners_l, patternfoundl );
drawChessboardCorners( frame_r, Size( board_w, board_h ), corners_r, patternfoundr );
imshow( "Webcaml", frame_l );
imshow( "Webcamr", frame_r );
if( corners_l.size() == (board_w*board_h) && corners_r.size() == (board_w*board_h) )
{
cornervector_l.push_back( corners_l );
cornervector_r.push_back( corners_r );
point3dvector.push_back( point3d );
successes++;
int c = cvWaitKey( 1000 );
}
}
else
{
imshow( "Webcaml", frame_l);
imshow( "Webcamr", frame_r);
}
char c = cvWaitKey( 1 );
if( c == 27 )break;
}
destroyAllWindows();
rms_l = calibrateCamera( point3dvector, cornervector_l, Size( video_r.get( CV_CAP_PROP_FRAME_WIDTH ), video_r.get( CV_CAP_PROP_FRAME_HEIGHT )),
intrinsics_l, distortion_l, rvecs_l, tvecs_l, CV_CALIB_FIX_K3 , cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,150000000000000000,DBL_EPSILON ) );
rms_r = calibrateCamera( point3dvector, cornervector_r, Size( video_r.get( CV_CAP_PROP_FRAME_WIDTH ), video_r.get( CV_CAP_PROP_FRAME_HEIGHT )),
intrinsics_r, distortion_r, rvecs_r, tvecs_r, CV_CALIB_FIX_K3 , cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,150000000000000000,DBL_EPSILON ) );
cout << "intrinsic_l = " << endl << format(intrinsics_l,"C" ) << endl << endl;
cout << "intrinsic_r = " << endl << format(intrinsics_r,"C" ) << endl << endl;
cout << "distortion_l = " << endl << format(distortion_l,"C" ) << endl << endl;
cout << "distortion_r = " << endl << format(distortion_r,"C" ) << endl << endl;
cout << "tvecs_l = " << endl << format(tvecs_l[0],"C" ) << endl << endl;
cout << "rvecs_l = " << endl << format(rvecs_l[0],"C" ) << endl << endl;
double rms_stereo = stereoCalibrate( point3dvector, cornervector_l, cornervector_r, intrinsics_l, distortion_l, intrinsics_r, distortion_r,
Size( video_r.get( CV_CAP_PROP_FRAME_WIDTH ),video_r.get( CV_CAP_PROP_FRAME_HEIGHT )), R, T, E, F,
TermCriteria( TermCriteria::COUNT+TermCriteria::EPS, 150000000000000000,DBL_EPSILON ), CV_CALIB_FIX_K3+CV_CALIB_FIX_INTRINSIC);
Rodrigues(R, R);
cout << "R = " << endl << format(R,"C" ) << endl << endl;
cout << "T = " << endl << format(T,"C" ) << endl << endl;
cout << "E = " << endl << format(E,"C" ) << endl << endl;
cout << "F = " << endl << format(F,"C" ) << endl << endl;
cout << "RMS Fehler l,r,stereo: " << rms_l << rms_r << rms_stereo << endl;
stereoRectify( intrinsics_l, distortion_l, intrinsics_r, distortion_r, Size( video_r.get( CV_CAP_PROP_FRAME_WIDTH ),video_r.get( CV_CAP_PROP_FRAME_HEIGHT )), R, T,
rectify_l, rectify_r, projection_l, projection_r, Q);
person
YuZ
schedule
30.10.2014