- 相关配置
- python和QT程序
- 所遇问题
1. .pro配置文件
在.pro文件中增加python的部分路径(按照自己的安装路径修改),如下语句:
INCLUDEPATH += D:Python36include
D:Python36Libsite-packagesnumpycoreinclude
LIBS += D:Python36libspython36.lib
2. 程序位置
将python程序拷贝到QT程序所在文件夹,并在项目中将.py文件添加至Other files。
python和QT程序在QT的.cpp主程序中添加头文件及程序:
#include#include int main() { string str ="image.png"; //Python初始化 Py_Initialize(); if( !Py_IsInitialized() ) qDebug()<<"初始化失败"; //导入sys模块设置模块地址 PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')"); //改成自己Py文件的路径 PyRun_SimpleString("sys.path.append('D:Python36Libsite-packages')"); //改成自己Python安装文件的路径 //创建模块指针 PyObject* pModule = Pyimport_importModule("predict"); //调用predict程序 if (pModule==NULL) { qDebug()<<"获取模块指针失败"; return -1; } //创建函数指针 PyObject* pFunc= PyObject_GetAttrString(pModule,"get_image"); //调用get_image函数 if(pFunc==NULL) { qDebug()<<"获取模块指针失败"; return -1; } PyObject* pPara = PyTuple_New(1); //1个输入参数 PyTuple_SetItem(pPara,0,Py_BuildValue("s",str.data())); //传入字符串 // 调用函数,并得到 python 类型的返回值 PyObject* Py_result = PyObject_CallObject(pFunc, pPara); //判断返回是否为空 if(Py_result != NULL) { vector > array; //获取矩阵维度 npy_intp *Py_array_shape = PyArray_DIMS(Py_result); int arrayrow = Py_array_shape[0]; int arraycol = Py_array_shape[1]; vector temp; int thisdata; //array for(npy_intp row = 0; row < (npy_intp)arrayrow; row++) { temp.clear(); for(npy_intp col = 0; col < (npy_intp)arraycol; col++) { thisdata = *(int*)PyArray_GETPTR2(Py_result,row,col); temp.push_back(thisdata); } array.push_back(temp); } //至此,python返回的array数据解析完成 } }
python程序如下,以predict.py命名:
import tensorflow as tf
from tensorflow.keras.layers import (Conv2D, Input, Lambda, Reshape, Softmax)
from tensorflow.keras.models import Model
import numpy as np
from PIL import Image
def Deepmodel(input_shape=(416, 416, 3), classes=21, alpha=1.):
img_input = Input(shape=input_shape)
x = Conv2D(classes, (1, 1), padding='same')(img_input)
x = Lambda(lambda xx: tf.image.resize(xx, size_before3[1:3]))(x)
x = Reshape((-1, classes))(x)
x = Softmax()(x)
model = Model(img_input, x)
return model
HEIGHT = 416
WIDTH = 416
NCLASSES = 9
model = Deepmodel(classes=NCLASSES, input_shape=(HEIGHT, WIDTH, 3))
model.load_weights("logs/ep072-loss0.038-val_loss0.284.h5")
def get_image(file_path):
img = Image.open(file_path)
img = img.resize((WIDTH,HEIGHT), Image.BICUBIC)
img = np.array(img) / 255
img = img.reshape(-1, HEIGHT, WIDTH, 3)
pr = model.predict(img)[0]
pr = pr.reshape((int(HEIGHT), int(WIDTH), NCLASSES)).argmax(axis=-1)
return pr
所遇问题
1. Pyimport_importModule为空
情况一:说明第三方库的路径没有完全导入,参考相关配置;
情况二:如果导入keras的话,会有这样的问题,将keras换成tensorflow.keras。
2. PyObject_CallObject为空
将
PyObject* pPara = PyTuple_New(1);
pPara = Py_BuildValue("s",str.data());
换成
PyObject* pPara = PyTuple_New(1);
PyTuple_SetItem(pPara,0,Py_BuildValue("s",str.data()));
3. 解析返回数据
python只有一个numpy返回值时,如上示例。
python有多个numpy返回值时,需要增加PyArg_UnpackTuple语句,将每个numpy拆分,例如:
PyArrayObject *Py_array1, Py_array2; PyArg_UnpackTuple(Py_result, "ref", 2, 2, &Py_array1, &Py_array2);
再对每个Py_array分别操作。具体可参考C++调用python,并且在python和C++之间传输数据(numpy和mat数据)
4. 编译不通过
说明QT和python的配置平台不一致,要想编译通过,需要QT和python为相同的配置平台,要么二者都是32位,要么二者都是64位。



