rewrote stereo_calib in C++
This commit is contained in:
parent
54ef68e7f4
commit
d61464a756
@ -1,388 +0,0 @@
|
||||
/* This is sample from the OpenCV book. The copyright notice is below */
|
||||
|
||||
/* *************** License:**************************
|
||||
Oct. 3, 2008
|
||||
Right to use this code in any way you want without warrenty, support or any guarentee of it working.
|
||||
|
||||
BOOK: It would be nice if you cited it:
|
||||
Learning OpenCV: Computer Vision with the OpenCV Library
|
||||
by Gary Bradski and Adrian Kaehler
|
||||
Published by O'Reilly Media, October 3, 2008
|
||||
|
||||
AVAILABLE AT:
|
||||
http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
|
||||
Or: http://oreilly.com/catalog/9780596516130/
|
||||
ISBN-10: 0596516134 or: ISBN-13: 978-0596516130
|
||||
|
||||
OTHER OPENCV SITES:
|
||||
* The source code is on sourceforge at:
|
||||
http://sourceforge.net/projects/opencvlibrary/
|
||||
* The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
|
||||
http://opencvlibrary.sourceforge.net/
|
||||
* An active user group is at:
|
||||
http://tech.groups.yahoo.com/group/OpenCV/
|
||||
* The minutes of weekly OpenCV development meetings are at:
|
||||
http://pr.willowgarage.com/wiki/OpenCV
|
||||
************************************************** */
|
||||
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// Given a list of chessboard images, the number of corners (nx, ny)
|
||||
// on the chessboards, and a flag: useCalibrated for calibrated (0) or
|
||||
// uncalibrated (1: use cvStereoCalibrate(), 2: compute fundamental
|
||||
// matrix separately) stereo. Calibrate the cameras and display the
|
||||
// rectified results along with the computed disparity images.
|
||||
//
|
||||
static void
|
||||
StereoCalib(const char* path, const char* imageList, int useUncalibrated)
|
||||
{
|
||||
CvRect roi1, roi2;
|
||||
int nx = 0, ny = 0;
|
||||
int displayCorners = 1;
|
||||
int showUndistorted = 1;
|
||||
bool isVerticalStereo = false;//OpenCV can handle left-right
|
||||
//or up-down camera arrangements
|
||||
const int maxScale = 1;
|
||||
const float squareSize = 1.f; //Set this to your actual square size
|
||||
FILE* f = fopen(imageList, "rt");
|
||||
int i, j, lr, nframes = 0, n, N = 0;
|
||||
vector<string> imageNames[2];
|
||||
vector<CvPoint3D32f> objectPoints;
|
||||
vector<CvPoint2D32f> points[2];
|
||||
vector<CvPoint2D32f> temp_points[2];
|
||||
vector<int> npoints;
|
||||
// vector<uchar> active[2];
|
||||
int is_found[2] = {0, 0};
|
||||
vector<CvPoint2D32f> temp;
|
||||
CvSize imageSize = {0,0};
|
||||
// ARRAY AND VECTOR STORAGE:
|
||||
double M1[3][3], M2[3][3], D1[5], D2[5];
|
||||
double R[3][3], T[3], E[3][3], F[3][3];
|
||||
double Q[4][4];
|
||||
CvMat _M1 = cvMat(3, 3, CV_64F, M1 );
|
||||
CvMat _M2 = cvMat(3, 3, CV_64F, M2 );
|
||||
CvMat _D1 = cvMat(1, 5, CV_64F, D1 );
|
||||
CvMat _D2 = cvMat(1, 5, CV_64F, D2 );
|
||||
CvMat matR = cvMat(3, 3, CV_64F, R );
|
||||
CvMat matT = cvMat(3, 1, CV_64F, T );
|
||||
CvMat matE = cvMat(3, 3, CV_64F, E );
|
||||
CvMat matF = cvMat(3, 3, CV_64F, F );
|
||||
|
||||
CvMat matQ = cvMat(4, 4, CV_64FC1, Q);
|
||||
|
||||
char buf[1024];
|
||||
|
||||
if( displayCorners )
|
||||
cvNamedWindow( "corners", 1 );
|
||||
// READ IN THE LIST OF CHESSBOARDS:
|
||||
if( !f )
|
||||
{
|
||||
fprintf(stderr, "can not open file %s\n", imageList );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !fgets(buf, sizeof(buf)-3, f) || sscanf(buf, "%d%d", &nx, &ny) != 2 )
|
||||
return;
|
||||
n = nx*ny;
|
||||
temp.resize(n);
|
||||
temp_points[0].resize(n);
|
||||
temp_points[1].resize(n);
|
||||
|
||||
for(i=0;;i++)
|
||||
{
|
||||
int count = 0, result=0;
|
||||
lr = i % 2;
|
||||
vector<CvPoint2D32f>& pts = temp_points[lr];//points[lr];
|
||||
if( !fgets( buf, sizeof(buf)-3, f ))
|
||||
break;
|
||||
size_t len = strlen(buf);
|
||||
while( len > 0 && isspace(buf[len-1]))
|
||||
buf[--len] = '\0';
|
||||
if( buf[0] == '#')
|
||||
continue;
|
||||
char fullpath[1024];
|
||||
sprintf(fullpath, "%s/%s", path, buf);
|
||||
IplImage* img = cvLoadImage( fullpath, 0 );
|
||||
if( !img )
|
||||
{
|
||||
printf("Cannot read file %s\n", fullpath);
|
||||
return;
|
||||
}
|
||||
imageSize = cvGetSize(img);
|
||||
imageNames[lr].push_back(buf);
|
||||
//FIND CHESSBOARDS AND CORNERS THEREIN:
|
||||
for( int s = 1; s <= maxScale; s++ )
|
||||
{
|
||||
IplImage* timg = img;
|
||||
if( s > 1 )
|
||||
{
|
||||
timg = cvCreateImage(cvSize(img->width*s,img->height*s),
|
||||
img->depth, img->nChannels );
|
||||
cvResize( img, timg, CV_INTER_CUBIC );
|
||||
}
|
||||
result = cvFindChessboardCorners( timg, cvSize(nx, ny),
|
||||
&temp[0], &count,
|
||||
CV_CALIB_CB_ADAPTIVE_THRESH |
|
||||
CV_CALIB_CB_NORMALIZE_IMAGE);
|
||||
if( timg != img )
|
||||
cvReleaseImage( &timg );
|
||||
if( result || s == maxScale )
|
||||
for( j = 0; j < count; j++ )
|
||||
{
|
||||
temp[j].x /= s;
|
||||
temp[j].y /= s;
|
||||
}
|
||||
if( result )
|
||||
break;
|
||||
}
|
||||
if( displayCorners )
|
||||
{
|
||||
printf("%s\n", buf);
|
||||
IplImage* cimg = cvCreateImage( imageSize, 8, 3 );
|
||||
cvCvtColor( img, cimg, CV_GRAY2BGR );
|
||||
cvDrawChessboardCorners( cimg, cvSize(nx, ny), &temp[0],
|
||||
count, result );
|
||||
IplImage* cimg1 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3);
|
||||
cvResize(cimg, cimg1);
|
||||
cvShowImage( "corners", cimg1 );
|
||||
cvReleaseImage( &cimg );
|
||||
cvReleaseImage( &cimg1 );
|
||||
int c = cvWaitKey(1000);
|
||||
if( c == 27 || c == 'q' || c == 'Q' ) //Allow ESC to quit
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
putchar('.');
|
||||
//N = pts.size();
|
||||
//pts.resize(N + n, cvPoint2D32f(0,0));
|
||||
//active[lr].push_back((uchar)result);
|
||||
is_found[lr] = result > 0 ? 1 : 0;
|
||||
//assert( result != 0 );
|
||||
if( result )
|
||||
{
|
||||
//Calibration will suffer without subpixel interpolation
|
||||
cvFindCornerSubPix( img, &temp[0], count,
|
||||
cvSize(11, 11), cvSize(-1,-1),
|
||||
cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
|
||||
30, 0.01) );
|
||||
copy( temp.begin(), temp.end(), pts.begin() );
|
||||
}
|
||||
cvReleaseImage( &img );
|
||||
|
||||
if(lr)
|
||||
{
|
||||
if(is_found[0] == 1 && is_found[1] == 1)
|
||||
{
|
||||
assert(temp_points[0].size() == temp_points[1].size());
|
||||
int current_size = points[0].size();
|
||||
|
||||
points[0].resize(current_size + temp_points[0].size(), cvPoint2D32f(0.0, 0.0));
|
||||
points[1].resize(current_size + temp_points[1].size(), cvPoint2D32f(0.0, 0.0));
|
||||
|
||||
copy(temp_points[0].begin(), temp_points[0].end(), points[0].begin() + current_size);
|
||||
copy(temp_points[1].begin(), temp_points[1].end(), points[1].begin() + current_size);
|
||||
|
||||
nframes++;
|
||||
|
||||
printf("Pair successfully detected...\n");
|
||||
}
|
||||
|
||||
is_found[0] = 0;
|
||||
is_found[1] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
printf("\n");
|
||||
// HARVEST CHESSBOARD 3D OBJECT POINT LIST:
|
||||
objectPoints.resize(nframes*n);
|
||||
for( i = 0; i < ny; i++ )
|
||||
for( j = 0; j < nx; j++ )
|
||||
objectPoints[i*nx + j] =
|
||||
cvPoint3D32f(i*squareSize, j*squareSize, 0);
|
||||
for( i = 1; i < nframes; i++ )
|
||||
copy( objectPoints.begin(), objectPoints.begin() + n,
|
||||
objectPoints.begin() + i*n );
|
||||
npoints.resize(nframes,n);
|
||||
N = nframes*n;
|
||||
CvMat _objectPoints = cvMat(1, N, CV_32FC3, &objectPoints[0] );
|
||||
CvMat _imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
|
||||
CvMat _imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
|
||||
CvMat _npoints = cvMat(1, npoints.size(), CV_32S, &npoints[0] );
|
||||
cvSetIdentity(&_M1);
|
||||
cvSetIdentity(&_M2);
|
||||
cvZero(&_D1);
|
||||
cvZero(&_D2);
|
||||
|
||||
// CALIBRATE THE STEREO CAMERAS
|
||||
printf("Running stereo calibration ...");
|
||||
fflush(stdout);
|
||||
cvStereoCalibrate( &_objectPoints, &_imagePoints1,
|
||||
&_imagePoints2, &_npoints,
|
||||
&_M1, &_D1, &_M2, &_D2,
|
||||
imageSize, &matR, &matT, &matE, &matF,
|
||||
cvTermCriteria(CV_TERMCRIT_ITER+
|
||||
CV_TERMCRIT_EPS, 100, 1e-5),
|
||||
CV_CALIB_FIX_ASPECT_RATIO +
|
||||
CV_CALIB_ZERO_TANGENT_DIST +
|
||||
CV_CALIB_SAME_FOCAL_LENGTH +
|
||||
CV_CALIB_FIX_K3);
|
||||
printf(" done\n");
|
||||
|
||||
// CALIBRATION QUALITY CHECK
|
||||
// because the output fundamental matrix implicitly
|
||||
// includes all the output information,
|
||||
// we can check the quality of calibration using the
|
||||
// epipolar geometry constraint: m2^t*F*m1=0
|
||||
vector<CvPoint3D32f> lines[2];
|
||||
points[0].resize(N);
|
||||
points[1].resize(N);
|
||||
_imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
|
||||
_imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
|
||||
lines[0].resize(N);
|
||||
lines[1].resize(N);
|
||||
CvMat _L1 = cvMat(1, N, CV_32FC3, &lines[0][0]);
|
||||
CvMat _L2 = cvMat(1, N, CV_32FC3, &lines[1][0]);
|
||||
//Always work in undistorted space
|
||||
cvUndistortPoints( &_imagePoints1, &_imagePoints1,
|
||||
&_M1, &_D1, 0, &_M1 );
|
||||
cvUndistortPoints( &_imagePoints2, &_imagePoints2,
|
||||
&_M2, &_D2, 0, &_M2 );
|
||||
cvComputeCorrespondEpilines( &_imagePoints1, 1, &matF, &_L1 );
|
||||
cvComputeCorrespondEpilines( &_imagePoints2, 2, &matF, &_L2 );
|
||||
double avgErr = 0;
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
double err = fabs(points[0][i].x*lines[1][i].x +
|
||||
points[0][i].y*lines[1][i].y + lines[1][i].z)
|
||||
+ fabs(points[1][i].x*lines[0][i].x +
|
||||
points[1][i].y*lines[0][i].y + lines[0][i].z);
|
||||
avgErr += err;
|
||||
}
|
||||
printf( "avg err = %g\n", avgErr/(nframes*n) );
|
||||
|
||||
// save intrinsic parameters
|
||||
CvFileStorage* fstorage = cvOpenFileStorage("intrinsics.yml", NULL, CV_STORAGE_WRITE);
|
||||
cvWrite(fstorage, "M1", &_M1);
|
||||
cvWrite(fstorage, "D1", &_D1);
|
||||
cvWrite(fstorage, "M2", &_M2);
|
||||
cvWrite(fstorage, "D2", &_D2);
|
||||
cvReleaseFileStorage(&fstorage);
|
||||
|
||||
//COMPUTE AND DISPLAY RECTIFICATION
|
||||
if( showUndistorted )
|
||||
{
|
||||
CvMat* mx1 = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_32F );
|
||||
CvMat* my1 = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_32F );
|
||||
CvMat* mx2 = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_32F );
|
||||
CvMat* my2 = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_32F );
|
||||
CvMat* img1r = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_8U );
|
||||
CvMat* img2r = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_8U );
|
||||
CvMat* disp = cvCreateMat( imageSize.height,
|
||||
imageSize.width, CV_16S );
|
||||
double R1[3][3], R2[3][3], P1[3][4], P2[3][4];
|
||||
CvMat _R1 = cvMat(3, 3, CV_64F, R1);
|
||||
CvMat _R2 = cvMat(3, 3, CV_64F, R2);
|
||||
// IF BY CALIBRATED (BOUGUET'S METHOD)
|
||||
if( useUncalibrated == 0 )
|
||||
{
|
||||
CvMat _P1 = cvMat(3, 4, CV_64F, P1);
|
||||
CvMat _P2 = cvMat(3, 4, CV_64F, P2);
|
||||
|
||||
cvStereoRectify( &_M1, &_M2, &_D1, &_D2, imageSize,
|
||||
&matR, &matT,
|
||||
&_R1, &_R2, &_P1, &_P2, &matQ,
|
||||
CV_CALIB_ZERO_DISPARITY,
|
||||
1, imageSize, &roi1, &roi2);
|
||||
|
||||
CvFileStorage* file = cvOpenFileStorage("extrinsics.yml", NULL, CV_STORAGE_WRITE);
|
||||
cvWrite(file, "R", &matR);
|
||||
cvWrite(file, "T", &matT);
|
||||
cvWrite(file, "R1", &_R1);
|
||||
cvWrite(file, "R2", &_R2);
|
||||
cvWrite(file, "P1", &_P1);
|
||||
cvWrite(file, "P2", &_P2);
|
||||
cvWrite(file, "Q", &matQ);
|
||||
cvReleaseFileStorage(&file);
|
||||
|
||||
isVerticalStereo = fabs(P2[1][3]) > fabs(P2[0][3]);
|
||||
if(!isVerticalStereo)
|
||||
roi2.x += imageSize.width;
|
||||
else
|
||||
roi2.y += imageSize.height;
|
||||
//Precompute maps for cvRemap()
|
||||
cvInitUndistortRectifyMap(&_M1,&_D1,&_R1,&_P1,mx1,my1);
|
||||
cvInitUndistortRectifyMap(&_M2,&_D2,&_R2,&_P2,mx2,my2);
|
||||
}
|
||||
//OR ELSE HARTLEY'S METHOD
|
||||
else if( useUncalibrated == 1 || useUncalibrated == 2 )
|
||||
// use intrinsic parameters of each camera, but
|
||||
// compute the rectification transformation directly
|
||||
// from the fundamental matrix
|
||||
{
|
||||
double H1[3][3], H2[3][3], iM[3][3];
|
||||
CvMat _H1 = cvMat(3, 3, CV_64F, H1);
|
||||
CvMat _H2 = cvMat(3, 3, CV_64F, H2);
|
||||
CvMat _iM = cvMat(3, 3, CV_64F, iM);
|
||||
//Just to show you could have independently used F
|
||||
if( useUncalibrated == 2 )
|
||||
cvFindFundamentalMat( &_imagePoints1,
|
||||
&_imagePoints2, &matF);
|
||||
cvStereoRectifyUncalibrated( &_imagePoints1,
|
||||
&_imagePoints2, &matF,
|
||||
imageSize,
|
||||
&_H1, &_H2, 3);
|
||||
cvInvert(&_M1, &_iM);
|
||||
cvMatMul(&_H1, &_M1, &_R1);
|
||||
cvMatMul(&_iM, &_R1, &_R1);
|
||||
cvInvert(&_M2, &_iM);
|
||||
cvMatMul(&_H2, &_M2, &_R2);
|
||||
cvMatMul(&_iM, &_R2, &_R2);
|
||||
//Precompute map for cvRemap()
|
||||
cvInitUndistortRectifyMap(&_M1,&_D1,&_R1,&_M1,mx1,my1);
|
||||
|
||||
cvInitUndistortRectifyMap(&_M2,&_D1,&_R2,&_M2,mx2,my2);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
|
||||
cvReleaseMat( &mx1 );
|
||||
cvReleaseMat( &my1 );
|
||||
cvReleaseMat( &mx2 );
|
||||
cvReleaseMat( &my2 );
|
||||
cvReleaseMat( &img1r );
|
||||
cvReleaseMat( &img2r );
|
||||
cvReleaseMat( &disp );
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc > 1 && !strcmp(argv[1], "--help"))
|
||||
{
|
||||
printf("Usage:\n ./stereo_calib <path to images> <file wtih image list>\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
StereoCalib(argc > 1 ? argv[1] : ".", argc > 2 ? argv[2] : "stereo_calib.txt", 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
9 6
|
||||
left01.jpg
|
||||
right01.jpg
|
||||
left02.jpg
|
||||
right02.jpg
|
||||
left03.jpg
|
||||
right03.jpg
|
||||
left04.jpg
|
||||
right04.jpg
|
||||
left05.jpg
|
||||
right05.jpg
|
||||
left06.jpg
|
||||
right06.jpg
|
||||
left07.jpg
|
||||
right07.jpg
|
||||
left08.jpg
|
||||
right08.jpg
|
||||
left09.jpg
|
||||
right09.jpg
|
||||
left11.jpg
|
||||
right11.jpg
|
||||
left12.jpg
|
||||
right12.jpg
|
||||
left13.jpg
|
||||
right13.jpg
|
||||
left14.jpg
|
||||
right14.jpg
|
@ -57,7 +57,7 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, bool useCalibrated=
|
||||
return;
|
||||
}
|
||||
|
||||
bool displayCorners = true;
|
||||
bool displayCorners = false;//true;
|
||||
const int maxScale = 2;
|
||||
const float squareSize = 1.f; // Set this to your actual square size
|
||||
// ARRAY AND VECTOR STORAGE:
|
||||
@ -172,7 +172,7 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, bool useCalibrated=
|
||||
CV_CALIB_FIX_ASPECT_RATIO +
|
||||
CV_CALIB_ZERO_TANGENT_DIST +
|
||||
CV_CALIB_SAME_FOCAL_LENGTH +
|
||||
CV_CALIB_FIX_K3);
|
||||
CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5);
|
||||
cout << "done\n";
|
||||
|
||||
// CALIBRATION QUALITY CHECK
|
||||
@ -217,13 +217,13 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, bool useCalibrated=
|
||||
cout << "Error: can not save the intrinsic parameters\n";
|
||||
|
||||
Mat R1, R2, P1, P2, Q;
|
||||
Rect roi1, roi2;
|
||||
Rect validRoi[2];
|
||||
|
||||
stereoRectify(cameraMatrix[0], distCoeffs[0],
|
||||
cameraMatrix[1], distCoeffs[1],
|
||||
imageSize, R, T, R1, R2, P1, P2, Q,
|
||||
1, imageSize, &roi1, &roi2);
|
||||
|
||||
1, imageSize, &validRoi[0], &validRoi[1]);
|
||||
|
||||
fs.open("extrinsics.yml", CV_STORAGE_WRITE);
|
||||
if( fs.isOpened() )
|
||||
{
|
||||
@ -237,17 +237,17 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, bool useCalibrated=
|
||||
// or up-down camera arrangements
|
||||
bool isVerticalStereo = fabs(P2.at<double>(1, 3)) > fabs(P2.at<double>(0, 3));
|
||||
|
||||
//COMPUTE AND DISPLAY RECTIFICATION
|
||||
// COMPUTE AND DISPLAY RECTIFICATION
|
||||
if( !showRectified )
|
||||
return;
|
||||
|
||||
Mat rmap[2][2];
|
||||
// IF BY CALIBRATED (BOUGUET'S METHOD)
|
||||
if( !useCalibrated )
|
||||
if( useCalibrated )
|
||||
{
|
||||
// we already computed everything
|
||||
}
|
||||
//OR ELSE HARTLEY'S METHOD
|
||||
// OR ELSE HARTLEY'S METHOD
|
||||
else
|
||||
// use intrinsic parameters of each camera, but
|
||||
// compute the rectification transformation directly
|
||||
@ -265,17 +265,60 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, bool useCalibrated=
|
||||
|
||||
R1 = cameraMatrix[0].inv()*H1*cameraMatrix[0];
|
||||
R2 = cameraMatrix[1].inv()*H2*cameraMatrix[1];
|
||||
P1 = cameraMatrix[0];
|
||||
P2 = cameraMatrix[1];
|
||||
}
|
||||
|
||||
//Precompute maps for cv::remap()
|
||||
initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, rmap[0][0], rmap[0][1]);
|
||||
initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, imageSize, CV_16SC2, rmap[1][0], rmap[1][1]);
|
||||
|
||||
/*for( i = 0; i < nimages; i++ )
|
||||
Mat canvas;
|
||||
double sf;
|
||||
int w, h;
|
||||
if( !isVerticalStereo )
|
||||
{
|
||||
Mat img =
|
||||
sf = 1;//600./MAX(imageSize.width, imageSize.height);
|
||||
w = cvRound(imageSize.width*sf);
|
||||
h = cvRound(imageSize.height*sf);
|
||||
canvas.create(h, w*2, CV_8UC3);
|
||||
}
|
||||
else
|
||||
{
|
||||
sf = 1;//300./MAX(imageSize.width, imageSize.height);
|
||||
w = cvRound(imageSize.width*sf);
|
||||
h = cvRound(imageSize.height*sf);
|
||||
canvas.create(h*2, w, CV_8UC3);
|
||||
}
|
||||
|
||||
for( i = 0; i < nimages; i++ )
|
||||
{
|
||||
for( k = 0; k < 2; k++ )
|
||||
{
|
||||
Mat img = imread(goodImageList[i*2+k], 0), rimg, cimg;
|
||||
remap(img, rimg, rmap[k][0], rmap[k][1], CV_INTER_LINEAR);
|
||||
cvtColor(rimg, cimg, CV_GRAY2BGR);
|
||||
Mat canvasPart = !isVerticalStereo ? canvas(Rect(w*k, 0, w, h)) : canvas(Rect(0, h*k, w, h));
|
||||
resize(cimg, canvasPart, canvasPart.size(), 0, 0, CV_INTER_AREA);
|
||||
if( useCalibrated )
|
||||
{
|
||||
Rect vroi(cvRound(validRoi[k].x*sf), cvRound(validRoi[k].y*sf),
|
||||
cvRound(validRoi[k].width*sf), cvRound(validRoi[k].height*sf));
|
||||
rectangle(canvasPart, vroi, Scalar(0,0,255), 3, 8);
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
if( !isVerticalStereo )
|
||||
for( j = 0; j < canvas.rows; j += 16 )
|
||||
line(canvas, Point(0, j), Point(canvas.cols, j), Scalar(0, 255, 0), 1, 8);
|
||||
else
|
||||
for( j = 0; j < canvas.cols; j += 16 )
|
||||
line(canvas, Point(j, 0), Point(j, canvas.rows), Scalar(0, 255, 0), 1, 8);
|
||||
imshow("rectified", canvas);
|
||||
char c = (char)waitKey();
|
||||
if( c == 27 || c == 'q' || c == 'Q' )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -297,7 +340,7 @@ static bool readStringList( const string& filename, vector<string>& l )
|
||||
|
||||
int print_help()
|
||||
{
|
||||
cout << "Usage:\n ./stereo_calib -w board_width -h board_height <image list XML/YML file>\n";
|
||||
cout << "Usage:\n ./stereo_calib -w board_width -h board_height [-nr /*dot not view results*/] <image list XML/YML file>\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -306,13 +349,28 @@ int main(int argc, char** argv)
|
||||
{
|
||||
Size boardSize;
|
||||
string imagelistfn;
|
||||
bool showRectified = true;
|
||||
|
||||
for( int i = 1; i < argc; i++ )
|
||||
{
|
||||
if( string(argv[i]) == "-w" )
|
||||
sscanf(argv[++i], "%d", &boardSize.width);
|
||||
{
|
||||
if( sscanf(argv[++i], "%d", &boardSize.width) != 1 || boardSize.width <= 0 )
|
||||
{
|
||||
cout << "invalid board width" << endl;
|
||||
return print_help();
|
||||
}
|
||||
}
|
||||
else if( string(argv[i]) == "-h" )
|
||||
sscanf(argv[++i], "%d", &boardSize.height);
|
||||
{
|
||||
if( sscanf(argv[++i], "%d", &boardSize.height) != 1 || boardSize.height <= 0 )
|
||||
{
|
||||
cout << "invalid board height" << endl;
|
||||
return print_help();
|
||||
}
|
||||
}
|
||||
else if( string(argv[i]) == "-nr" )
|
||||
showRectified = false;
|
||||
else if( string(argv[i]) == "--help" )
|
||||
return print_help();
|
||||
else if( argv[i][0] == '-' )
|
||||
@ -332,11 +390,13 @@ int main(int argc, char** argv)
|
||||
|
||||
vector<string> imagelist;
|
||||
bool ok = readStringList(imagelistfn, imagelist);
|
||||
|
||||
if( !ok || imagelist.empty() || boardSize.width <= 0 || boardSize.height <= 0 )
|
||||
if(!ok || imagelist.empty())
|
||||
{
|
||||
cout << "can not open " << imagelistfn << " or the string list is empty" << endl;
|
||||
return print_help();
|
||||
}
|
||||
|
||||
StereoCalib(imagelist, boardSize);
|
||||
StereoCalib(imagelist, boardSize, true, showRectified);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
9 6
|
||||
left01.jpg
|
||||
right01.jpg
|
||||
left02.jpg
|
||||
right02.jpg
|
||||
left03.jpg
|
||||
right03.jpg
|
||||
left04.jpg
|
||||
right04.jpg
|
||||
left05.jpg
|
||||
right05.jpg
|
||||
left06.jpg
|
||||
right06.jpg
|
||||
left07.jpg
|
||||
right07.jpg
|
||||
left08.jpg
|
||||
right08.jpg
|
||||
left09.jpg
|
||||
right09.jpg
|
||||
left11.jpg
|
||||
right11.jpg
|
||||
left12.jpg
|
||||
right12.jpg
|
||||
left13.jpg
|
||||
right13.jpg
|
||||
left14.jpg
|
||||
right14.jpg
|
32
samples/cpp/stereo_calib.xml
Normal file
32
samples/cpp/stereo_calib.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0"?>
|
||||
<opencv_storage>
|
||||
<imagelist>
|
||||
"left01.jpg"
|
||||
"right01.jpg"
|
||||
"left02.jpg"
|
||||
"right02.jpg"
|
||||
"left03.jpg"
|
||||
"right03.jpg"
|
||||
"left04.jpg"
|
||||
"right04.jpg"
|
||||
"left05.jpg"
|
||||
"right05.jpg"
|
||||
"left06.jpg"
|
||||
"right06.jpg"
|
||||
"left07.jpg"
|
||||
"right07.jpg"
|
||||
"left08.jpg"
|
||||
"right08.jpg"
|
||||
"left09.jpg"
|
||||
"right09.jpg"
|
||||
"left11.jpg"
|
||||
"right11.jpg"
|
||||
"left12.jpg"
|
||||
"right12.jpg"
|
||||
"left13.jpg"
|
||||
"right13.jpg"
|
||||
"left14.jpg"
|
||||
"right14.jpg"
|
||||
</imagelist>
|
||||
</opencv_storage>
|
||||
|
Loading…
Reference in New Issue
Block a user