Python이 동적 링크 라이브러리 .dll 및 .so를 호출하는 방법에 대한 자세한 기록

이미지 처리 시리즈 기사 디렉토리


머리말

이미지 처리 알고리즘은 C++로 작성되고 동적 링크 라이브러리**.dll 또는 .so**로 컴파일됩니다.
Python을 사용하여 논리 처리를 위한 동적 링크 라이브러리 호출, 동적 링크 라이브러리에 대한 Opencv Mat 입력의 시간 효율성 비교 매트를 파이썬 처리로 출력

1. Windows 시스템 DLL 컴파일

Visual Studio를 열어 새 DLL 프로젝트 또는 빈 프로젝트를 만들고 빈 프로젝트인 경우 .dll을 설정하면 됩니다 .
여기에 이미지 설명 삽입

2. 코드 작성

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;
}

컴파일을 실행하여 xxx.dll 파일 생성

3. 리눅스 시스템 컴파일

컴파일할 때 동적 링크 라이브러리를 생성하도록 선택할 수 있습니다 .so 파일을 컴파일하는 방법을 모르는 경우 Baidu에서 배울 수 있습니다.

넷째, Python은 동적 링크 라이브러리를 호출합니다.

방법 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

방법 2 : xxx.py , 방법 1에 비해 사후 버퍼 처리 시간이 매우 빠름

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. 후처리 동적 링크 라이브러리 버퍼와 이미지의 시간 비교

방법 1과 비교하여 시간이 많이 소요되는 방법 2의 후처리는 거의 무시할 수 있는 수준임을 알 수 있습니다.
여기에 이미지 설명 삽입

요약하다

단순히 기록

추천

출처blog.csdn.net/zengwubbb/article/details/127305511