如何将 python ndarray 转换为 c++ char*?

Posted

技术标签:

【中文标题】如何将 python ndarray 转换为 c++ char*?【英文标题】:how to convert python ndarray to c++ char*? 【发布时间】:2019-05-29 11:23:09 【问题描述】:

我正在使用 swig 来包装一个 c++ 库,它需要以 char* 格式获取图像数据。我可以在 python 中读取图像。但是我怎样才能把它转换成 c++ 呢?

我知道我可能需要使用 typemap。我尝试了几种方法,但我总是得到一张只有条纹的照片。

这是我的接口文件:

/* np2char */
%module np2char

%
    #define SWIG_FILE_WITH_INIT
    #include <opencv2/opencv.hpp>
    using namespace cv;
%

%inline %
  typedef char* Image_Data_Type;
  typedef int Image_Width_Type;
  typedef int Image_Height_Type;

  struct Image_Info 
      Image_Data_Type imageData;
      Image_Width_Type imageWidth;
      Image_Height_Type imageHeight;
  ;

  int Imageshow(Image_Info ImageInfo) 
      Mat img(ImageInfo.imageHeight, ImageInfo.imageWidth, CV_8UC3, ImageInfo.imageData);
      imshow("img_in_cpp", img);
      waitKey(0);
      destroyAllWindows();
      return 0;
  

%

这是我的 setup.py:

"""
setup.py
"""
from distutils.core import setup,Extension

module1 = Extension('_np2char',
            sources=['np2char_wrap.cxx'],
            include_dirs=['include'],
            libraries = ["opencv_world342"],
            library_dirs=["lib"],
            )

setup(name = "np2char",
      version = "1.0",
      description = 'This package is used to trans ndarray to char*',
      ext_modules = [module1],
      py_modules=['np2char'])

这是我的python文件:

import np2char
import cv2

img1 = cv2.imread("1.jpg")

img_info = np2char.Image_Info()
img_info.imageData = img1.data
img_info.imageWidth = img1.shape[1]
img_info.imageHeight = img1.shape[0]

np2char.Imageshow(img_info)

我试过了

%typemap(in) Image_Data_Type
  $1 = reinterpret_cast<char*>(PyLong_AsLongLong($input));

,在 python 端 img_info.imageData=img1.ctypes.data 但我仍然只有条纹。似乎图像数据被复制到内存中的其他地方。在这个过程中,它被'\0'截断了。

【问题讨论】:

【参考方案1】:

哈哈,我自己想通了。 在SWIG Documentation 5.5.2,

SWIG 假定 char * 类型的所有成员都已使用 malloc() 动态分配,并且它们是以 NULL 结尾的 ASCII 字符串。 如果此行为与您在应用程序中需要的不同,可以使用 SWIG“memberin”类型映射来更改它。

所以,我需要的是“typemap(memberin)”:

%typemap(in) Image_Data_Type
  $1 = reinterpret_cast<Image_Data_Type>(PyLong_AsLongLong($input));


%typemap(memberin) Image_Data_Type
  $1 = $input;


%typemap(out) Image_Data_Type
  $result = PyLong_FromLongLong(reinterpret_cast<__int64>($1));

使用整数传递指针有点难看。有没有更好的办法?

【讨论】:

以上是关于如何将 python ndarray 转换为 c++ char*?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 cupy.ndarray 转换为标量?

如何将张量转换为 ndarray(内部带有对抗图像的张量)

如何将PyTorch张量转换为Numpy ndarray

PySpark:Spark数据框-将ImageSchema列转换为nDArray作为新列

将 numpy.ndarray 转换为小写

TypeError:获取参数数组的类型无效 numpy.ndarray,必须是字符串或张量。 (不能将 ndarray 转换为张量或操作。)