Detailed records of how python calls the dynamic link library .dll and .so

Image processing series article directory


foreword

The image processing algorithm is written in C++ and compiled into a dynamic link library**.dll or .so**
Using python to call the dynamic link library for logic processing, the time efficiency comparison of Opencv Mat input to the dynamic link library to output Mat to python processing

1. Windows system DLL compilation

Open Visual Studio to create a new DLL project or an empty project . If it is an empty project, just set the .dll .
insert image description here

2. Write code

xxx.h

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT void ImageEnhance(int rows, int cols, uchar *src_data, uchar *dst_data);

xxx.cpp

DLLEXPORT void ImageEnhance(int rows, int cols, uchar *src_data, uchar *dst_data)
{
    
    
	cv::Mat src = cv::Mat(rows, cols, CV_8UC3, src_data);
	Mat test2dst = test2(src);  //图像处理函数
	Mat dst = test7(test2dst);
	//uchar* dst_data = (uchar*)malloc(sizeof(uchar) * rows * cols * 3);
	memcpy(dst_data, dst.data, rows * cols * 3);
	//return dst_data;
}

Execute compilation to generate xxx.dll file

3. Linux system so compilation

You can choose to generate a dynamic link library when compiling . If you don’t know how to compile the so file, you can learn it from Baidu.

Fourth, python calls the dynamic link library

Method 1 : xxx.py

import ctypes
import time
def ImportDLL(img, IE_DLL):
	# if Windows
    IE_DLL = ctypes.CDLL(r"xxx.dll", winmode=0)
    # elif Linux
    ll = ctypes.cdll.LoadLibrary
    IE_DLL = ll("xxx.so")
    
    rows, cols, channel = img.shape[0], img.shape[1], img.shape[1]
    if channel < 3:   # 算法只处理3通道图像
        return -1
    # 获取numpy对象的数据指针
    frame_data = np.asarray(img, dtype=np.uint8)
    input_data = frame_data.ctypes.data_as(ctypes.c_char_p)

    # 设置输出数据类型为uint8的指针
    IE_DLL.ImageEnhance.restype = ctypes.POINTER(ctypes.c_uint8)
    # 调用dll内部的函数
    pointer = IE_DLL.ImageEnhance(ctypes.c_int(rows), ctypes.c_int(cols), input_data)

    # 从指针指向的地址中读取数据,并转为numpy array
    # 这种用np.fromiter处理dll输出的buffer的方法很慢
    t1 = time.time()
    np_result = np.array(np.fromiter(pointer, dtype=np.uint8, count=rows * cols * 3))
    dst = np_result.reshape((rows, cols, 3))
    print("=== dll_buffer to img: ", time.time() - t1)
    cv2.imshow("dst", dst)
    cv2.waitKey(0)
    return pointer, dst

Method 2 : xxx.py , compared to method 1, the post-buffer processing time is very fast

import ctypes
import time
def ImportDLL(img, IE_DLL):
	# if Windows
    IE_DLL = ctypes.CDLL(r"xxx.dll", winmode=0)
    # elif Linux
    ll = ctypes.cdll.LoadLibrary
    IE_DLL = ll("xxx.so")
    
    rows, cols, channel = img.shape[0], img.shape[1], img.shape[1]
    if channel < 3:   # 算法只处理3通道图像
        return -1
    # 获取numpy对象的数据指针
    frame_data = np.asarray(img, dtype=np.uint8)
    input_data = frame_data.ctypes.data_as(ctypes.c_char_p)

    # 设置输出数据类型为uint8的指针
    IE_DLL.ImageEnhance.restype = ctypes.POINTER(ctypes.c_uint8)
    # 调用dll内部的函数
    pointer = IE_DLL.ImageEnhance(ctypes.c_int(rows), ctypes.c_int(cols), input_data)

    # 从指针指向的地址中读取数据,并转为numpy array
    t1 = time.time()
    buffer_frome_memory = ctypes.pythonapi.PyMemoryView_FromMemory
    buffer_frome_memory.restype = ctypes.py_object
    buffer = buffer_frome_memory(pointer, rows * cols*3)
    dst = np.frombuffer(buffer, dtype=np.uint8)
    dst = np.reshape(dst, (rows, cols, 3))
    print("=== dll_buffer to img: ", time.time() - t1)
    cv2.imshow("dst", dst)
    cv2.waitKey(0)
    return pointer, dst

5. Time comparison of post-processing dynamic link library buffer to image

It can be seen that compared with method 1, the time-consuming post-processing of method 2 is almost negligible
insert image description here

Summarize

simply record

Guess you like

Origin blog.csdn.net/zengwubbb/article/details/127305511