【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)

简介: 【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)

前言

  最近在项目中遇到了一些问题,在这里记录一下。起因是这样的:有部分功能在python中处理的较慢,而在C++中使用相同的逻辑则使用的较快。面对这种困境的话我想到了C++可以制作dll文件或SO文件供python端调用,于是便有了本文中的记录。

需求

  现有一使用python调用opencv库读取的图像文件需要交付C++进行处理后返回结果,在这里我们简化一下流程:

image.png


  在上述的流程里我们参考VS的官方资料可以得到使用c++生成dll的步骤与例子,我就不过多阐述了;关于python调用dll的例子大家在python的官网上也可查阅到。我也不过过阐述了。在这里我主要记录一下难点:如何把一张三维图传递给dll

数据的传入与接收

  在python端我们可通过numpy将cv2读取的图像数据转为指针的形式,然后再c++中将指针转三维图像。

python

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

C++

ini

复制代码

// 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函数的输入类型以及输出类型

ini

复制代码

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调用

结尾

  Python 调用 C++ 生成的 DLL 函数可以实现 Python 与 C++ 之间的数据交换和函数调用。通过 ctypes 模块,Python 可以动态链接 DLL 文件,并调用其中的函数。同时,使用 C++ 生成 DLL 文件的过程中需要注意一些问题,如函数声明需要添加 __declspec(dllexport) 关键字等。此外,对于 C++ 中一些复杂的数据类型,需要使用 ctypes 提供的相关类型进行转换。最后,需要注意在使用 ctypes 调用 DLL 函数时,需要指定函数的返回类型和参数类型。通过正确使用 ctypes 模块,Python 可以与 C++ 相结合,实现更加强大的功能和更高效的计算。


相关文章
|
1月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
330 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
2月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
49 4
|
12天前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
15 2
|
2月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
|
1月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
272 3
|
1月前
|
C++ Python
探索Python与C/C++混合编程的艺术
探索Python与C/C++混合编程的艺术
36 1
|
2月前
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
61 11
|
2月前
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
25 3
|
2月前
|
Python Windows
Python:执行py命令,提示: Can‘t find a default Python.
Python:执行py命令,提示: Can‘t find a default Python.
WK
|
2月前
|
机器学习/深度学习 Java 程序员
为什么Python比C++慢很多?
Python相较于C++较慢主要体现在:动态类型系统导致运行时需解析类型,增加开销;作为解释型语言,逐行转换字节码的过程延长了执行时间;自动内存管理和垃圾回收机制虽简化操作但也带来了额外负担;全局解释器锁(GIL)限制了多线程性能;尽管Python库方便灵活,但在性能上往往不及C++底层库。然而,Python在某些领域如数据分析、机器学习中,凭借其高级别抽象和简洁语法仍表现出色。选语言需依据具体应用场景和需求综合考量。
WK
74 1