7

カメラの既知の向きに基づいて画像から遠近歪みを除去しようとするプロジェクトに取り組んでいます。私の考えでは、カメラの既知の X、Y、および Z 方向に基づいて回転行列を作成できます。次に、これらの行列を WarpPerspective メソッドを介して画像に適用できます。

私のスクリプト (Python で記述) では、3 つの回転行列を作成し、それぞれが方向角に基づいています。私は 2 つの問題で行き詰まるところまで来ました。まず、個々のマトリックスを WarpPerspective メソッドにロードすると、正しく機能していないように見えます。画像を 1 つの軸でワープするたびに、画像が大幅にオーバーワープされているように見えます。画像の内容は、向きの角度を約 1 度以下に制限した場合にのみ認識できます。

次に、3 つの回転マトリックスを単一のマトリックスに結合して、WarpPerspective メソッドにロードする方法を教えてください。そのメソッドに 3x3 回転行列をインポートできますか、それとも 4x4 射影行列を作成する必要がありますか? 以下は私が取り組んでいるコードです。

ご協力ありがとうございました。

CR

from numpy import *
import cv

#Sets angle of camera and converts to radians
x =  -14 * (pi/180)
y = 20 * (pi/180)
z =  15 * (pi/180)

#Creates the Rotational Matrices
rX = array([[1, 0, 0], [0, cos(x), -sin(x)], [0, sin(x), cos(x)]])
rY = array([[cos(y), 0, -sin(y)], [0, 1, 0], [sin(y), 0, cos(y)]])
rZ = array([[cos(z), sin(z), 0], [-sin(z), cos(z), 0], [0, 0, 1]])

#Converts to CVMat format
X = cv.fromarray(rX)
Y = cv.fromarray(rY)
Z = cv.fromarray(rZ)

#Imports image file and creates destination filespace
im = cv.LoadImage("reference_image.jpg")
dst = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_8U, 3)

#Warps Image
cv.WarpPerspective(im, dst, X)

#Display
cv.NamedWindow("distorted")
cv.ShowImage("distorted", im)
cv.NamedWindow("corrected")
cv.ShowImage("corrected", dst)
cv.WaitKey(0)
cv.DestroyWindow("distorted")
cv.DestroyWindow("corrected")
4

3 に答える 3

4

あなたはいくつかの間違ったことをしています。まず、カメラモデルがないとx軸またはy軸を中心に回転できません。信じられないほど広い視野を持つカメラを想像してみてください。オブジェクトのすぐ近くに持って全体を見ることができますが、そのオブジェクトを回転させると、そのエッジが非常に速く飛んで、強い遠近法の歪みが発生するように見えます。一方、小さな視野(望遠鏡を考えてください)では、遠近法による歪みはほとんどありません。開始するのに適した場所は、少なくともカメラから幅が広い限り画像平面を設定し、オブジェクトを画像平面上に配置することです。これがこの例で行ったことです(c ++ openCV)

手順は次のとおりです

  1. 回転行列を作成します
  2. 画像を原点の中央に配置します
  3. 画像を回転させる
  4. 画像をz軸の下に移動します
  5. カメラマトリックスを掛ける
  6. パースペクティブをワープ

//1
float x =  -14 * (M_PI/180);
float y =  20 * (M_PI/180);
float z =  15 * (M_PI/180);

cv::Matx31f rot_vec(x,y,z);
cv::Matx33f rot_mat;
cv::Rodrigues(rot_vec, rot_mat); //converts to a rotation matrix

cv::Matx33f translation1(1,0,-image.cols/2,
                        0,1,-image.rows/2,
                        0,0,1);
rot_mat(0,2) = 0;
rot_mat(1,2) = 0;
rot_mat(2,2) = 1;

//2 and 3
cv::Matx33f trans = rot_mat*translation1;
//4
trans(2,2) += image.rows;
cv::Matx33f camera_mat(image.rows,0,image.rows/2,
                       0,image.rows,image.rows/2,
                       0,0,1);
//5
cv::Matx33f transform = camera_mat*trans;
//6
cv::Mat final;
cv::warpPerspective(image, final, cv::Mat(transform),image.size());

このコードは私にこの出力を与えました

ここに画像の説明を入力してください

これを投稿するまで、フランコの答えはわかりませんでした。彼は完全に正しいです。FindHomographyを使用すると、これらすべての手順を節約できます。それでも、これがお役に立てば幸いです。

于 2012-09-06T04:49:24.870 に答える
3

テレセントリック レンズまたは非常に長い焦点の望遠レンズを使用して画像を撮影しない限り、回転を知るだけでは十分ではありません (この場合、画像はほぼ正投影であり、遠近法の歪みはありません)。

その上、それは必要ありません。確かに、カメラをキャリブレーションすることで、画像内の 1 つの平面の遠近法の短縮を元に戻すことができます (つまり、完全なカメラ射影行列を形成するための内部パラメーターと外部パラメーターを推定します)。

しかし、実際の正方形 (または既知の幅と高さの比率を持つ長方形) のイメージである四角形をイメージで識別できれば、同じ結果をはるかに簡単に得ることができます。それができれば、正方形 (長方形) を四角形にマッピングするホモグラフィ行列を自明に計算し、その逆数を使用してワープできます。

于 2012-09-06T03:29:19.150 に答える
0

回転行列に関するウィキペディアのページには、3 つの基本的な回転行列を 1 つに結合する方法が示されています。

于 2012-09-05T20:14:00.060 に答える