こいつが曲者だった。英語力がなかったので読み取れなかったが、複数枚の画像を使う。それにあわせて引数をちゃんと作ってやらなければならない。
void cvCalibrateCamera2( const CvMat* object_points, const CvMat* image_points, const CvMat* point_counts, CvSize image_size, CvMat* intrinsic_matrix, CvMat* distortion_coeffs, CvMat* rotation_vectors=NULL, CvMat* translation_vectors=NULL, int flags=0 ); const CvMat* object_points //位置関係の正しいコーナーの座標を格納したベクトル。 const CvMat* image_points //全画像のcornersをまとめて1つのCvMatに変換したもの。 const CvMat* point_counts //各画像ごとにコーナーの総数を格納したもの。 CvSize image_size //キャリブレーションしたい画像のサイズ CvMat* intrinsic_matrix //返される3*3のカメラ行列。 CvMat* distortion_coeffs //返される4*1の歪み係数ベクトル。 CvMat* rotation_vectors //とりあえずNULLで良い。 CvMat* translation_vectors //とりあえずNULLで良い。 int flags //とりあえず0で良い。
object_pointsのz座標は1.0にすればよいので以下のようにする。10.0とかいうのは適当。とりあえず動いた。
#define CHESS_WIDTH 8 //コーナー列数 #define CHESS_HEIGHT 6 //コーナー行数 #define CHESS_SIZE (CHESS_WIDTH*CHESS_HEIGHT) //1つのチェスボードに含まれるコーナーの総数 #define NUM_OF_IMAGES 5 //キャリブレーションに使う画像の枚数 #define TOTAL_CORNER (CHESS_SIZE*NUM_OF_IMAGES) //全画像のコーナーの合計 CvPoint3D32f _objects[TOTAL_CORNER]; CvMat objects; for(i=0;i<NUM_OF_IMAGES;i++){ for(j=0;j<CHESS_HEIGHT;j++){ for(k=0;k<CHESS_WIDTH;k++){ _objects[i*CHESS_SIZE+j*CHESS_WIDTH+k].x = 10.0*(float)(k-CHESS_WIDTH/2); _objects[i*CHESS_SIZE+j*CHESS_WIDTH+k].y = 10.0*(float)(j-CHESS_HEIGHT/2); _objects[i*CHESS_SIZE+j*CHESS_WIDTH+k].z = 1.0; } } } cvInitMatHeader(&objects, TOTAL_CORNER, 1, CV_32FC3, _objects, CV_AUTOSTEP);
ていうかcvInitMatHeader()って
CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data=NULL, int step=CV_AUTOSTEP );
ってなってるから普通にdataを多次元配列のポインタで渡しても大丈夫なんだろうか?未確認。