LoginSignup
4
2

More than 3 years have passed since last update.

C++からPythonをコールしてopencv Matを渡す

Last updated at Posted at 2019-06-21

とりあえずC++からPythonの関数をCALLしてcv:Matを渡して戻り値を取るってのをした。
boost pythonとかうまく行かなかなったので直に書いた。
やり方はとしてまずpythonの部分はこんな感じ

py_test3.py
import cv2

def test4(mat):
    gray = cv2.cvtColor(mat, cv2.COLOR_BGR2GRAY)
    bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
    return bgr

とりあえず入力をグレーにして次に3チャンネルにしてみた。
でこれをC++から呼ぶにはこうする

#include "Python.h"
#include <opencv2/opencv.hpp>
#include <numpy/arrayobject.h>



int demo5(){
    Py_Initialize();
    import_array();
    //カレントディレクトリを探す範囲にいれる-------------------------
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path,PyUnicode_DecodeFSDefault("."));
    //---------------------------------------------------------------
    //探すファイルを指定-------------------------------------------
    PyObject *pName = PyUnicode_DecodeFSDefault("py_test3");
    PyObject *pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    //---------------------------------------------------------------

    PyObject *pFunc = PyObject_GetAttrString(pModule, "test4");

    cv::Mat matdata=cv::imread("/home/kokawa2003/Pictures/daat3.png");
    int ch=matdata.channels();
    npy_intp dimensions[3] = {matdata.rows, matdata.cols, ch};
    int d=matdata.dims + 1;
    PyObject *pdemo2=PyArray_SimpleNewFromData(d,&dimensions[0], NPY_UINT8, matdata.data);

    //Tupleの作成    -----------------------------------------------
    PyObject *pArgs = PyTuple_New(1);//Tupleを新しく作成する
    PyTuple_SetItem(pArgs,0,pdemo2);//Tupleの0の位置にpdemo2を設定
    //---------------------------------------------------------------
    //RUN
    PyArrayObject *presult = (PyArrayObject *)PyObject_CallObject(pFunc, pArgs);


    int res1=PyArray_NDIM(presult);
    long rows = PyArray_SHAPE(presult)[0];
    long cols = PyArray_SHAPE(presult)[1];
    long res2 = PyArray_SHAPE(presult)[2];
    assert (res1 == 3 && res2 == 3);
    void *frame_data = PyArray_DATA(presult);


    cv::Mat cv_frame(rows, cols, CV_8UC3, frame_data);
    cv::imshow("win",cv_frame);

    Py_Finalize();
    return 0;
}

要点はtupleにすることぐらいか?
import_array();をコールしないとPyArray_SimpleNewFromDataが落ちる。(1日悩んだ)
あとpy_test3.pyは実行ファイルと同じところにおく。
リンクはqtならproに
CONFIG += link_pkgconfig
PKGCONFIG += python3
PKGCONFIG += opencv
CONFIG += no_keywords
を追記(言いたいのはpkgconfigでリンクしろってこと)
忘れないうちに書いた。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2