Ask Your Question
0

Camera Calibration Logitech c930

asked 2014-12-27 11:48:17 -0600

pistorinoj gravatar image

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.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2014-12-27 16:08:18 -0600

updated 2014-12-27 16:10:41 -0600

I see two points:

a) Why do you pass the CV_CALIB_FIX_PRINCIPAL_POINT-Flag?

b) The computation of the obj-Vector is strange. This vector should contain the 3d-positions of the corners in the marker frame (in a metric coordinate system [Or imperial, if you are living in Liberia, Myanmar or the US]). Your first point is at (0,0,0) and the second one at (0.1,1,0) which is no valid position.

edit flag offensive delete link more

Comments

Thanks. I will check out the CV_CALIB_FIX_PRINCIPAL_POINT. Looking at the docs, it seemed like it might make sense to set that. Help me to understand your comment about the obj-Vector. I actually am not sure where in the code the second point is being set at (0.1,1.0). Is it the cornerSubPix line? If so, that line is copied directly from the tutorial link above. In any event, how should I change it? Finally, I do not know how many OpenCV programmers there are in Burma, but my guess is not many. Thanks

pistorinoj gravatar imagepistorinoj ( 2014-12-28 18:29:14 -0600 )edit

I was refering to this:

for(int j=0;j<numSquares;j++)
    obj.push_back(Point3f((1.0*j)/(1.0*numCornersHor),j%numCornersHor,0.0f));

Where did you get these lines from? You should use the "calcBoardCornerPositions"-Function from your linked tutorial.

FooBar gravatar imageFooBar ( 2015-01-02 11:28:23 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2014-12-27 11:48:17 -0600

Seen: 1,580 times

Last updated: Dec 27 '14