c++呼び出しpython numpyプログラミング
背景
現在、pythonエンジニアリングをc++で再構築しており、一部の後処理で再構築に時間がかかりたくないので、直接呼び出しに来ます.資料を探しながら作ったので、このデモを作るのに時間がかかったので、忘れないようにメモしておきます.
資料
多くのc++がpythonを呼び出す方法を探して、まず肯定することができるのは1つ以上の方法があって、直接pythonライブラリ、numpy arrayobjectライブラリを使ってします;もう1つはboost/python boost/numpyを使用する方法です.後者は融通がきかず、リンクライブラリの問題で、記録して後ろに置いた.
1)一般的な方式パッケージの基本構造C/C++呼び出しPython(OpenCVとNumpy)の著者は多くの情報を収集し、大きな助けになった. コンパイル、stackoverflow:how to build this project という説明もある.コードブロック c++: cc.cpp. 1-c++コードに説明が必要な箇所【1】python検索のパスを指定し、import***(PyImport_Import)のエラーを防止する必要があります.探索経路を設定する場合もこのように が可能である. python:simple_module.py. 2 c++複数numpyタイプの戻り値を処理するpythonコード 参考文献:PyArg_ParseTupleの公式ドキュメントでは、この関数の標準的な使い方について説明しています.しかし、より便利な関数があります.このリンクのページは少し上のPyArg_です.UnpackTuple関数、完全にPyArg_と同等ですParseTuple関数、もっと頭がいいです. は、複数numpyタイプの戻り値コード を処理する.
補足 import_array()には奇妙な戻り値があり、このブログでは解決策import_にも言及しています.array()エラーが発生し、戻り値タイプが関数タイプと一致しません.しかし、物を削除するには、間違いを報告しないリスクがあります.ここでどこで見たコードか忘れてしまいましたが、履歴にも見つからず、先にコードを貼っておきました.実はこの関数にシェルを追加します.import_をinitで置き換えますarray. エピソード、c++メイン関数はマルチスレッドを使用し、pythonはサブスレッドに配置して実行する必要があります.サブスレッドで非同期呼び出しを行うとsegment faultがあり、同じコード順序で実行されても問題はありません.私は一度マルチスレッドの鍋だと疑っていたので、半日のc++マルチスレッド呼び出しpythonを試して、ついでにフィルタリングした資料を下に添付しました.サブスレッドロックmutexも試みた.ああ、言い忘れました.マルチスレッドがpythonを呼び出すときも、python解釈器にロックをかけます.次はC++マルチスレッド呼び出しpythonのリンクで、優先順位で排出されます.c++マルチスレッド呼び出しpython C++呼び出しPythonAPIスレッドステータスとグローバル解釈器ロックC++マルチスレッド呼び出しPythonスクリプト c++呼び出しpythonクラスc++を介してpythonクラスを呼び出す資料の一部を収集しました.例えば、1).c++python 3-インスタンス化クラスへのアクセス方法、2).c++呼び出しpythonインスタンスは、クラスマルチパラメータリストをパラメータとして、3).c++呼び出しpythonのコード、関数、クラスに関する.これらはnumpyを渡すときに適切な例が見つかりません.ここでは、ドキュメントが常に調整されていないことを説明していません.最後にpython関数を呼び出す方法に従って、グローバルクラスオブジェクトを作成して呼び出しを完了します. segmentationエラーおよびプログラム仮死python異常の場合、c++呼び出しpythonのエラー情報はタイムリーでなく、情報が少ない.したがって、仮死やセグメントエラーなどの奇妙な現象が発生した場合、pythonコード を優先的に調べる.
2)boostライブラリの方式パケットの基本構造C++はpythonを呼び出し配列 を渡す. debugで発生したエラーは、主にboost/numpyの問題で、インストール後もライブラリが見つからない場合があります.stackoverflowには会話があります.統一の問題です.環境変数を修正して解決する必要があります.まずここにメモしておきましょう. boostライブラリのインストール cc.cpp
simple_module.py
複数numpy戻り値
コードc++:cc.cpp↩︎
コードpython:simple_module.py ↩︎
現在、pythonエンジニアリングをc++で再構築しており、一部の後処理で再構築に時間がかかりたくないので、直接呼び出しに来ます.資料を探しながら作ったので、このデモを作るのに時間がかかったので、忘れないようにメモしておきます.
資料
多くのc++がpythonを呼び出す方法を探して、まず肯定することができるのは1つ以上の方法があって、直接pythonライブラリ、numpy arrayobjectライブラリを使ってします;もう1つはboost/python boost/numpyを使用する方法です.後者は融通がきかず、リンクライブラリの問題で、記録して後ろに置いた.
1)一般的な方式
g++ -o cc cc.cpp `pkg-config --cflags --libs opencv` -I/usr/include/python3.5 -lpython3.5m
から収集説明に値するのは、python 3.5 mはパス/usr/lib/x86_64-linux-gnu/libpython3.5m.so
の下で、自分で素を探すことができることです.また,コードにwarningがあり,マクロ定義を用いることで削除でき,コードにはPyRun_SimpleString ("import sys; sys.path.insert(0, '/home/ely/Desktop/Python/C-Python/')");
size_t init() {
import_array();
}
2)boostライブラリの方式
// c++: cc.cpp
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION // numpy/arrayobject.h
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char *argv[]) {
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
cout << argv[0] << endl;
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]
");
exit(1);
}
Py_SetProgramName(program); /* */
/* , 【1】 */
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"/home/user/project/run_retina/build\")");
import_array();
/* */
/* */
Mat sml_img = imread("lena.jpg");
/* , , .py, */
// PyObject *pName = PyUnicode_DecodeFSDefault("simple_module");
PyObject *pName = PyUnicode_FromString("simple_module");
/* */
if (pName == NULL) {
PyErr_Print();
throw std::invalid_argument("Error: PyUnicode_FromString");
}
PyObject *pModule = PyImport_Import(pName);
if (pModule == NULL) {
PyErr_Print();
throw std::invalid_argument("fails to import the module");
}
PyObject *pFunc = PyObject_GetAttrString(pModule, "super_resolution");
if (pFunc == NULL) {
PyErr_Print();
throw std::invalid_argument("fails to PyObject_GetAttrString");
}
/* */
PyObject *pArgs = PyTuple_New(2);
if (!sml_img.isContinuous()) { sml_img = sml_img.clone(); }
npy_intp dims[] = {sml_img.rows, sml_img.cols, 3};
PyObject *pValue = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, sml_img.data);
PyTuple_SetItem(pArgs, 0, pValue); /* pValue , */
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 2)); /* 2 */
/* */
PyObject *pRetValue = PyObject_CallObject(pFunc, pArgs);
/* */
PyArrayObject *ret_array;
PyArray_OutputConverter(pRetValue, &ret_array);
npy_intp *shape = PyArray_SHAPE(ret_array);
Mat big_img(shape[0], shape[1], CV_8UC3, PyArray_DATA(ret_array));
imwrite("aa.jpg", big_img);
/* */
//Py_DECREF(...);
return 0;
}
simple_module.py
# simple_module.py
import cv2 as cv
def simple_func(a,b):return a+b
def super_resolution(img, scale=4):
height, width = img.shape[:2]
dsize = (width*scale, height*scale)
big_img = cv.resize(img, dsize)
print(img.shape, big_img.shape)
cv.imwrite('aaa.jpg',big_img)
return big_img
複数numpy戻り値
/* */
PyArrayObject *r1, *r2, *r3, *r4, *r5, *r6;
PyArg_UnpackTuple(pRetValue, "ref", 6, 6, &r1, &r2, &r3, &r4, &r5, &r6);
npy_intp *shape1 = PyArray_SHAPE(r1);
npy_intp *shape2 = PyArray_SHAPE(r2);
npy_intp *shape3 = PyArray_SHAPE(r3);
npy_intp *shape4 = PyArray_SHAPE(r4);
npy_intp *shape5 = PyArray_SHAPE(r5);
npy_intp *shape6 = PyArray_SHAPE(r6);
std::cout << "shape[1]:" << shape1[0] <<
" shape2:" << shape2[0] << "," << shape2[1] <<
" shape3:" << shape3[0] <<
" shape4:" << shape4[0] << "," << shape4[1] <<
" shape5:" << shape5[0] <<
" shape6:" << shape6[0] << "," << shape6[1] <<
std::endl;
#
#-#-#-#-#-#-#-#-#-#-
list_id float32 (11,)
list_track float32 float32 (20, 2) (11,)
list_box float32 (11, 4)
entran;pass_by;ratio float32 (3,)
entrance_line;rec float32 (4, 2)
#-#-#-#-#-#-#-#-#-#-
shape[1]:11 shape2:20,2 shape3:11 shape4:11,4 shape5:3 shape6:4,2
コードc++:cc.cpp↩︎
コードpython:simple_module.py ↩︎