使用findChessboardCorners的OpenCV问题

时间:2015-07-15 21:12:22

标签: c++ opencv camera-calibration

我也在OpenCV论坛上问过这个问题,我在其他地方试试运气。我在Visual Studio Professional 2013中使用OpenCV 3.0。

所以我正在尝试使用calib3d和this教程中的教程代码校准相机。我一遍又一遍地得到同样的错误(std :: length_error在内存位置)并且我已经将它追踪到我尝试的位置并将findChessboardCorners给出的角矢量添加到我代码的最后一行中的image_points矢量。

image_points.push_back(corners);

在调试窗口中,角的大小列为:corner {size = 2305843009213050645},这显然太大了(我正在使用的校准图像中只有35个角)。

在下面删除了教程代码,但我再次将问题与findChessboardCorners分离,给出了看似无意义的角落向量。奇怪的是,在我正在使用的校准图像上绘制角落没有问题 - 看起来好像校准了角落。那么这里的问题是什么?我真的不知道为什么findChessboardCorners会给我这么大的角矢量,我甚至无法将它添加到矢量列表中。

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);
} 

1 个答案:

答案 0 :(得分:1)

想出来。问题是findChessboardCorners中的一个错误 - 角落在函数本身内被不正确地调整大小,导致它爆炸。找到问题并从here获得修复,但是一旦我运行了修正后的函数,我就不得不将角转换回矢量。

更新的代码:

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);

使用此功能:

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;

}