0

I want to pass a image from a python code to a c++ function. My c++ function is in a .so file and is being loaded to python using ctypes. The c++ function takes argument of type Mat. The argument (i.e. the image) is passed from Python (using opencv).

When i try to run the above scenario, it throws error as below;

ctypes.ArgumentError: argument 1: : Don't know how to convert parameter 1

My code is given below: 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()

cpp code:

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

Checked for the error online and came to know that Opencv-python converts image data to numpy array. And Opencv-c++ uses Mat type. So how can I convert numpy array to Mat type or Pass Image from python to c++ function.

I do not want to use Boost::python

Thanks.

Community
  • 1
  • 1
TheLazy
  • 253
  • 1
  • 15
  • Possible duplicate of [C++ conversion from NumPy array to Mat (OpenCV)](https://stackoverflow.com/questions/29758662/c-conversion-from-numpy-array-to-mat-opencv) – paler123 Mar 15 '19 at 14:04

1 Answers1

0

I finally figured out the solution to the problem.

I had to convert the mat format to a numpy array. and pass this array as argument to the cpp function imgread().

The cpp function imgread() needs to receive it as a char pointer and then convert it to mat.

Modified 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()

At cpp side;

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

Cheers.

TheLazy
  • 253
  • 1
  • 15