pybind11实现numpy和OpenCV Mat的数据交互

2024-01-08 22:04

本文主要是介绍pybind11实现numpy和OpenCV Mat的数据交互,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、编译安装pybind11

下载源代码:https://github.com/pybind/pybind11,

文档:https://pybind11.readthedocs.io/en/stable/compiling.html

解压后进入到命令行,如果有conda环境,就先进入想要的conda环境,再运行下面的指令

mkdir build
cd build
cmake ..
make -j8
sudo make install

2 编译动态链接库

新建CMakeLists.txt,如下,需要安装opencv,安装教程参考Ubuntu 18.04 安装opencv4.2.0,如果遇到IPPICV问题参考解决编译opencv时,卡在IPPICV

cmake_minimum_required(VERSION 3.4...3.18)
project(test LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)#使用这个命令的前提是pybind11, make install过
find_package(pybind11 REQUIRED)
find_package(OpenCV)#添加头文件,CMAKE_SOURCE_DIR是CMakeLists.txt所在的位置
include_directories(${CMAKE_SOURCE_DIR}/ ${OpenCV_INCLUDE_DIRS})#添加CPP文件, PROJECT_NAME = test
pybind11_add_module(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/test.cpp)#指定动态链接库的位置
# link_directories(/home/hnty/SDK/iRaySDK/dev/bin)#指定编译依赖库,PUBLIC是必须的参数,也可以换成其他关键字
target_link_libraries(${PROJECT_NAME} PUBLIC pthread ${OpenCV_LIBS})#指定安装位置,表示编译的结果安装在 ${CMAKE_INSTALL_PREFIX}/site-packages 目录下,能够直接在python代码中导入
#make install 命令先编译后安装,一步到位
# set(CMAKE_INSTALL_PREFIX /home/hnty/miniconda3/envs/dev/lib/python3.7/)
# install(TARGETS ${PROJECT_NAME} DESTINATION site-packages)

新建test.cpp如下:

#include <opencv2/opencv.hpp>
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>namespace py = pybind11;
using namespace cv;typedef struct test
{/* data */int ages;std::string name;cv::Mat pic;
} Person;Person handle;void setData(int ages, std::string &name, py::array_t<uint8_t>& img)
{handle.ages = ages;handle.name = name;//np.ndarray -> opencv matauto rows = img.shape(0);auto cols = img.shape(1);auto channels = img.shape(2);auto type = CV_8UC3;handle.pic = cv::Mat(rows, cols, type, (unsigned char*)img.data());
}py::dict getData()
{// 在cpp中可以直接使用python内置的数据类型,还是很方便的py::dict pydata;pydata["name"] = handle.name;pydata["ages"] = handle.ages;auto rows = handle.pic.rows;auto cols = handle.pic.cols;auto channels = handle.pic.channels();//opencv mat -> np.ndarraypy::array_t<uint8_t> output_img(py::buffer_info(handle.pic.data, sizeof(uint8_t), //itemsizepy::format_descriptor<uint8_t>::format(), 3, // ndimstd::vector<size_t> {rows, cols , channels}, // shapestd::vector<size_t> {cols * sizeof(uint8_t)*3, sizeof(uint8_t)*3, sizeof(uint8_t)} // strides));pydata["pic"] = output_img;return pydata;
}PYBIND11_MODULE(test, m) {m.doc() = "pybind11 example plugin"; // optional module docstringm.def("getData", &getData, "A function which adds two numbers");m.def("setData", &setData, "test func");
}

新建test.py:

from build import testimport cv2
import numpy as npimg = cv2.imread("oil-bin-1.png") #换成你自己的图片
ages = 23
name = "kitty"test.setData(ages, name, img)res = test.getData()
print(res['name'], res['ages'])
cv2.imwrite("output.png", res["pic"])

3、测试

将上述3个文件放到同一个目录,然后在命令行中进入到改目录,依次运行。会生成output.png

mkdir build
cd build
cmake ..
make
cd ..
python test.py

文件夹格式如下:

4、总结

使用pybind11相比ctypes方法ctypes实现python和c之间的数据交互-CSDN博客,更加简单、易用。但ctypes的优势在于不用额外配置库,python内置了。

这篇关于pybind11实现numpy和OpenCV Mat的数据交互的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/584969

相关文章

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert