C++加持让python程序插上翅膀——利用pybind11进行c++和python联合编程示例
目录
- 0、前言
- 1、安装 pybind11库
- c++侧
- python侧
- 2、C++引入bybind11
- vs增加相关依赖及设置
- cpp中添加头文件及导出模块
- cpp中添加numpy相关数据结构的接收和返回
- 编译生成dll后改成导出模块同名文件的.pyd
- 3、python调用c++
- 4、C++引入bybind11
0、前言
在当今的计算机视觉和机器学习领域,Python 和 C++ 是两种最常用的编程语言。Python 以其简单易学、高效编程和强大的科学计算库而闻名,而 C++ 则以其高效性和强大的计算能力而著称。然而,这两种语言各有优劣,因此将它们结合起来使用可以发挥它们的优点,同时弥补它们的缺点。在本文中,我们将介绍如何在 Windows VS 环境下使用 pybind11 进行 C++ 和 Python 联合编程示例,进行机器视觉和相机位姿优化相关的程序开发。我们将使用 Python 3.7 和 C++,并利用 numpy 数组格式接收 Python 侧的两幅图像,并利用 g2o 进行 BA 优化,最后将优化结果以 numpy 数组形式返回 Python。

1、安装 pybind11库
首先,我们需要安装 pybind11 库。pybind11 是一个用于将 C++ 代码绑定到 Python 解释器的库,它提供了一种简单的方法来创建 Python 模块,这些模块可以直接调用 C++ 代码。
c++侧
pybind11库是一个纯头文件的库,其实只要从github上下载源码,即可供使用。
git clone https://github.com/pybind/pybind11.git

python侧
python侧,可以进入conda虚拟环境,注意需要3.7版本的python,直接pip安装:
pip install pybind11

2、C++引入bybind11
安装 pybind11 库后,我们可以开始编写 C++ 代码。以g2o ba为例,我们将上篇博文中的c++代码进行稍加改造,开个python的调用“接口”即可:
vs增加相关依赖及设置
使用bybind11,需要将下载的头文件路径引入项目,同时,需要将python3.7的头文件路径及lib引入及链接进项目。
(1)头文件路径加入:

(2)python3.7的lib加入:

(3)生成动态库dll类型:

cpp中添加头文件及导出模块
在c++程序中去掉main函数,添加头文件,及导出模块设置:


