2017-06-16 25 views
0

私は(x、y)ピクセル座標を乗算して(x、y)実世界座標を得ることができるように変換行列Hを見つけようとしています。私のコードは以下の通りです:Opencvホモグラフィでピクセルxy座標からグローバルxy座標を見つける

import cv2 
import numpy as np 
from numpy.linalg import inv 
if __name__ == '__main__' : 
D=[159.1,34.2] 
I=[497.3,37.5] 
G=[639.3,479.7] 
A=[0,478.2] 
# Read source image. 
im_src = cv2.imread('/home/vivek/june_14.png') 
# Four corners of the book in source image 
pts_src = np.array([D,I,G,A]) 

# Read destination image. 
im_dst = cv2.imread('/home/vivek/june_14.png') 

# Four corners of the book in destination image. 
print "img1 shape:",im_dst.shape 
scale=1 
O=[0.0,0.0] 
X=[134.0*scale,0] 
Y=[0.0,184.0*scale] 
P=[134.0*scale,184.0*scale] 
# lx = 75.5 * scale 
# ly = 154.0 * scale 
pts_dst = np.array([O,X,P,Y]) 

# Calculate Homography 
h, status = cv2.findHomography(pts_src, pts_dst) 

print "homography:",h 
print "inv of H:",inv(h) 
print "position of the blob on the ground xy plane:",np.dot(np.dot(h,np.array([[323.0],[120.0],[1.0]])),scale) 


# Warp source image to destination based on homography 

im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0])) 

# Display images 
cv2.imshow("Source Image", im_src) 
cv2.imshow("Destination Image", im_dst) 
cv2.imshow("Warped Source Image", im_out) 
cv2.imwrite("im_out.jpg", im_out) 
cv2.waitKey(0) 

グローバルなxyは非常にオフです。私はどこかで何か間違っていますか?

+0

申し訳ありませんが、変数 'D、I、G、A、O、X、P、Yは何ですか?これらは何を表すはずですか?とにかく、 "実世界"(x、y)の座標を計算する場所では、均等な*点が得られます。これらの点は、スケーリングされたときに等価です---換言すれば、同じ点。しかし、あなたはスケールされたものではなく、 'x、y'ポイントが必要なので、スケールで分割する必要があります。 3つのベクトルはすべて同じ量でスケーリングされるため、スケーリング係数の最後のエントリを使用できます。 'pts = scale * np.dot(h、np.array([323.0]、[120.0]、[1.0]]))' 'と' 'pts = pts/pts [-1]'を実行する必要があります。 –

+0

OXPYは実際のワードポイントです(O原点、右にX-134インチ、右にP-134インチ、Y-184インチ下にY-184インチ)、DIGAは画像平面上のそれぞれのピクセル座標です。 –

+0

すみません。私はスケーリングの部分をかなり得ていませんでした。 –

答えて

3

長い答え

ホモグラフィは3x3行列とポイントがちょうどペア、2x1ありますので、一緒にこれらをマッピングする方法はありません。代わりに、均一な座標が使用され、3x1のベクトルに掛けることができます。ただし、均質な点は同じ点を表す間に拡大縮小することができます。すなわち、同次座標で、(kx、ky、k)は、(x、y、1)と同じポイントです。です。 Wikipedia page on homogeneous coordinatesから:ゼロ以外の実数Z、三重ためのユークリッド平面上の点(x、y)が与えられ

、(XZ、YZ、Z)呼ばれその点の同次座標の集合。この定義によって、3つの同次座標を共通の非ゼロ係数で乗算することにより、同じ点に対して新しい同次座標の集合が得られる。特に、(x、y、1)は、点(x、y)の均質座標系である。例えば、直交座標(1,2)は、同次座標で(1,2,1)または(2,4,4)と表すことができます。元のデカルト座標は、最初の2つの位置を3番目の位置で割って復元されます。したがって、デカルト座標とは異なり、無限に多くの同次座標によって単一点を表すことができます。

明らかに、デカルト座標では、このスケーリングは成立しません。 (x、y)は(XZ、YZ)ない限り、Z = 0又はZ = 1と同じ点はありません。ですから、これらの同次座標を、無限の数の方法で表すことができるデカルト座標にマップする方法が必要です。デカルト座標は一方向にしか表現できません。幸いにも、これは非常に簡単です。均等な座標をスケーリングするだけで、トリプルの最後の数字はになります。

ホモグラフィは、同次座標を乗算し、同次座標を返します。ですから、それらをデカルトの世界に戻すには、最後の座標で除算して、最初の2つの数値を外します。

あなたはホモグラフィによって同次座標を掛けたとき

は、あなたがそれらをスケーリングする必要が短い答え:

sx'  x 
sy' = H * y 
s   1 

だから、デカルト座標に戻って取得するには、することにより、新しい同次座標を分割:(sx '、sy'、s)/ s =(x '、y'、1)そして次に(x '、y')はあなたが望むポイントです。

短く答え

は、デカルト2 - ベクトルに均質な3-ベクトルからあなたのポイントを変換するために、内蔵のOpenCVの機能convertPointsFromHomogeneous()を使用してください。

関連する問題