findChessboardCorners的校准图像失败
c++
camera-calibration
computer-vision
opencv
44
0

我正在尝试让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);
    }
}
参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

棋盘的宽度和高度不能为相同的长度,即它必须是不对称的。这可能是问题的根源。 是有关使用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);
}
收藏
评论

而不是使用

Size patternsize(8,8); 

采用

Size patternsize(7,7);  
收藏
评论

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

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号