Directorio de artículos de la serie de procesamiento de imágenes
Directorio de artículos
- Directorio de artículos de la serie de procesamiento de imágenes
- prefacio
- 1. Compilación de DLL del sistema de Windows
- 2. Escribir código
- 3. Sistema Linux para compilación
- Cuarto, python llama a la biblioteca de enlaces dinámicos
- 5. Comparación temporal del búfer de la biblioteca de enlaces dinámicos de posprocesamiento con la imagen
- Resumir
prefacio
El algoritmo de procesamiento de imágenes está escrito en C++ y compilado en una biblioteca de enlaces dinámicos**.dll o .so**
Usando python para llamar a la biblioteca de enlaces dinámicos para el procesamiento lógico, la comparación de eficiencia de tiempo de la entrada de Opencv Mat con la biblioteca de enlaces dinámicos para Procesamiento de Mat a Python
1. Compilación de DLL del sistema de Windows
Abra Visual Studio para crear un nuevo proyecto DLL o un proyecto vacío.Si es un proyecto vacío, simplemente configure el .dll .
2. Escribir código
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;
}
Ejecutar compilación para generar el archivo xxx.dll
3. Sistema Linux para compilación
Puede optar por generar una biblioteca de enlaces dinámicos al compilar Si no sabe cómo compilar el archivo so, puede aprenderlo de Baidu.
Cuarto, python llama a la biblioteca de enlaces dinámicos
Método 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
Método 2 : xxx.py , en comparación con el método 1, el tiempo de procesamiento posterior al búfer es muy rápido
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. Comparación temporal del búfer de la biblioteca de enlaces dinámicos de posprocesamiento con la imagen
Se puede ver que, en comparación con el método 1, el posprocesamiento del método 2, que consume mucho tiempo, es casi insignificante.
Resumir
simplemente grabar