Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Issue with findChessboardCorners

I also asked this on the OpenCV forum, am trying my luck elsewhere. I'm using OpenCV 3.0 in Visual Studio Professional 2013.

So I'm trying to calibrate a camera using the tutorial code in calib3d and this tutorial. I keep getting the same error over and over (std::length_error at memory location) and I've traced it to where I try and add the corner vector given from findChessboardCorners to the image_points vector in the last line of my code.

image_points.push_back(corners);

In the debug window, the size of corners is listed as: corners { size=2305843009213050645 }, which is obviously way too big (there are only 35 corners in the calibration image I'm using).

Stripped down tutorial code is below, though again I've isolated the problem to findChessboardCorners giving a seemingly nonsensical corner vector. The strange part is that there's no problem drawing the corners on the calibration image I'm using-- it appears as though the corners were calibrated perfectly. So what is the problem here? I really don't know why findChessboardCorners would be giving me such a large corner vector that I can't even add it to a list of vectors.

using namespace cv;
using namespace std;

int main(int argc, char** argv){

int numBoards = 1;
int numCornersHor=7;
int numCornersVer=5;

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;

Mat large_image;
Mat image;
Mat gray_image;
large_image = imread(argv[1], IMREAD_COLOR);
resize(large_image, image, Size(), .5, .5);

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

if (image.empty())
        return(0);
else if (image.channels()>1)
    cvtColor(image, gray_image, CV_BGR2GRAY);
else gray_image = image;

bool found = findChessboardCorners(image, board_sz, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);


if (found)
{
    cornerSubPix(gray_image, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));

    drawChessboardCorners(gray_image, board_sz, corners, found);

}

imshow("win1", image);      
imshow("win2", gray_image);

int key = waitKey(1);
if (key == 27)
    return 0;

image_points.push_back(corners);
} 
like image 241
Max Avatar asked Nov 10 '22 09:11

Max


1 Answers

Figured it out. Problem was a bug in findChessboardCorners-- corners was being improperly resized within the function itself, causing it to blow up. Found the issue and got the fix from here, although I had to convert corners back to a vector once I ran the corrected function.

Updated code:

Mat pointBuf;

found = actually_findChessboardCorners(image, board_sz, pointBuf,
            CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE); 

corners.assign((Point2f*)pointBuf.datastart, (Point2f*)pointBuf.dataend);

using this function:

bool actually_findChessboardCorners(Mat& frame, Size& size, Mat& corners, int flags) {
int count = size.area() * 2;
corners.create(count, 1, CV_32FC2);
CvMat _image = frame;
bool ok = cvFindChessboardCorners(&_image, size,
    reinterpret_cast<CvPoint2D32f*>(corners.data),
    &count, flags) > 0;
return ok;

}

like image 50
Max Avatar answered Nov 15 '22 05:11

Max