Передача изображения из оболочки python в функцию С++

Я хочу передать изображение из кода Python в функцию С++. Моя функция С++ находится в файле .so и загружается в python с использованием ctypes. Функция С++ принимает аргумент типа Mat. Аргумент (то есть изображение) передается из Python (с использованием opencv).

Когда я пытаюсь запустить описанный выше сценарий, он выдает ошибку, как показано ниже;

ctypes.ArgumentError: аргумент 1:: Не знаю, как преобразовать параметр 1

Мой код приведен ниже: test.py

import cv2
from ctypes import *

testso = CDLL("./libvideoread.so")
cap = cv2.VideoCapture("Bigbunny.mp4")
if(cap.isOpened == False):
    print("error")
else:
    frame_width = int(cap.get(3))
    frame_height = int(cap.get(4))
    cv2.namedWindow('frame',cv2.WINDOW_NORMAL)
    while(cap.isOpened):
       ret,frame = cap.read()
       if ret:
          testso.imgread(frame)
       else:
           break

cap.release()
cv2.destroyAllWindows()

СРР-код:

void imgread(Mat frame)
{
     /*Do something*/
}

Проверил ошибку онлайн и узнал, что Opencv-python преобразует данные изображения в массив numpy. И Opencv-С++ использует тип Mat. Итак, как я могу преобразовать массив numpy в тип Mat или передать изображение из функции python в функцию c++.

Я не хочу использовать Boost::python

Спасибо.


person TheLazy    schedule 15.03.2019    source источник
comment
Возможный дубликат преобразования C++ из массива NumPy в Mat (OpenCV)   -  person paler123    schedule 15.03.2019


Ответы (1)


Наконец-то я понял решение проблемы.

Мне пришлось преобразовать формат мата в массив numpy. и передать этот массив в качестве аргумента функции cpp imgread().

Функция cpp imgread() должна получить его как указатель на символ, а затем преобразовать его в мат.

Модифицированный test.py;

import cv2
from ctypes import *

testso = CDLL("./libvideoread.so")
cap = cv2.VideoCapture("Bigbunny.mp4")
if(cap.isOpened == False):
    print("error")
else:
    frame_width = int(cap.get(3)) # Width is 1280
    frame_height = int(cap.get(4)) # Height is 720
    cv2.namedWindow('frame',cv2.WINDOW_NORMAL)
while(cap.isOpened):
   ret,frame = cap.read()
   if ret:
      # Next 3 lines convert frame data to numpy array
      testarray1 = np.fromstring(frame, np.uint8) 
      testarray2 = np.reshape(testarray1, (720, 1280, 3))
      framearray = testarray2.tostring()

      #Send framearray to the cpp function.
      testso.imgread(framearray)
   else:
       break

 cap.release()
 cv2.destroyAllWindows()

На стороне cpp;

void imgread(unsigned char* framedata)
{
  cv::Mat frame(cv::Size(1280,720), CV_8UC3, framedata);
   /*Do something*/
}

Ваше здоровье.

person TheLazy    schedule 29.05.2019