2013-07-16 87 views
9

我想讓OpenCV 2.4.5從我的攝像頭識別棋盤圖案。我不能得到那個工作,所以我決定嘗試只使用一個「完美」的形象得到它的工作:findChessboardCorners校準失敗

checkerboard with white border

,但它仍然是行不通的 - 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); 
    } 
} 

回答

14

通過試驗和錯誤,我意識到patternsize應該是7x7,因爲它計數內部角落。這個參數必須是確切的 - 8x8不會工作,但都不會低於7x7。

+3

棋盤必須是不對稱的。我再說一遍,棋盤必須是不對稱的。告訴我你如何可能校準,否則。 – CTZStef

+0

@laurenelizabeth你的回答讓我更近了一步,但我似乎仍然有同樣的問題。關於7x7而不是8x8的提示對我來說非常重要。但是,我仍然無法檢測到拍攝棋盤的角落,甚至沒有發現接近完美的照片。 –

+0

我們正在嘗試使用不對稱9x7棋盤,我們要求8x6(內部正方形)。它工作得非常快。沒有問題檢測。而且我們使用的是雙攝像頭,我們只考慮兩臺攝像頭同時檢測到的東西。 謝謝! – helios

2

棋盤的寬度和高度不能是相同的長度,即它需要是不對稱的。這可能是你的問題的根源。 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); 
} 
+4

那麼,它使用7x7時,所以我不知道它需要不對稱。儘管感謝教程鏈接! – laurenelizabeth

+1

您是否可以使用對稱圖案校準並重新映射相機?我不這麼認爲。因此,它沒有工作。也許findChessboardCorners()工作,但這不是校準。 – CTZStef

+0

我只需要角落,而不是完整的校準例程。 – laurenelizabeth

8

而不是使用

Size patternsize(8,8); 

使用

Size patternsize(7,7);