Image processing series article directory
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 .
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
Summarize
simply record