2017-10-02 8 views
1

私はsolvePnPを次の引数で呼び出そうとしています。solvePnP object_points/image_pointsシェイプ?

apriltag_object_points = np.array([(-1, -1, 0), (-1, 1, 0), (1, 1, 0), (1, -1, 0)], dtype=np.float) 

camera_matrix_left = np.eye(3) 

dist_left = np.zeros((5, 1)) 

image_points = np.array(detection.position, dtype=np.float) 

cv2.solvePnPRansac(apriltag_object_points, image_points, camera_matrix_left, dist_left) 

しかし、私は次のエラー取得しています:

OpenCV Error: Assertion failed (CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2)) in cvUndistortPoints, file /Users/travis/miniconda3/conda-bld/opencv_1506476120161/work/opencv-3.3.0/modules/imgproc/src/undistort.cpp, line 312 
Traceback (most recent call last): 
    File "/Users/me/Documents/Code/project/file.py", line 139, in <module> 
    ret = cv2.solvePnPRansac(apriltag_object_points, image_points, camera_matrix_left, dist_left) 
cv2.error: /Users/travis/miniconda3/conda-bld/opencv_1506476120161/work/opencv-3.3.0/modules/imgproc/src/undistort.cpp:312: error: (-215) CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2) in function cvUndistortPoints 

を私の引数の形状に問題があるように見えますが、彼らは罰金のように見える...

apriltag_object_points.shape == (4, 3) 
image_points.shape == (4, 2) 

画像の点は均質でなければならないのですか? hstackの列ベクトル1からimage_pointsまでを持っていればいいですか?

+0

"イメージポイントは均質でなければならないのですか?"ドキュメントには 'Nx2'や' 2xN'や2チャンネル(つまり 'Nx1x2')と書かれているので、問題が解決しないようです。誰でもこのプログラムを実行してエラーを再現できるように、ハードコードされた値で 'image_points'を作成できますか? –

答えて

2

この関数は、Pythonで実装されているため、ドキュメントは単にが間違っています。です。 solvePnP()solvePnPRansac()両方の状態のためのドキュメント:

Parameters:

objectPoints – Array of object points in the object coordinate space, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel, where N is the number of points. vector<Point3f> can be also passed here.

imagePoints – Array of corresponding image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, where N is the number of points. vector<Point2f> can be also passed here.

だからあなたはあなたがあなたの入力のための(N、3)及び(N、2)アレイを使用してよかったと想定。しかし、エラーコードはそうではないと言います。

CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2)

いいえ、それらはnumpy配列なので、おそらく最初の2つを破棄することができます。一つだけの行またはsrcdst内の1つの列があることを確認しています

(_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1)

:しかし、その後、次のチェックで、私たちは何か面白いものを参照してください。言い換えれば、厳密にはドキュメント内に記載されている2番目のバージョンにあなたのポイントを期待しています。マルチチャネルのポイント配列が必要です。

>>> apriltag_object_points = apriltag_object_points.reshape(4,1,3) 
>>> image_points = image_points.reshape(4,1,2) 
>>> it_works, rvec, tvec, inliers = cv2.solvePnPRansac(apriltag_object_points, image_points, camera_matrix_left, dist_left) 
>>> it_works 
True 

それは動作します:これは、我々は単にマルチチャンネル配列にあなたのポイントを再構築するのであれば第二など、次のチャンネルに座標

、行列の一つのチャネル上にある第1の座標を意味します!

将来プロヒント:すべての関数でOpenCVの(npoints, ncoords)形式でポイントを許可しない、それはまた、私の知る限り(npoints, 1, ncoords)形式でそれらを受け入れること。ただし、いくつかの関数は、後者の形式で動作します。したがって、PythonでOpenCVのポイント座標を使用している場合は、ポイント数がマルチチャネル配列にあると仮定するのが最善です。ここで、チャネル数は座標軸の数です。

+0

ありがとう!私は良い一日半をドキュメントを信頼し、どこが間違っていたのか疑問に思っていました。私はこれが将来の読者のための偉大なリソースになると確信しています – Carpetfizz

+1

@Carpetfizz私は、ポイント変換関数のためのスタックに関する多くの同様の質問に答えました。私が最初に関数を使用したとしても、その事実を解明するために*複数関数のドキュメントを見なければなりませんでした。ドキュメンテーションはPythonにとってもっと役立つかもしれませんが、OpenCVは最終的にはC++ライブラリなので、これを実装する最良の方法を知ることは難しいです。奇妙なことに、これらのチェックは、あなたがやったのと同じタイプの入力を使ってC++のバージョンを破るように思えます。OpenCVのGitHubをチェックし、必要に応じて問題を開いてみましょう。 –

+0

これは非常に役に立ちます。ありがとうございました – Carpetfizz

関連する問題