当方 Python3.5or3.6 そしてOpencvは3.1.0or3.2.0を用いています。
Python2系やOpencv2系は記法が違ったりするので注意。
Pythonを使って透視変換をする時,画像の変換には次の関数を使う。
dst= cv2.warpPerspective(src, Matrix, (rows,cols), flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0, 0, 0, 0))
点群の座標変換
一方で,点群の座標を変換する際には
cv2.perspectiveTransform(points,perspective)
のように記述する。点群の方が先にくるなんてなんか違和感がある。
さらに違和感があるのは記述法だ。次の例を見て欲しい。
import cv2
import numpy as np
a = np.array([[1, 2], [4, 5], [7, 8]], dtype='float32')
h = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype='float32')
pointsOut = cv2.perspectiveTransform(a, h)
一見正しそうに見えるがこれは以下のようなエラーを起こす。
cv2.error: /build/buildd/opencv-2.3.1/modules/core/src/matmul.cpp:1916:
error: (-215) scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)
in function perspectiveTransform
公式Docmentには入力は「two-channel or three-channel floating-point array, where each element is a 2D/3D vector」と書いてある。
各要素に2/3次元ベクトルが詰まった2/3チャネルのarrayということなのである。
ということで正解はこちら
import cv2
import numpy as np
a = np.array([[1, 2], [4, 5], [7, 8]], dtype='float32')
h = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype='float32')
a2 = np.array([a])
pointsOut = cv2.perspectiveTransform(a2, h)
違いはこうなる。
a=
array([[ 1., 2.],
[ 4., 5.],
[ 7., 8.]], dtype=float32)
a2=
array([[[ 1., 2.],
[ 4., 5.],
[ 7., 8.]]], dtype=float32)
なんとなくで公式documentを読んでいてもダメなのだ。