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

本文详细描述了如何在Qt应用中调用Python代码,处理QImage数据,并实现图像的计算和显示,涉及头文件配置、系统环境设置以及Python环境初始化和数据传递的过程。
摘要由CSDN通过智能技术生成

目的:

用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

三,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()"<<qImage.width()<<"qImage.height()"<<qImage.height()<<"qImage.format()"<<qImage.format()<<endl;

        int index =0;
        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);
            }
        }
        //qDebug()<< CArrays[width*height*3-1] <<endl;
        // 创建 NumPy 数组
        npy_intp dims[3] = { height, width, 3 }; // 假设图像是RGB格式的
        PyObject* imageArray = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, (void*)CArrays);



        //qDebug()<<"start UsePythonface"<<endl;
        PyObject* imageData = PyObject_CallMethod(pInstance, "process_frame", "O", imageArray);
        Py_DECREF(imageArray);
        if(!imageData)
        {
            PyErr_Print(); // 打印 Python 错误信息
            qDebug()<<"cant UsePythonface"<<endl;
            return;
        }

        // qDebug()<<"end UsePythonface"<<endl;
        mempcpy(CArrays,PyArray_DATA(imageData),width*height*3);
        QImage img((unsigned char*)CArrays, width, height,  QImage::Format_RGB888);
        //qDebug()<<"img.width()"<<img.width()<<"img.height()"<<img.height()<<"img.format()"<<img.format()<<endl;

        CArrays = nullptr;
        delete[] CArrays;

        Py_DECREF(imageData);
        disp_image( img);

    }
}

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chilian12321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值