关键词: DLL 、PYTHON 、 C++ 、 OPENCV 、 调用
最近在项目中遇到了一些问题,在这里记录一下。起因是这样的:有部分功能在python中处理的较慢,而在C++中使用相同的逻辑则使用的较快。面对这种困境的话我想到了C++可以制作dll文件或SO文件供python端调用,于是便有了本文中的记录。
现有一使用python调用opencv库读取的图像文件需要交付C++进行处理后返回结果,在这里我们简化一下流程:
graph TD
C++生成dll --> dll文件
python读取图像 --> 定义输入与输出类型
定义输入与输出类型 --> dll文件
dll文件 --> 得到返回结果
在上述的流程里我们参考VS的官方资料可以得到使用c++生成dll的步骤与例子,我就不过多阐述了;关于python调用dll的例子大家在python的官网上也可查阅到。我也不过过阐述了。在这里我主要记录一下难点:如何把一张三维图传递给dll
数据的传入与接收
在python端我们可通过numpy将cv2读取的图像数据转为指针的形式,然后再c++中将指针转三维图像。
python
import cv2
from ctypes import *
import numpy as np
def Mat2Uchar(matImg):
Mat = np.asarray(matImg, dtype=np.uint8)
Uchar = Mat.ctypes.data_as(c_char_p)
return Uchar
// pch.cpp: 与预编译标头对应的源文件
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/ml/ml.hpp"
// change uchar* to mat Uchar2Mat
cv::Mat Uchar2Mat(uchar* frame_data, int width, int height) {
cv::Mat img(height, width, CV_8UC3);
uchar* ptr = img.ptr<uchar>(0);
int count = 0;
int channels = 3;
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;
在调用的时候我们需要定义dll函数的输入类型以及输出类型
mydll = CDLL("C:/Users/kiven/Desktop/v56c/Dll1/x64/Debug/Dll1.dll")
mydll.SaveImg.argtypes = [c_char_p] # 定义输入值类型
mydll.SaveImg.restype = c_int # 定义返回值类型
py的对比C++的缺点
上述的两段代码我们已经实现了python调用c++生成的处理图像的dll函数。回过头来总结一下python相较于C++的缺点:
Python 是解释型语言,因此相较于编译型语言 C++,Python 的执行速度要慢一些。Python 需要将代码翻译成机器语言,这个过程需要花费一定的时间。尤其是在进行大量的数值计算时,Python 的性能表现较差。
GIL 的存在
Python 的全局解释器锁(Global Interpreter Lock,GIL)是一种限制 Python 多线程并行性能的机制。GIL 只允许 Python 解释器执行同一时刻只有一个线程的代码。这意味着 Python 在多线程应用中无法充分利用多核 CPU 的性能。
资源占用较多
Python 在执行代码时需要占用较多的内存资源,这可能会导致在处理大型数据集时出现内存不足的问题。此外,Python 的一些库和框架可能会占用大量的磁盘空间。
由于面对上述的明显缺点,我们可逆推一下:当我们的python任务面对:大量的数值计算任务、 需要充分利用多核CPU、处理大型数据集时内存不足时可利用好C++生成dll供python调用