2017-08-16 17 views
0

OpenCV wrapPerspectiveで遊ぶための小さな例を作りましたが、期待どおりの出力が得られません。OpenCV:warpPerspective/perspective変換を理解する

私の入力は45°の角度のバーです。私はそれを垂直に/ 90°の角度で整列させるように変換したい。それに問題はない。しかし、私が理解できないことは、実際の目的地点の周りのすべてが黒であるということです。私がこれを理解していない理由は、実際に変換マトリックスだけが目的地点ではなくwrapPerspective関数に渡されるからです。だから、私の予想される出力は、90°の角度のバーであり、その周りのほとんどは黒ではなく黄色である。推理で私の誤りはどこですか?

# helper function 
def showImage(img, title): 
    fig = plt.figure() 
    plt.suptitle(title) 
    plt.imshow(img) 


# read and show test image 
img = mpimg.imread('test_transform.jpg') 
showImage(img, "input image") 


# source points 
top_left = [194,430] 
top_right = [521,103] 
bottom_right = [549,131] 
bottom_left = [222,458] 
pts = np.array([bottom_left,bottom_right,top_right,top_left]) 


# target points 
y_off = 400; # y offset 
top_left_dst = [top_left[0], top_left[1] - y_off] 
top_right_dst = [top_left_dst[0] + 39.6, top_left_dst[1]] 
bottom_right_dst = [top_right_dst[0], top_right_dst[1] + 462.4] 
bottom_left_dst = [top_left_dst[0], bottom_right_dst[1]] 
dst_pts = np.array([bottom_left_dst, bottom_right_dst, top_right_dst, top_left_dst]) 

# generate a preview to show where the warped bar would end up 
preview=np.copy(img) 
cv2.polylines(preview,np.int32([dst_pts]),True,(0,0,255), 5) 
cv2.polylines(preview,np.int32([pts]),True,(255,0,255), 1) 
showImage(preview, "preview") 


# calculate transformation matrix 
pts = np.float32(pts.tolist()) 
dst_pts = np.float32(dst_pts.tolist()) 
M = cv2.getPerspectiveTransform(pts, dst_pts) 

# wrap image and draw the resulting image 
image_size = (img.shape[1], img.shape[0]) 
warped = cv2.warpPerspective(img, M, dsize = image_size, flags = cv2.INTER_LINEAR) 
showImage(warped, "warped") 

このコードを使用した結果は次のとおりです。

enter image description here

は、ここに私の入力画像test_transform.jpgです: enter image description here そして、ここでの座標と同じ画像が追加さ: enter image description here

リクエストにより、ここに変換行列があります:

[[ 6.05504680e-02 -6.05504680e-02 2.08289910e+02] 
[ 8.25714275e+00 8.25714275e+00 -5.12245707e+03] 
[ 2.16840434e-18 3.03576608e-18 1.00000000e+00]] 
+0

する必要があります出力変換行列ができますか? Ichにはかなり大きな視点の部分があると思います。 2D回転と平行移動(パースペクティブ部分なしのアフィン変換)だけを実行する場合、最後の行は(0,0,1)にする必要があります。 2D回転は、平行移動(回転中心から0)、回転(0,0)(ある角度で)、別の平行移動で中心を元の位置に戻す、またはオブジェクトを配置したい場所から計算することで計算できます置いた。これらの演算は、1つの変換行列に結合することができます。 – Micka

+0

@Micka:最初の投稿の最後に変換マトリックスを追加しました。実際にはこれは縮小されたサンプル/テストでしかありませんが、最終的には通りの車線を変えたいです(車の視点から鳥瞰の視点へ) –

答えて

2

あなたの配列またはその位置でのご注文は、欠陥かもしれません。この変換されたイメージを確認してください:dst_pts配列は:np.array([[196,492]、[233,494]、[234,32]、[196,34]])で、プレビューイメージの青色の矩形に多少似ています。 (私は自分自身は、彼らが正しいことを確認する座標製) 注:あなたの送信元と送信先のポイントは右の順に

enter image description here

+1

これは正解です。角度のついたバーの 'top_left'は、垂直バーの' bottom_left'に対応します(そして、他のすべてのものは、同じミスに従います)。そしてそれがなぜ垂直バーの上部と下部がぼやけているのか、なぜOPが歪んだ画像で黄色が非常に狭いのかです。 –

+1

ありがとう、2つは正しい!私のための固定された、働くソースポイントは、 'top_left = [521,103] top_right = [549,131] bottom_right = [222,458] bottom_left = [194,430]'であり、私はオフセットを調整しました: 'y_off = 50' –

関連する問題