使用 OpenCV 进行相机校准 - findChessboardCorners 返回 false

Posted

技术标签:

【中文标题】使用 OpenCV 进行相机校准 - findChessboardCorners 返回 false【英文标题】:Camera calibration with OpenCV - findChessboardCorners returns false 【发布时间】:2014-12-07 21:37:11 【问题描述】:

我尝试校准我的相机。我运行了一些示例,但它们都没有找到棋盘的角落。最后,我使用this question的代码,但是找不到角。下面有一张图片。我用它来寻找角落。

我在网上找到了一个解决这个问题的命令。它说 board_sz 必须保存内角的数量,而不是 正方形的数量。 board_sz 是一个二维对象。我不明白如何使用它来保存除 h*w 之外的内角的数量。

我给 w = 9,h = 7

编辑 1 ** **代码:

#include <cv.h>
#include <highgui.h>
#include <vector>
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
using namespace std;

int main()

int numBoards = 0;
int numCornersHor;
int numCornersVer;

printf("Enter number of corners along width: ");
scanf("%d", &numCornersHor);

printf("Enter number of corners along height: ");
scanf("%d", &numCornersVer);

printf("Enter number of boards: ");
scanf("%d", &numBoards);

int numSquares = numCornersHor * numCornersVer;
Size board_sz = Size(numCornersHor, numCornersVer);
VideoCapture capture = VideoCapture(0);

vector<vector<Point3d>> object_points;
vector<vector<Point2d>> image_points;

vector<Point2d> corners;
int successes=0;

Mat image;
Mat gray_image;
capture >> image;

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

while(successes<numBoards)

    cvtColor(image, gray_image, CV_BGR2GRAY);

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

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

    capture >> image;

    int key = waitKey(1);

    if(key==27)
        return 0;

    if(key==' ' && found!=0)
    
        image_points.push_back(corners);
        object_points.push_back(obj);
        printf("Snap stored!\n");

        successes++;

        if(successes>=numBoards)
            break;
    


Mat intrinsic = Mat(3, 3, CV_32FC1);
Mat distCoeffs;
vector<Mat> rvecs;
vector<Mat> tvecs;

intrinsic.ptr<float>(0)[0] = 1;
intrinsic.ptr<float>(1)[1] = 1;

calibrateCamera(object_points, image_points, image.size(), intrinsic, distCoeffs, rvecs, tvecs);

Mat imageUndistorted;
while(1)

    capture >> image;
    undistort(image, imageUndistorted, intrinsic, distCoeffs);

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

    waitKey(1);


capture.release();

return 0;

图片:

【问题讨论】:

向我们展示代码,否则我们无法为您提供帮助。我的直觉是你把棋盘的大小弄错了。 对了,你为什么要设置intrinsic[0][0]和intrinsic[1][1]为1?这些通常有点不同。 【参考方案1】:

试试尺寸 (8,6)。正确计算正方形有点令人困惑,但请尝试计算“内”角。

【讨论】:

以上是关于使用 OpenCV 进行相机校准 - findChessboardCorners 返回 false的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV 进行相机校准:使用失真和旋转平移矩阵

使用 openCV 进行相机校准 - cv2.getOptimalNewCameraMatrix 导致 roi 为零

OpenCV 相机校准

使用来自 OpenCV 的转换矩阵手动进行图像校准

不使用 cv2.findChessboardCorners 在 Python 中校准 OpenCV 相机

OpenCV中的相机失真内外参不失真图像相机校准