【问题标题】:findChessboardCorners fails for calibration imagefindChessboardCorners 校准图像失败
【发布时间】:2013-07-14 00:09:19
【问题描述】:

我正在尝试让 OpenCV 2.4.5 识别来自我的网络摄像头的棋盘格图案。我无法让它工作,所以我决定尝试使用“完美”的图像来让它工作:

但它仍然无法正常工作——patternFound 每次都返回 false。有谁知道我做错了什么?

#include <stdio.h>

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

int main(){
    Size patternsize(8,8); //number of centers
    Mat frame = imread("perfect.png"); //source image
    vector<Point2f> centers; //this will be filled by the detected centers

    bool patternfound = findChessboardCorners(frame,patternsize,centers);

    cout<<patternfound<<endl;
    drawChessboardCorners(frame, patternsize, Mat(centers), patternfound);

    cvNamedWindow("window");
    while(1){
        imshow("window",frame);
        cvWaitKey(33);
    }
}

【问题讨论】:

    标签: c++ opencv computer-vision camera-calibration


    【解决方案1】:

    通过反复试验,我意识到图案大小应该是 7x7,因为它计算的是内角。此参数必须准确--8x8 不起作用,但任何小于 7x7 的参数都不会。

    【讨论】:

    • 棋盘需要不对称。我再说一遍,棋盘必须是不对称的。告诉我你怎么可能校准。
    • @laurenelizabeth 你的回答让我更近了一步,但我似乎仍然有同样的问题。关于 7x7 而不是 8x8 的提示对我来说非常重要。但是,我仍然无法检测到已拍摄棋盘的角落,即使在接近完美的照片上也是如此。
    • 我们正在尝试使用不对称的 9x7 棋盘,我们要求使用 8x6(内部正方形)。它工作得非常快。检测没有问题。我们使用的是双摄像头设置,我们只考虑两个摄像头同时检测到的东西。谢谢!!!
    • @CTZStef 如果你说你不能用方形板校准,我想 OpenCV 可能有这个限制,但一般来说计算机视觉绝对不是这样,很有可能用上面有 (nxn) 个正方形的棋盘进行校准。如果您说您无法使用完全上下完美的棋盘进行校准(即,棋盘不是对角线或倾斜的),那么是的,我同意。
    • 我使用 5x3 模式并且它有效。选择图案的最佳方法是选择一个矩形棋盘,并选择至少 1 个偶数棋盘角。 openCV 的唯一限制是它应该大于 2x2
    【解决方案2】:

    而不是使用

    Size patternsize(8,8); 
    

    使用

    Size patternsize(7,7);  
    

    【讨论】:

    • 为什么?它是一个 8x8 网格
    • @johnktejik 它寻找两个白色方块和两个黑色方块相交的点。所以是的,有 8 个方格乘 8 个方格,但只有 7x7 个点连接四个方格。
    【解决方案3】:

    棋盘的宽度和高度不能是相同的长度,即它必须是不对称的。这可能是您的问题的根源。 Here 是一个非常好的 OpenCV 相机校准教程。

    下面是我用于校准的代码(经过测试且功能齐全,但是我在自己的一些处理线程中调用它,您应该在处理循环中调用它或您用来捕捉帧的任何东西):

    void MyCalibration::execute(IplImage* in, bool debug)
    {
        const int CHESSBOARD_WIDTH = 8;
        const int CHESSBOARD_HEIGHT = 5;
        const int CHESSBOARD_INTERSECTION_COUNT = CHESSBOARD_WIDTH * CHESSBOARD_HEIGHT;
    
        //const bool DO_CALIBRATION = ((BoolProperty*)getProperty("DoCalibration"))->getValue();
        if(in->nChannels == 1)
            cvCopy(in,gray_image);
        else
            cvCvtColor(in,gray_image,CV_BGR2GRAY);
    
        int corner_count;
        CvPoint2D32f* corners = new CvPoint2D32f[CHESSBOARD_INTERSECTION_COUNT];
        int wasChessboardFound = cvFindChessboardCorners(gray_image, cvSize(CHESSBOARD_WIDTH, CHESSBOARD_HEIGHT), corners, &corner_count);
    
        if(wasChessboardFound) {
            // Refine the found corners
            cvFindCornerSubPix(gray_image, corners, corner_count, cvSize(5, 5), cvSize(-1, -1), cvTermCriteria(CV_TERMCRIT_ITER, 100, 0.1));
    
            // Add the corners to the array of calibration points
            calibrationPoints.push_back(corners);
    
            cvDrawChessboardCorners(in, cvSize(CHESSBOARD_WIDTH, CHESSBOARD_HEIGHT), corners, corner_count, wasChessboardFound);
        } 
    }
    

    以防万一您想知道班级成员,这是我的班级(在我写它的时候,IplImage 还在):

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv/cv.h>
    
    class MyCalibration
    {
    private:
        std::vector<CvPoint2D32f*> calibrationPoints;
    
        IplImage *gray_image;
    
    public:
        MyCalibration(IplImage* in);
        void execute(IplImage* in, bool debug=false);
        ~MyCalibration(void);
    };
    

    最后是构造函数:

    MyCalibration::MyCalibration(IplImage* in)
    {
        gray_image = cvCreateImage(cvSize(in->width,in->height),8,1);
    }
    

    【讨论】:

    • 嗯,当我使用 7x7 时它工作正常,所以我不确定它是否需要不对称。不过,感谢您的教程链接!
    • 您是否能够使用对称图案校准和重新映射您的相机?我不这么认为。因此,它没有用。也许 findChessboardCorners() 有效,但这不是校准。
    • 我只需要角落,而不是完整的校准程序。
    • @CTZStef 谢谢你的回答。我在尝试使用对称棋盘校准相机时遇到了错误。
    猜你喜欢
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多