16

OpenCV 2.4.5 に Web カメラからのチェッカーボード パターンを認識させようとしています。私はそれを機能させることができなかったので、「完璧な」画像を使用して機能させることにしました。

白枠の市松模様

しかし、それでもうまくいきません。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);
    }
}
4

3 に答える 3

27

試行錯誤の結果、内側のコーナーをカウントしているため、パターンサイズは 7x7 にする必要があることに気付きました。このパラメーターは正確である必要があります。8x8 は機能しませんが、7x7 未満のパラメーターも機能しません。

于 2013-07-16T00:14:29.310 に答える
4

チェス盤の幅と高さを同じ長さにすることはできません。つまり、非対称にする必要があります。これが問題の原因である可能性があります。 これは、 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);
}
于 2013-07-18T02:05:05.277 に答える