QT C++调用python传递RGB图像和三维数组,并接受python返回值(图像)

目的:

用QT调用python代码,将QT读取的图像(Qimage)作为参数传入python中,将QT的三维数组作为参数传递给python,python接收QT传入的图像进行计算,将结果返回给QT并显示。

一   .pro 头文件的配置,和lib库的配置


INCLUDEPATH += \
    -I D:\tools\python3_9\include
INCLUDEPATH += \
    -I D:\tools\python3_9\Lib\site-packages\numpy\core\include
LIBS += \
    -L D:\tools\python3_9\libs -lpython39

 二。系统环境变量的配置  在path添加 python环境   D:/tools/python3_9

QT C++调用python传递RGB图像和三维数组,并接受python返回值(图像)_第1张图片

QT C++调用python传递RGB图像和三维数组,并接受python返回值(图像)_第2张图片

三,python环境的初始化

//加入python环境
  1.  Py_SetPythonHome(L"D:/tools/python3_9");

  2. 类似于先连接上Python    Py_Initialize();


  3. 注意使用这个 import_array1(); 用于后边numpy数组的调用,   import_array();会报无返回值的错误。

其他看代码注释

 


void  MainForm::init_python()
{

    //加入python
    Py_SetPythonHome(L"D:/tools/python3_9");
    // 1. 类似于先连接上Python

    Py_Initialize();
    import_array1();
    if (!Py_IsInitialized()) {
        qDebug() << "Fail to init Python.";
    }


    // 2. 加入python文件的路径
    PyRun_SimpleString("import os");
    PyRun_SimpleString("import sys");
    std::string path = "sys.path.append('E:/DigitalScreen/StuEmo/realtime_detect')";
    PyRun_SimpleString(&path[0]);
    PyRun_SimpleString("print(sys.path)");

    // 3. 找到要用的python文件
     PyObject * pModule = PyImport_ImportModule("capture_xjh");
    if (pModule == NULL) {
        qDebug() <<"Fail to load Python module (capture_xjh.py)";
    }

    // 1. 找到Python的类
    PyObject* pDict = PyModule_GetDict(pModule);
    if(!pDict) {
        qDebug() << "Cant find dictionary.";
    }
     Py_DECREF(pModule);

    PyObject* pClassCalc = PyDict_GetItemString(pDict, "RtDetector");
    if (!pClassCalc) {
        qDebug() << "Cant find PythonClass class.";
    }
    Py_DECREF(pDict);
    // 2. 初始化对象
    PyObject* pConstruct = PyInstanceMethod_New(pClassCalc);
    if (!pConstruct) {
        qDebug() << "Cant find PythonClass constructor.";
    }
    Py_DECREF(pClassCalc);

    PyObject* cons_args = PyTuple_New(5);
    PyTuple_SetItem(cons_args, 0, Py_BuildValue("s",  "group1"));
    PyTuple_SetItem(cons_args, 1, Py_BuildValue("s",  "E:/DigitalScreen/StuEmo/GROUP_DATA/"));
    PyTuple_SetItem(cons_args, 2, Py_BuildValue("s",   "E:/DigitalScreen/StuEmo/weights/detr_face_body.pt"));
    PyTuple_SetItem(cons_args, 3, Py_BuildValue("s",   "E:/DigitalScreen/StuEmo/realtime_detect/Person_reID/model/ft_ResNet50/net_last.pth"));
    PyTuple_SetItem(cons_args, 4, Py_BuildValue("O",   Py_True));

    pInstance = PyObject_CallObject(pConstruct, cons_args);
    if (!pInstance) {
        qDebug() << "Cant construct instance.";
    }
    Py_DECREF(cons_args);
    Py_DECREF(pConstruct);

    // PyObject* methods = PyObject_Dir(pInstance);
    // if (methods) {
    //     // 遍历返回的方法列表
    //     for (Py_ssize_t i = 0; i < PyList_GET_SIZE(methods); ++i) {
    //         PyObject* method = PyList_GET_ITEM(methods, i);
    //         const char* methodName = PyUnicode_AsUTF8(method);
    //         qDebug() << "Method Name:" << methodName;
    //     }
    //     Py_DECREF(methods);
    // } else {
    //     qDebug() << "Failed to get methods of the instance.";
    // }

    //测试
    // PyObject* pRet =PyObject_CallMethod(pInstance,"addTest1","ii",5,6);
    // if (!pRet) {
    //     qDebug() << "Cant addTest.";
    // }
    // else{
    //     double ret = PyFloat_AsDouble(pRet);
    //     qDebug() << "sum: " << ret;
    // }

    // Py_DECREF(pRet);

    //通过图片检测
     QImage qImage ("E:/DigitalScreen/StuEmo/images/1.png");
     UsePythonface(  qImage);
}

四,Qimage  转换到numpy数组的使用

Qimage 传入的是QImage::Format_RGB888格式图片,通过

  for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                QRgb pixel = qImage.pixel( j,i);

                CArrays[index++] = qRed(pixel);
                CArrays[index++] = qGreen(pixel);
                CArrays[index++] = qBlue(pixel);
            }
        }转换为一维数组CArrays

 // 创建 NumPy 数组 通过CArrays转换而来
        npy_intp dims[3] = { height, width, 3 }; // 图像是RGB格式的
        PyObject* imageArray = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, (void*)CArrays);

返回值又通过 mempcpy(CArrays,PyArray_DATA(imageData),width*height*3);
  再生成      QImage img((unsigned char*)CArrays, width, height,  QImage::Format_RGB888);

调用 disp_image( img);显示图像


void MainForm::UsePythonface( QImage qImage)
{
    if(!qImage.isNull())
    {
        int width = qImage.width();
        int height = qImage.height();
        unsigned char *CArrays = (unsigned  char*)malloc(sizeof(unsigned char) * width*height*3);
        qDebug()<<"qImage.width()"<

你可能感兴趣的:(qt,c++,python)