c++向python传递图片 高效方法 mat转numpy

11 篇文章 1 订阅
				版权声明:本文为博主原创文章,未经博主允许不得转载。					https://blog.csdn.net/u014679795/article/details/82215511				</div>
							<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
    								            <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
					<div class="htmledit_views" id="content_views">
            <p>c++向python传输图片 效率最好的自然是传到python的格式自动为图像格式,不需要做二次转换</p>

将图片数据转化为python中numpy的格式,opencv在python中图像表示方法为numpy的array格式,

如果是多通道情况,最常见的就是红绿蓝(RGB)三通道,则第一个维度是高度,第二个维度是宽度,第三个维度是通道数

在代码中表达方式如下

import numpy as np
import cv2
img = np.array([
    [[255, 0, 0], [0, 255, 0], [0, 0, 255]],
    [[255, 255, 0], [255, 0, 255], [0, 255, 255]],
    [[255, 255, 255], [128, 128, 128], [0, 0, 0]],
], dtype=np.uint8)
 
# 用opencv存储
cv2.imwrite('img_cv2.jpg',img)

那么c++中讲mat格式图像转化为numpy格式如下

void init_numpy()
{
    import_array();
}
 
void main(){
// 初始化Python
    //在使用Python系统前,必须使用Py_Initialize对其
    //进行初始化。它会载入Python的内建模块并添加系统路
    //径到模块搜索路径中。这个函数没有返回值,检查系统
    //是否初始化成功需要使用Py_IsInitialized。
    Py_Initialize();
    init_numpy();
    // 检查初始化是否成功
    if ( !Py_IsInitialized() )
    {
        return -1;
    }
 
    PyRun_SimpleString("print 'hello'");
    PyObject *pName,*pModule,*pDict,*pFunc,*pArgs;
    // 载入名为pytest的脚本
    //pName = PyString_FromString("testvideo");
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('/home/vetec-p/Pan/project/run-maskrcnn')");
    PyRun_SimpleString("sys.path.append('/home/vetec-p/Pan/project/run-maskrcnn/build')");
    PyRun_SimpleString("sys.path.append('/home/vetec-p/Pan/Detectron-master')");
    //    PyRun_SimpleString("print sys.path");
    //();
    pModule = PyImport_ImportModule("infer_one_pic");
    if ( !pModule )
    {
        printf("can't find testvideo.py");
        //getchar();
        return -1;
    }
    pDict = PyModule_GetDict(pModule);
    if ( !pDict )
    {
        return -1;
    }
    pFunc = PyDict_GetItemString(pDict, "run");
    if ( !pFunc || !PyCallable_Check(pFunc) )
    {
        printf("can't find function [run]");
        getchar();
        return -1;
    }
    for(int i=1;i<200;i++)
    {
        clock_t start,finish;
        double totaltime;
        start=clock();
        Mat img=imread("/media/vetec-p/Data/Rubbish/maskrcnn_dataset/0803_mask/train_all/pic/"+to_string(i)+".png");
        if(img.empty())
            return -1;
        //        imshow("img",img);
        //        waitKey(0);
 
        clock_t s1;
        s1=clock();
        PyObject *PyList  = PyList_New(data_size);//定义一个与数组等长的PyList对象数组
        PyObject *ArgList = PyTuple_New(1);
 
 
        auto sz = img.size();
        int x = sz.width;
        int y = sz.height;
        int z = img.channels();
        uchar *CArrays = new uchar[x*y*z];
        int iChannels = img.channels();
        int iRows = img.rows;
        int iCols = img.cols * iChannels;
        if (img.isContinuous())
        {
            iCols *= iRows;
            iRows = 1;
        }
 
        uchar* p;
        int id = -1;
        for (int i = 0; i < iRows; i++)
        {
            // get the pointer to the ith row
            p = img.ptr<uchar>(i);
            // operates on each pixel
            for (int j = 0; j < iCols; j++)
            {
                CArrays[++id] = p[j];//连续空间
            }
        }
 
        npy_intp Dims[3] = { y, x, z}; //注意这个维度数据!
        PyObject *PyArray = PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, CArrays);
        PyTuple_SetItem(ArgList, 0, PyArray);
        clock_t e1=clock();
 
 
 
        cout<<"\n赋值为"<<(double)(e1-s1)/CLOCKS_PER_SEC<<"秒!"<<endl;
 
        //PyTuple_SetItem(ArgList, 0, PyList);//将PyList对象放入PyTuple对象中
        PyObject *pReturn = PyObject_CallObject(pFunc, ArgList);
        clock_t e2=clock();
        //cout<<"\n detect为"<<(double)(e2-e1)/CLOCKS_PER_SEC<<"秒!"<<endl;
    }
 
 
    Py_DECREF(pModule);
 
    // 关闭Python
    Py_Finalize();
 
 
    return 0;
}

在python端直接当做图像格式使用即可

import cv2
 
def run(imgdata):
    cv2.imshow("img", img)
    cv2.waitKey(0)

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
C++ 中,Mat 是 OpenCV 库中表示图像和矩阵的数据结构,而 numpyPython 中表示矩阵和数组的数据结构。如果你需要将 C++ 中的 Mat 换为 numpy 中的数组,可以使用以下代码: ```python import numpy as np import cv2 # 读取图像文件 img = cv2.imread("image.jpg") # 将 Mat 换为 numpy 数组 img_array = np.array(img) # 输出数组的形状和数据类型 print("Array shape:", img_array.shape) print("Array data type:", img_array.dtype) ``` 在上面的代码中,我们首先使用 OpenCV 的 imread 函数读取图像文件,得到一个 Mat 对象。然后,使用 numpy 的 array 函数将该对象换为 numpy 数组。最后,输出数组的形状和数据类型。 需要注意的是,这种方式会将图像中的所有通道(例如 RGB 通道)合并成一个数组。如果你希望将每个通道分别保存在不同的数组中,可以将 numpy 数组的最后一个维度拆分成多个维度,例如: ```python # 将 Mat 换为 numpy 数组 img_array = np.array(img).transpose(2, 0, 1) # 输出数组的形状和数据类型 print("Array shape:", img_array.shape) print("Array data type:", img_array.dtype) # 分别输出每个通道的数组 for i, channel in enumerate(("B", "G", "R")): print(f"{channel} channel:") print(img_array[i]) ``` 在上面的代码中,我们使用 numpy 的 transpose 函数将 numpy 数组的最后一个维度拆分成三个维度,分别对应于 RGB 通道。然后,输出数组的形状和数据类型,并分别输出每个通道的数组。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值