パイソンからOpenCVの画像を取得し、pybind11にC ++でそれを使用する方法?

Rika :

私はそれを受信することが可能であるかを把握しようとしているOpenCV中のpythonから画像をC++私はC ++からの私のPythonモジュールに、コールバック関数を送信しようとしている、と私は私のC ++アプリで特定のPythonのメソッドを呼び出すときに、私は必要な画像にアクセスすることができます。
私はより多くの詳細を追加する前に、私はいくつかの質問を含め、この点では、すでに存在していることを追加する必要があります。

  1. どのツー変換-OpenCVの像データから、パイソン・ツー・C
  2. パス画像データから、パイソンツーれるCvMatイン-C
  3. 書き込みのpythonバインディング-FOR-Cコード-その使用、OpenCVの
  4. C-変換から-numpyのアレイ対マットOpenCVの

それらのどれもについては何も持っていませんPybind11実際にはそれらはすべて使用しているPyObject(からPython.hでとすることなく、ヘッダ)Boost.Python
私の最初の試みは、それがで可能である方法を知っているのでPybind11、それはのためのサポートがあることを知ってNumpy、それがうまくいけば物事がはるかに簡単に作ることができるので、配列を。

また上C++側面、OpenCV二つのバージョン、私が最近見つけたとして4.xの3.xおよび4.xのを持っている、あるC++11準拠しています。Pythonの側で、私はOpenCVのを使用3.xし、私が選択する1の交差点にだとどのような意味合いそれがに来るとき、それは持っていますPybind11

私がこれまで試してみました:
私は、迅速なダミーのコールバックを作り、シンプルを渡してみましたcv::Mat&。このように:

#include <pybind11/embed.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
namespace py = pybind11;
...

void cpp_callback1(bool i, std::string id, cv::Mat img)
{ 
    auto timenow = chrono::system_clock::to_time_t(chrono::system_clock::now());
    cout  <<"arg1: " << i << " arg2: " << id<<" arg3: " << typeid(img).name() <<" " << ctime(&timenow)<<endl;
}

そして、このようにそれを使用しました。

py::list callback_lst;
callback_lst.attr("append")(py::cpp_function(cpp_callback1));

py::dict core_kwargs = py::dict("callback_list"_a = callback_lst,
                                "debug_show_feed"_a = true);

py::object core_obj = core_cls(**core_kwargs);
core_obj.attr("start")();

それは言うPythonの一部の例外で失敗します。

29/03/2020 21:56:47 : exception occured ("(): incompatible function arguments. The following argument types are supported:\n    1. (arg0: bool, arg1: str, arg2: cv::Mat) -> None\n\nInvoked with: True, '5', array([[[195, 217, 237],\n        [195, 217, 237],\n        [196, 218, 238],\n        ...,\n        [211, 241, 255],\n        [211, 241, 255],\n        [211, 241, 255]],\n\n       [[195, 217, 237],\n        [195, 217, 237],\n        [195, 217, 237],\n        ...,\n        [211, 241, 255],\n        [211, 241, 255],\n        [211, 241, 255]],\n\n       [[195, 217, 237],\n        [195, 217, 237],\n        [195, 217, 237],\n        ...,\n        [211, 241, 255],\n        [211, 241, 255],\n        [211, 241, 255]],\n\n       ...,\n\n       [[120, 129, 140],\n        [110, 120, 130],\n        [113, 122, 133],\n        ...,\n        [196, 209, 245],\n        [195, 207, 244],\n        [195, 207, 244]],\n\n       [[120, 133, 142],\n        [109, 121, 130],\n        [114, 120, 131],\n        ...,\n        [195, 208, 242],\n        [195, 208, 242],\n        [195, 208, 242]],\n\n       [[121, 134, 143],\n        [106, 119, 128],\n        [109, 114, 126],\n        ...,\n        [194, 207, 241],\n        [195, 208, 242],\n        [195, 208, 242]]], dtype=uint8)",) 
Traceback (most recent call last):
  File "C:\Users\Master\Anaconda3\Lib\site-packages\F\utils.py", line 257, in start
    self._main_loop()
  File "C:\Users\Master\Anaconda3\Lib\site-packages\F\utils.py", line 301, in _main_loop
    self._execute_callbacks(is_valid, name, frame)
  File "C:\Users\Master\Anaconda3\Lib\site-packages\F\utils.py", line 142, in _execute_callbacks
    callback(*args)
