ctypes实现numpy和OpenCV Mat之间的数据交互

2024-01-09 06:20

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

1、目的

将c/c++编译成动态链接库,通过python调用,实现常见变量比如int,字符串之间的交互,以及np.ndarray和cv::Mat间的交互. 更简单的方式参考:pybind11实现numpy和OpenCV Mat的数据交互-CSDN博客

2 步骤

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

cmake_minimum_required(VERSION 3.10)
project(test)
add_definitions(-std=c++11)
add_definitions(-DAPI_EXPORTS)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)
find_package(OpenCV)
include_directories(${OpenCV_INCLUDE_DIRS})
add_library(myplugins SHARED ${PROJECT_SOURCE_DIR}/test.cpp)
target_link_libraries(myplugins ${OpenCV_LIBS})

新建test.cpp

#include <opencv2/opencv.hpp>
#include <string>
using namespace std;#if defined(_MSC_VER)
#define API __declspec(dllimport)
#else
#define API
#endif  // API_EXPORTStypedef struct test
{/* data */int ages;std::string name;cv::Mat pic;
} Person;extern "C" API void * init(int age_,  char * name_ptr, unsigned char *src_data, int rows, int cols)
{Person *handle = new Person();std::string name_ = name_ptr;handle->ages = age_;handle->name = name_;handle->pic = cv::Mat(rows, cols, CV_8UC3, src_data);return (void*) handle;
}extern "C" API int get_ages(void* handle_)
{Person * handle = (Person*)handle_;return handle->ages;
}extern "C" API char* get_name(void* handle_)
{Person * handle = (Person*)handle_;return (char*)handle->name.c_str();
}extern "C" API void get_pic(void* handle_, int rows, int cols, unsigned char* out_data)
{Person * handle = (Person*)handle_;cv::imshow("raw", handle->pic);cv::waitKey();//数据处理//....//返回结果memcpy(out_data, handle->pic.data, rows*cols*3);
}

新建test.py,具体转换见代码注释

from ctypes import *
import cv2
import numpy as np
import numpy.ctypeslib as npct#加载链接库
lib = CDLL('./build/libmyplugins.so')#定义函数的输入类型和输出类型
lib.get_ages.restype = c_int
lib.get_ages.argtypes = [c_void_p] #输入句柄(指针)
lib.get_name.restype = c_void_p #返回char*
lib.get_name.argtypes = [c_void_p] #输入句柄(指针)img = cv2.imread("oil-bin-1.png") #修改成自己的图片
ages = 23
name = bytes("kitty", "utf-8") #要对应c函数中的char*,需要转为二进制(rows, cols) = (img.shape[0], img.shape[1])
image_type = npct.ndpointer(dtype = np.uint8, ndim = 3, shape = img.shape, flags="C_CONTIGUOUS") #指定numpy图片的格式lib.init.restype = c_void_p #返回句柄(指针)
lib.init.argtypes = [c_int, c_void_p, image_type, c_int, c_int]#将np格式的图片传递到c
hd = lib.init(c_int(ages), c_char_p(name), img, c_int(rows), c_int(cols))print(lib.get_ages(hd)) #返回整数,直接打印
name = c_char_p(lib.get_name(hd)).value #返回char*, 需要转换
print(name.decode('utf-8')) #解码成字符串##第一种读取图片的方式,使用ndpointer指定图片类型
out_image = np.zeros_like(img).astype(np.uint8) #需要先开辟内存
lib.get_pic.argtypes = [c_void_p, c_int, c_int, image_type]
lib.get_pic(hd, c_int(rows), c_int(cols), out_image)
cv2.imshow("out1", out_image)##第二种读取图片的方式,不使用ndpointer指定图片类型
out_image = np.zeros_like(img).astype(np.uint8) #需要先开辟内存
lib.get_pic.argtypes = [c_void_p, c_int, c_int, c_void_p] #句柄(指针),rows,cols, 图片指针
lib.get_pic(hd, c_int(rows), c_int(cols), out_image.ctypes.data_as(POINTER(c_ubyte)))cv2.imshow("out2", out_image)
cv2.waitKey()

3、测试

将上述3个文件放到同一个目录,然后在命令行中进入到该目录,依次运行,会弹出图片,单击图片,按任意键即可

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

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



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

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import