Webカメラからチェッカーボードパターンを認識するようにOpenCV2.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);
}
}
試行錯誤の結果、内部の角を数えているので、パターンサイズは7x7でなければならないことに気づきました。このパラメーターは正確である必要があります-8x8は機能しませんが、7x7未満のものも機能しません。
使用する代わりに
Size patternsize(8,8);
使用する
Size patternsize(7,7);
チェス盤の幅と高さを同じ長にすることはできません。つまり、非対称である必要があります。これが問題の原因である可能性があります。 ここ は、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);
}