TypeError: (): incompatible function arguments. The following argument types are supported:
    1. (arg0: bool, arg1: str, arg2: cv::Mat) -> None

Invoked with: True, '5', array([[[195, 217, 237],
        [195, 217, 237],
        [196, 218, 238],
        ...,
        [211, 241, 255],
        [211, 241, 255],
        [211, 241, 255]],

       [[195, 217, 237],
        [195, 217, 237],
        [195, 217, 237],
        ...,

使用するpy::objectか、py::array_t<uint8_t>代わりにcv::Mat任意のエラーが発生することはありませんが、私はに戻ってそれらをキャストする方法を見つけるように見えるカントcv::Mat正しくを!

私Tryiedはにnumpyの配列をキャストするcv::Matコメントで指示しますが、出力がゴミであるとして:

void cpp_callback1(bool i, std::string id, py::array_t<uint8_t>& img)
{ 
    auto im = img.unchecked<3>();
    auto rows = img.shape(0);
    auto cols = img.shape(1);
    auto type = CV_8UC3;

    //py::buffer_info buf = img.request();
    cv::Mat img2(rows, cols, type, img.ptr());
    cv::imshow("test", img2);
}

結果には: ここでは、画像の説明を入力します。

それは、私には前進しそうですか、その方向に何かが、画像はこのように表示されていることを台無しにされています。何が私がここに間違っているのでしょうか?でも、私は()img.stridesを使用couldntの!PY ::プリントを使用して、それを印刷したとき、それは示し960またはそのような何か。私はそれをどのように解釈するかを完全に無知ですよ!

Rika :

私は最終的に成功した仕事に、@のおかげでこれを取得することができDanMasekと、このリンクを

void cpp_callback1(bool i, std::string id, py::array_t<uint8_t>& img)
{ 
    py::buffer_info buf = img.request();
    cv::Mat mat(buf.shape[0], buf.shape[1], CV_8UC3, (unsigned char*)buf.ptr);

    cv::imshow("test", mat);
}

キャストが必要であることに注意し、またはそうでなければ、あなたは黒っぽい画面のみを取得したいです!
しかし、もし何らかの形のような方法があったpy::return_value_policyので、でも、Pythonの一部が終了しても、クラッシュしないでしょうC ++側は素晴らしいことだ、我々は参照の種類を変更するために使用することができることを。

サイドノート:
それはそうptrで公開されたプロパティnumpyの配列は、実際にはないですpy::handleけどPyObject*&私は成功した変換を持っているので、私は上記の投稿ソリューションに頼っことができませんでした。私はこのアウトを理解するとき、私は、この答えを更新します。

更新:

私が判明、アレイはdata、基礎となるバッファにポインタを保持し、容易に使用することもできます。<pybind11/numpy.h>L681:

/// Pointer to the contained data. If index is not provided, points to the
/// beginning of the buffer. May throw if the index would lead to out of bounds access.

使用したことを私の元のコードのでimg.ptr()、使用して作業することができimg.data()、このように:

void cpp_callback1(bool i, std::string id, py::array_t<uint8_t>& img)
{ 
    //auto im = img.unchecked<3>();
    auto rows = img.shape(0);
    auto cols = img.shape(1);
    auto type = CV_8UC3;

    cv::Mat img2(rows, cols, type, (unsigned char*)img.data());
    cv::imshow("test", img2);
}


おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=387418&siteId=1