DOSEIの日記

技術メモ+日常ログ

雑感

CvPoint と行列との相性というか、インタフェースが悪すぎると思う。

画像上の点 CvPoint p を何か透視変換してまた CvPoint q に戻すには、

CvMat *pp = cvCreateMat(1, 1, CV_32FC2); // 2チャンネルの1x1行列
CvMat *qq = cvCreateMat(1, 1, CV_32FC2);
cvSet1D(pp, 0, cvScalar(p.x, p.y));

cvPerspectiveTransform(pp, qq, A);

CvScalar q_ = cvGet1D(qq, 0);
CvPoint q = cvPoint(cvRound(q_.val[0]), cvRound(q_.val[1]));

cvReleaseMat(&pp);
cvReleaseMat(&qq);

って書くのでしょうか…。もっとうまい書き方があるんだろうか。
ていうか、2次元ベクトルを2チャンネル行列(または CvArr 互換の何か)に見立てるのって…。

まあ、たくさんのデータ列を一気に変換するときに役立つんだろうな。というかあれだ、1個だけなら素直に cvMatMul あたりで変換しろってことだな。

CvMat *pp = cvCreateMat(3, 1, CV_32FC1); // 3x1 縦ベクトル
CvMat *qq = cvCreateMat(3, 1, CV_32FC1);
cvmSet(pp, 0, 0, p.x);
cvmSet(pp, 1, 0, p.y);
cvmSet(pp, 2, 0, 1.0);

cvMatMul(A, pp, qq);

double w = cvmGet(qq, 2, 0);
CvPoint q = cvPoint(cvRound(cvmGet(qq, 0, 0) / w), cvRound(cvmGet(qq, 1, 0) / w));

cvReleaseMat(&pp);
cvReleaseMat(&qq);

やっぱりめんどいよ… orz