Как конвертировать Python ndarray в C ++ char *? - PullRequest
0 голосов
/ 29 мая 2019

Я использую 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 Но все же я получил только полосы.Кажется, что imagedata копируется в другие места в памяти.В процессе он был усечен '\ 0'.

1 Ответ

0 голосов
/ 30 мая 2019

хаха, я сам понял.В Документация SWIG 5.5.2 ,

SWIG предполагает, что все члены типа char * были динамически распределены с помощью malloc () и что они являются строками ASCII с завершением NULL.Если это поведение отличается от того, что вам нужно в ваших приложениях, для его изменения можно использовать карту типов 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));
}

Немного некрасиво использовать целое число для передачи указателя.Есть ли способ лучше?

...