Camera Calibration Logitech c930
I am using OpenCV 2.4.9 with VS2012 c++/cli on a Win8.1 machine.
I am attempting to calibrate a Logitech c930 HD webcam and am getting some perplexing results.
In particular:
1) the resulting intrinsic matrix appears off; and
2) findChessboardCorners does not recognize boards placed relatively close (within 2-3 squares) to the horizontal edges of the image;
I am using findChessboardCorners looking for 20 or more matches with a 10 X 7 board where each square is 1". The chessboard is placed about 18 inches from the camera and I have measured the squares which are printed on standard paper and placed flat. The auto-zoom and focus are both turned off before capturing the images and the input image is 1920 x 1080.
The resulting intrinsic matrix is (e.g.):
9028.981 0 0
0 14583.126 0
959.5 539.5 1
I get an RMS of 0.6523 and an AVG of 0.6523.
As I understand it, the matrix should not have the values at 0,2 and 1,2 locations (i.e., the 959 and 539 values). In addition the values at 2,0 and 2,1 should be the principal point of the image rather than 0,0.
My code has attempted to follow the example at: http://docs.opencv.org/doc/tutorials/...
Here is a code sample.
int totalframes = 0;
int numCornersHor = CALIBRATE_CORNERS_HORIZONTAL;
int numCornersVer = CALIBRATE_CORNERS_VERTICAL;
int numSquares = numCornersHor * numCornersVer;
Size board_sz = Size(numCornersHor,numCornersVer);
vector<vector<Point3f>> object_points;
vector<vector<Point2f>> image_points;
vector<Point2f> corners;
int successes = 0;
vector<Point3f> obj;
Mat tImage,tImage2;
Mat grayImage;
vector<Mat> rvecs;
vector<Mat> tvecs;
vector<float> reprojErrs;
double totalAvgErr;
for(int j=0;j<numSquares;j++)
obj.push_back(Point3f((1.0*j)/(1.0*numCornersHor),j%numCornersHor,0.0f));
while(successes<CALIBRATE_NUMBER_OF_BOARDS_TO_MATCH && totalframes<CALIBRATE_TOTAL_FRAMES)
{
// check for new image
if(CameraVI->isFrameNew(CameraNumber))
{
totalframes++;
// load the image from the buffer
CameraVI->getPixels(CameraNumber, LdataBuffer, false, true);
// convert it to a mat
cv::Mat tImage(Images->Height, Images->Width, CV_8UC3, LdataBuffer, Mat::AUTO_STEP);
cvtColor(tImage,grayImage,CV_RGB2GRAY);
bool found = findChessboardCorners(grayImage, board_sz, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE | CALIB_CB_FAST_CHECK);
if(found)
{
cornerSubPix(grayImage, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
image_points.push_back(corners);
object_points.push_back(obj);
successes++;
}
Sleep(500);
}
double rms = calibrateCamera(object_points, image_points, grayImage.size(), intrinsic, distCoeffs, rvecs, tvecs,CV_CALIB_FIX_PRINCIPAL_POINT);
totalAvgErr = computeReprojectionErrors(object_points, image_points, rvecs, tvecs, intrinsic, distCoeffs, reprojErrs);
}
Any idea on what I am doing wrong? Thanks for any help.