python 与c++动态库之间传递opencv图片数据

python 与c++动态库之间传递opencv图片数据

  • python 与c++动态库之间传递opencv图片数据
    • C++函数
    • python端

python 与c++动态库之间传递opencv图片数据

调研了很多方法,发现利用ctypes模块调用动态库函数时,传递opencv的图片数据教程不多,而且也不好理解,根据我查阅的资料,写一个小demo

C++函数

// change uchar* to mat
Mat classA::readfrombuffer(uchar* frame_data,int height, int width,int channels){
    if(channels == 3){
        Mat img(height, width, CV_8UC3);
        uchar* ptr =img.ptr<uchar>(0);
        int count = 0;
        for (int row = 0; row < height; row++){
             ptr = img.ptr<uchar>(row);
             for(int col = 0; col < width; col++){
	               for(int c = 0; c < channels; c++){
	                  ptr[col*channels+c] = frame_data[count];
	                  count++;
	                }
	         }
        }
        return img;
    }
char* classA::mattostring(uchar* frame_data, int rows, int cols, int channels){
    Mat mat = readfrombuffer(frame_data,rows,cols,channels);
    if (!mat.empty()) {

        vector<uchar> data_encode;
        vector<int> compression_params;
        compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);  // png 选择jpeg  CV_IMWRITE_JPEG_QUALITY
        compression_params.push_back(1); //在这个填入你要的图片质量 0-9

        imencode(".png", mat, data_encode);

        std::string str_encode(data_encode.begin(), data_encode.end());
        char* char_r = new char[str_encode.size() + 10];     
        memcpy(char_r, str_encode.data(), sizeof(char) * (str_encode.size()));
        return char_r;
    }
}
extern "C"{
    char* mattostring(uchar* matrix, int rows, int cols, int channels)
    {
        classA t;
        return t.mattostring(matrix, rows, cols,  channels);
    }
}

设置两个类的函数,分别用来接收从Python传过来的uchar*指针并存成mat,、将处理后的mat再次解析成指针。
将类classA编译成动态库(.so)文件 classA.so

python端

import ctypes  
import cv2
import numpy as np
so = ctypes.cdll.LoadLibrary   
lib = so("classA.so")   # absolute path
print ('helloworld')

#image data
src = cv2.imread("1.jpg") #0-gray

cols = src.shape[1]
rows = src.shape[0]
channels = 0
if 3==len(src.shape):
	channels = 3	
src = np.asarray(src, dtype=np.uint8) 
src1 = src.ctypes.data_as(ctypes.c_char_p)
lib.mattostring.restype = ctypes.c_void_p
a = lib.mattostring(src1,rows,cols,channels)
b = ctypes.string_at(a,cols*rows*channels) #string_at(c_str_p) # 获取内容
nparr = np.frombuffer(b, np.uint8)
img_decode = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
cv2.imshow(" dst ", img_decode)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考链接:
python回调c++数据.
python调用动态库

你可能感兴趣的:(c++)