下の緑の台形内の座標 Pxy を実際の地面の同等の座標に変換する方法を見つけようとしています。
私は部屋の正確な測定値を持っています。つまり、A、B、C、D がその部屋にいる時間を正確に知ることができます。また、A、B、C、および D がその緑色の三角形にどれくらいの長さであるかを知っています (座標に関して)。
私はすでにホモグラフィと行列変換について読んでいますが、それについて頭を悩ませることはできません。私を正しい方向に導いてくれる情報をいただければ幸いです。
ありがとう!
下の緑の台形内の座標 Pxy を実際の地面の同等の座標に変換する方法を見つけようとしています。
私は部屋の正確な測定値を持っています。つまり、A、B、C、D がその部屋にいる時間を正確に知ることができます。また、A、B、C、および D がその緑色の三角形にどれくらいの長さであるかを知っています (座標に関して)。
私はすでにホモグラフィと行列変換について読んでいますが、それについて頭を悩ませることはできません。私を正しい方向に導いてくれる情報をいただければ幸いです。
ありがとう!
私があなたの質問を正しく理解していれば、世界に対するカメラの位置と向き (別名「ポーズ」) を表す変換行列を探しています。この行列がある場合 ( Mと呼びましょう)、任意の点をカメラ座標フレームからワールド座標フレームに、またその逆にマッピングできます。あなたの場合、世界座標で長方形を平面 (0, 1, 0)^T + 0 に変換したいと思うでしょう。
このポーズ マトリックスを導出するには、いくつかの方法があります。まず最初に、カメラ座標フレーム内の位置を実際のピクセル位置に変換するための内部カメラ パラメーターを記述する別のマトリックス ( K ) を知る必要があります。これには、標準的なピンホール投影、放射状の歪み、およびその他のいくつかの要素が含まれます。
KとMの両方を決定するには、カメラを調整する必要があります。これは通常、チェス盤フィールドの位置がわかっているキャリブレーション パターン (チェス盤パターンなど) を取得することによって行われます。次に、パターン上の既知の位置と観察されたピクセル位置の間に、いわゆる点対応を確立できます。これらの点のペアが十分にあれば、行列H = KMを解くことができます。これは、すでに言及したホモグラフィ行列です。それができたら、KとMを再構築できます。
理論は以上です。実用的な部分については、OpenCV-Documentations を参照することをお勧めします (たとえば、ここから開始できます: OpenCV カメラ キャリブレーションと ここ: OpenCV ポーズ推定)。
これがあなたを正しい方向に向けることを願っています;)
ライブラリOpencvを使用してアフィン変換行列を計算するコードがあります(台形を長方形に変換する方法と、さらに計算するための変換行列を見つける方法を示しています):
//example from book
// Learning OpenCV: Computer Vision with the OpenCV Library
// by Gary Bradski and Adrian Kaehler
// Published by O'Reilly Media, October 3, 2008
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
IplImage *src=0, *dst=0;
// absolute or relative path to image should be in argv[1]
char* filename = argc == 2 ? argv[1] : "Image0.jpg";
// get the picture
src = cvLoadImage(filename,1);
printf("[i] image: %s\n", filename);
assert( src != 0 );
// points (corners of )
CvPoint2D32f srcQuad[4], dstQuad[4];
// transformation matrix
CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);
// clone image
dst = cvCloneImage(src);
// define all the points
//here the coordinates of corners of your trapezoid
srcQuad[0].x = ??; //src Top left
srcQuad[0].y = ??;
srcQuad[1].x = ??; //src Top right
srcQuad[1].y = ??;
srcQuad[2].x = ??; //src Bottom left
srcQuad[2].y = ??;
srcQuad[3].x = ??; //src Bot right
srcQuad[3].y = ??;
//- - - - - - - - - - - - - -//
//coordinates of rectangle in src image
dstQuad[0].x = 0; //dst Top left
dstQuad[0].y = 0;
dstQuad[1].x = src->width-1; //dst Top right
dstQuad[1].y = 0;
dstQuad[2].x = 0; //dst Bottom left
dstQuad[2].y = src->height-1;
dstQuad[3].x = src->width-1; //dst Bot right
dstQuad[3].y = src->height-1;
// get transformation matrix that you can use to calculate
//coordinates of point Pxy
cvGetPerspectiveTransform(srcQuad,dstQuad,warp_matrix);
// perspective transformation
cvWarpPerspective(src,dst,warp_matrix);
cvNamedWindow( "cvWarpPerspective", 1 );
cvShowImage( "cvWarpPerspective", dst );
cvWaitKey(0);
cvReleaseMat(&warp_matrix);
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvDestroyAllWindows();
return 0;
それが役立つことを願っています!
完成のためだけに。@mmgp によって提案されたスレッドを見て、Christopher R. Wren によって提示されたものと同等のソリューションを実装しました。
カメラからの歪みはありましたが、これは私のケースでは非常にうまく機能することがわかりました。