栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

QT下C++调用python程序,含第三方库numpy和tensorflow

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

QT下C++调用python程序,含第三方库numpy和tensorflow

QT下C++调用python程序,含第三方库
  • 相关配置
  • 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位。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/339580.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号