如上两图,在常规c++文件中首位加入头文件和导出模块定义,我们这次导出的是ab这个函数,ab是将上篇博文的main函数改成的。
cpp中添加numpy相关数据结构的接收和返回
// 将Python中的图像传递给C++进行处理
py::array_t<double> ab(py::array_t<uint8_t> &imge1, py::array_t<uint8_t> &imge2){//创建全0 numpy数组py::array_t<double> output_array({3,4});auto buf = output_array.mutable_data();for (int i = 0; i < 3; i++) {for (int j = 0; j < 4; j++) {buf[i * 4 + j] = 0;}}// 将输入图像转换为OpenCV的Mat对象auto bufimg1 = imge1.request();auto bufimg2 = imge2.request();int type = CV_8UC3;int channels = 3;if (bufimg1.ndim == 3) {channels = bufimg1.shape[2];if (channels == 4) {type = CV_8UC4;}}//如果不是3或4通道则退出if (channels != 3 && channels != 4) {return output_array;}cv::Mat img1(bufimg1.shape[0], bufimg1.shape[1], type, bufimg1.ptr);cv::Mat img2(bufimg2.shape[0], bufimg2.shape[1], type, bufimg2.ptr);
如上,我们ab函数,可以接收来自python的图像numpy数组,并将图像转化为了cv::mat格式,交给c++后续处理。最后返回numpy形式的g2o优化后的位姿数组:
g2o::VertexSE3Expmap* v = dynamic_cast<g2o::VertexSE3Expmap*>(optimizer.vertex(1));Eigen::Isometry3d pose = v->estimate();// 获取输出数组的指针auto output_ptr = output_array.mutable_data();// 将isometry的旋转矩阵和平移向量存储在numpy数组中Eigen::Map<Eigen::Matrix<double, 3, 4, Eigen::RowMajor>> result_map(output_ptr);result_map.block<3, 3>(0, 0) = pose.rotation().matrix();result_map.block<3, 1>(0, 3) = pose.translation();return output_array;
编译生成dll后改成导出模块同名文件的.pyd


将生成的dll改成g2opy.pyd

3、python调用c++
进入与c++依赖的同一个python环境,然后编辑简单的调用程序:

两帧图像送入c++,优化计算后返回输出:

本篇所有源码已上传,链接如下:
python实现C++程序g2o的ba优化模块调用,python侧的程序资源
本资源为python和C++联合编程的示例vs工程源码
4、C++引入bybind11
通过本文的示例,我们验证了如何在 Windows VS 环境下使用 pybind11 进行 C++ 和 Python 联合编程的可行性,可进一步进行机器视觉和相机位姿优化相关的程序开发。
有了C++的加持,python的机器人开发在性能上或者是解决方案上,又有了更多的可选项。可以发挥python的更大威力了,keep go on!
相关文章:
C++加持让python程序插上翅膀——利用pybind11进行c++和python联合编程示例
目录 0、前言1、安装 pybind11库c侧python侧 2、C引入bybind11vs增加相关依赖及设置cpp中添加头文件及导出模块cpp中添加numpy相关数据结构的接收和返回编译生成dll后改成导出模块同名文件的.pyd 3、python调用c4、C引入bybind11 0、前言 在当今的计算机视觉和机器学习领域&am…...
ubuntu20.04安装cv2
查看ubuntu的版本 cat /etc/lsb-release DISTRIB_IDUbuntu DISTRIB_RELEASE20.04 DISTRIB_CODENAMEfocal DISTRIB_DESCRIPTION"Ubuntu 20.04.3 LTS"更改镜像源 cp /etc/apt/sources.list /etc/apt/sources.list.bak cat > /etc/apt/sources.listdeb http://mirr…...
Android 13.0 recovery出厂时清理中字体大小的修改
1.前言 在13.0的系统rom定制化开发中,在recovery模块也是系统中比较重要的模块,比如恢复出厂设置,recovery ota升级, 清理缓存等等,在一些1080p的设备,但是density只是240这样的设备,会在恢复出厂设置的时候,显示的字体有点小, 产品要求需要将正在清理的字体调大点,这…...
spring+pom-注意多重依赖时的兼容问题[java.lang.NoSuchMethodError]
背景: 项目中同时引入了依赖A和依赖B,而这两个依赖都依赖于项目C,但它们指定的C版本不一致,导致运行时出现了错误。 报错如: java.lang.NoSuchMethodError 解决方案: 需要在项目pom文件中引入依赖C并指定需…...
Matalab插值详解和源码
转载:Matalab插值详解和源码 - 知乎 (zhihu.com) 插值法 插值法又称“内插法”,是利用函数f (x)在某区间中已知的若干点的函数值,作出适当的特定函数,在区间的其他点上用这特定函数的值作为函数f (x)的近似值,这种方…...
Flask 接口
目录 前言 代码实现 简单接口实现 执行其它程序接口 携带参数访问接口 前言 有时候会想着开个一个接口来访问试试,这里就给出一个基础接口代码示例 代码实现 导入Flask模块,没安装Flask 模块需要进行 安装:pip install flask 使用镜…...
Vue3 toRef函数和toRefs函数
当我们在setup 中的以读取对象属性单独交出去时,我们会发现这样会丢失响应式: setup() {let person reactive({name: "张三",age: 18,job: {type: "前端",salary:10}})return {name: person.name,age: person.age,type: person.jo…...
【论文阅读】(VAE-GAN)Autoencoding beyond pixels using a learned similarity metric
论文地址;[1512.09300] Autoencoding beyond pixels using a learned similarity metric (arxiv.org) / 一、Introduction 主要讲了深度学习中生成模型存在的问题,即常用的相似度度量方式(使用元素误差度量)对于学习良好的生成模型存在一定…...
verilog之wire vs reg区别
文章目录 一、wire vs reg二、实例一、wire vs reg wire线网: 仅支持组合逻辑建模必须由assign语句赋值不能在always块中驱动用于连接子模块的输出用于定义模块的输入端口reg寄存器: 可支持组合逻辑或时序逻辑建模必须在always块中赋值二、实例 wire [7:0] cnt; assign cnt …...
力扣面试经典150题详细解析
刷题的初心 众所周知,算法题对于面试大厂是必不可缺的一环,而且对于提高逻辑思维能力有着不小的提升。所以,对于程序员来讲,无论刚入行,还是从业多年,保持一个清醒的头脑,具备一个良好的设计思…...
【Java 进阶篇】唤醒好运:JQuery 抽奖案例详解
在现代社交网络和电商平台中,抽奖活动成为吸引用户、提升用户参与度的一种常见手段。通过精心设计的抽奖页面,不仅可以增加用户的互动体验,还能在一定程度上提高品牌的知名度。本篇博客将通过详细解析 JQuery 抽奖案例,带领你走进…...
数据处理生产环境_利用MurmurHash3算法在Spark和Scala中生成随机颜色
需求 根据给定的轨迹编号在这一列后面生成随机颜色_16 输入数据 ("吃饭", "123"), ("吃饭", "宋江"), ("郭靖", "宋江"), ("杨过", "奥特曼"), ("周芷若", "张无忌"),…...
便利工具分享:一个proto文件的便利使用工具
最近在研究序列化,每次的proto文件手敲生成代码指令都很麻烦,干脆自己写一个泛用脚本,这样以后使用时候就方便了。 废话不多说,首先上代码: #!/bin/bash # 检查是否提供了文件名参数 if [ -z "$1" ]; then…...
LeetCode704.二分查找及二分法
每日一题:LeetCode704.二分查找 LeetCode704.二分查找知识点:二分法解题代码 LeetCode704.二分查找 问题描述:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中…...
2023年R1快开门式压力容器操作证模拟考试题库及R1快开门式压力容器操作理论考试试题
题库来源:安全生产模拟考试一点通公众号小程序 2023年R1快开门式压力容器操作证模拟考试题库及R1快开门式压力容器操作理论考试试题是由安全生产模拟考试一点通提供,R1快开门式压力容器操作证模拟考试题库是根据R1快开门式压力容器操作最新版教材&#…...
探索NLP中的核心架构:编码器与解码器的区别
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
解决:Error: Missing binding xxxxx\node_modules\node-sass\vendor\win32-x64-83\
一、具体报错 二、报错原因 这个错误是由于缺少 node-sass 模块的绑定文件引起的。 三、导致原因 3.1、环境发生了变化 3.2、安装过程出现问题 四、解决方法步骤: 4.1、重新构建 node-sass 模块 npm rebuild node-sass 4.2、清除缓存并重新安装依赖 npm c…...
科研学习|科研软件——面板数据、截面数据、时间序列数据的区别是什么?
一、数据采集方式不同 面板数据是通过在多个时间点上对同一组体进行观测而获得的数据。面板数据可以是横向面板数据,即对同一时间点上不同个体的观测,也可以是纵向面板数据,即对同一个体在不同时间点上的观测。采集面板数据需要跟踪相同的个体…...
【UE5】物体沿样条线移动
目录 效果 步骤 一、使用样条线创建路径 二、创建沿样条线路径移动的物体 三、定义可移动物体的生成器 效果 步骤 一、使用样条线创建路径 先创建一个Actor蓝图,这里命名为“BP_Line” 该蓝图中只需添加一个样条组件 将“BP_Line”拖入场景中 按住Alt鼠标左键…...
Qt控件按钮大全
按钮 在 Qt 里,最常用使用的控件就是按钮了,有了按钮,我们就可以点击,从而响应事件,达到人机交互的效果。不管是嵌入式或者 PC 端,界面交互,少不了按钮。Qt 按钮部件是一种常用的部件之一,Qt 内置了六种按钮部件如下: (1) QPushButton:下压按钮 (2) QToolBu…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑 在电子商务领域,转化率与网站性能是决定商业成败的核心指标。今天,我们将深入解析不同类型电商平台的转化率基准,探讨页面加载速度对用户行为的…...
欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...
【Vue】scoped+组件通信+props校验
【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性, 令样式只作用于当前组件的标签 作用:防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...
轻量安全的密码管理工具Vaultwarden
一、Vaultwarden概述 Vaultwarden主要作用是提供一个自托管的密码管理器服务。它是Bitwarden密码管理器的第三方轻量版,由国外开发者在Bitwarden的基础上,采用Rust语言重写而成。 (一)Vaultwarden镜像的作用及特点 轻量级与高性…...
