c++读出像素矩阵_Python传numpy矩阵调c++(求3D图像连通区域)

v2-a96c448fe2595da1592296e14f74dc3b_1440w.jpg?source=172ae18b

Python有很多种调c++的方法,有的复杂有的简单,有时使用的时候反而不知道到底该用哪一种比较好,其实没有最好的方法,只有适合不适合自己。本文从我所遇到的问题说起,然后讲述另一种比较简单的python调c++并且传参numpy矩阵的方法。该方法调用的是python自带的ctypes库,所以使用该方法不用安装或配置任何地第三方库。

背景

之前项目遇到一个问题,求二值图像连通区域,对于一般的图像其实很简单,opencv有函数可以直接调。但是我要处理的是一个3D图像,opencv没有求3D图像连通区域的函数,所以只能自己写算法实现。该算法的核心思想是使用深度遍历来判断有多少像素点是连通的,所以,看到遍历两个字那python就肯定得排除了,所以就选择了c++。

从工程上来看,我的问题可以简单描述为:python环境下有一个numpy矩阵,以及若干参数,现需要传递给c++程序计算,然后返回一个新的numpy矩阵或者直接修改原始numpy矩阵。

然后,我开始思考我到底该使用哪种方式调c++,我也调研了一些方法,在此不一一列举,总的来说,它们的缺点是:额外学习成本相对较高、得另外安装软件或库支持(例如boost)、调试起来各种奇怪的错误等等。再加上我使用的Linux服务器我并没有sudo权限,故更加限制了这些方法的使用。这些方法或许很强大,但是我的要求很简单,只要能实现我上述的要求即可,于是我开始把目光转向ctypes。

解决方案

Python使用ctypes调c++很简单,网上有一堆相关教程,但这些教程中传递的参数基本都是int、float等等一些最基本的类型,而我现在要传的是一个很大的numpy矩阵,该怎么办?

v2-3c5b4099a6da570eecfc55679be27f65_b.png

我仔细研究了一下,发现可以通过ctypes传指针,而且numpy矩阵的指针也可以得到,惊喜。

v2-e2bb3d5df51059b2c8f7eee418542db5_b.png

利用ctypes,numpy矩阵的指针可以这样得到:

p 

于是我想,把numpy指针和numpy的shape信息传递过去不就相当于把整个numpy传递过去了吗?比如src是一个10*10的矩阵,指针为p,那么在c++中是不是就可以使用p[x][y]来定位具体的元素了?

想法是美好的,c++中可以使用p[x][y]的前提是p一个指针的指针,具体来说应该是int**类型的,而事实是p仅仅只是一个指针,是int*类型的,故,此思路行不通。

v2-53739a83e4c3d83f50ee8a5608d2dfa9_b.png

转念又一想,既然它是int*类型,那我就p[x]这样来取值,就把它当成一个一维数组,于是成功。

v2-1dc20f38ce4f8503e7f3a6a9624ef0de_b.png

那么现在问题来了,本来numpy矩阵是多维的,怎样跟一维数组对应呢?对,很简单,就是把多维的矩阵拉成一维的即可,相当于numpy的一个函数reshape,想想reshape成一维的之后元素是怎样跟之前对应的,就是这个对应关系。

比如一个二维矩阵shape为(10,20),那么其中的(i,j)点对应到一维数组里面的坐标就是i*20+j,三维矩阵道理相同。

至此,关键问题解决了。

后续思考

速度问题

现有这样一个任务:三维矩阵所有元素值加一,用遍历方法实现。我们分别使用两种方法来实现并且对比速度,1,纯python实现;2,c++实现,使用刚刚的方法调c++。

c++代码如下(demo.cpp):

#include 

python代码如下(main.py):

import 

然后使用下面命令编译成动态链接库:

=c++11 -shared -fPIC demo.c

最后运行main.py,结果如下:

(10, 512, 512)
c++   :  0.009840011596679688
python:  7.284840822219849

可见速度差别之大。

v2-4d9c44669152d3f7b0ab1dd193865a96_b.png

内存连续问题

可能有小伙伴已经想到了,该方法可行的另一个重要前提是numpy矩阵所有元素在内存中必须是连续的,若不连续肯定会出错。但是有时候我们传递的numpy矩阵可能就是不连续的,那该怎么办?很简单,仅仅只需改变一下传递姿势。

还拿刚才的例子举例,还是元素自加一,但是为了方便展示,我们把numpy矩阵改为二维的。首先创建一个10*10的值为1的二维矩阵m0,然后只取其左上角5*5的一部分m,可以看出m肯定是不连续的,现把m传参测试,python代码如下:

def 

结果:

(5, 5)
[[2 2 2 2 2 2 2 2 2 2][2 2 2 2 2 2 2 2 2 2][2 2 2 2 2 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1 1 1]]
[[2 2 2 2 2][2 2 2 2 2][2 2 2 2 2][1 1 1 1 1][1 1 1 1 1]]

可以看出,m0和m的值都被改变了,m的值并没有全部改变,只改变了一部分,而且m0刚好前5*5=25个值改变了,这说明了m并不是深拷贝,它仍然和m0共用一块内存空间,c++处理的时候只会连续着处理,所以只改变了连续空间的这一段长度为5*5的值。

当然,解决方法很简单,只需不让它们共用一份内存重新拷贝一份即可。上述第三行修改为:

m 

或:

m 

即可。

写在后面

前面已经说过,没有最好的方法,只有最适合自己的。我认为这种方法足够简单高效,前提是它能满足你的需求,比如类似传numpy矩阵这种。

对了,还有一点需要注意的地方,就是一定要保证numpy元素的数据类型跟c++中的一致,比如一个numpy的dtype为np.uint8,在c++中却使用int*,那肯定会出错,可以先使用astype函数把数据类型转成一致,然后再调c++。

还有,我本来要解决的问题是3D图像的连通区域求解,现已实现,速度贼快,感兴趣的小伙伴可以评论区回复。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android四大组件的作用简书,Android四大组件是什么

Android四大组件是:活动、服务、广播接收器、内容提供商。它们的英文名称是ACTIVITY、SERVICE、BroadcastReceiver、Content Provider。四个组件分别起到不同的作用,相互配合才能确保安卓系统的正常运行,因此是缺一不可的。Android四大组件及…

python 获取文件大小_第41p,超级重要,Python中的os库

大家好,我是杨数Tos,这是《从零基础到大神》系列课程的第41篇文章,第二阶段的课程:Python基础知识:Python内置库之os库的使用。学习本课程,建议先看一遍:【计算机基础知识】课程。os模块是与操作…

惠普打印机节能环保认证证书_低成本高效办公 苏宁惠普超品日这几款打印机了解下!...

【PConline 导购】说到打印机,很多朋友会想到公司那台不停运转的打印机。其实,伴随着近几年来打印机技术的成熟,其打印成本也一降再降,这就让有打印的需求的中下型企业,甚至个人,都会去选购一款合适的打印产…

vm客户机隔离不能选_开汽车美容店,这些位置绝对不能选,会让你门可罗雀,生意惨淡...

之前的文章里,讲了一些开汽车美容店选址的要领,今天,来聊聊一些更加细致的选址要素,让你避免错误选址而导致生意不佳。门面宽度小于2.5米的不要选一辆普通汽车的宽度在1.8米-2米之间,加上两侧后视镜各20公分左右&#…

markdown格式_第1篇:如何将Markdown笔记转入ANKI复习? | 学习骇客

用技术和心理学改善学习 第128次摘要:将日常使用的Markdown笔记软件与复习工具ANKI结合起来,于ANKI用户而言可以简化学习过程,于一般的学习者而言可以解决笔记“记而不学”的问题。本文摘选自视频课程《复习的技术,跟LEO学ANKI》(…

android手机无分区无法刷机,手机刷死了别说没提醒!安卓设备刷机前必看

大家好,清明节已经过去了,上班的感觉是不是很不爽?但是告诉大家一个好消息是:本周只需要煎熬三天,大家就又可以休息了!听了这个消息,不爽的心情是不是稍微好一些了?本期的微信和大家…

mysqlbinlog工具_带你解析MySQL binlog

前言:我们都知道,binlog可以说是MySQL中比较重要的日志了,在日常学习及运维过程中,也经常会遇到。不清楚你对binlog了解多少呢?本篇文章将从binlog作用、binlog相关参数、解析binlog内容三个方面带你了解binlog。1.bin…

inputstream 初始化_如何完美回答面试官问的Mybatis初始化原理!

前言对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外。本章将通过以下几点详细介绍MyBatis的初始化过程。MyBatis的初始化做了什么MyBatis基于XML配置文件创建Configuration对象的过程手动加载XML配置文件创建Configuration对象完成初…

html中加减号怎么输入,jQuery 实现点击加减号改变input标签中的value值,该怎么解决...

jQuery 实现点击加减号改变input标签中的value值我想点击左右两边的加减号,让中间input标签中的value属性值做出相应的改变,jQuery怎么实现?------解决思路----------------------$("button1").click(function(){var num $("…

java mybatis狂神说sql_狂神说MyBatis01:第一个程序

狂神说MyBatis系列连载课程,通俗易懂,基于MyBatis3.5.2版本,欢迎各位狂粉转发关注学习,视频同步文档。未经作者授权,禁止转载MyBatis简介环境说明:jdk 8 MySQL 5.7.19maven-3.6.1IDEA学习前需要掌握&#x…

鸿蒙系统暗黑2,暗黑破坏神2为什么被称为神作!看看装备强化系统就知道有多完美...

暗黑破坏神2之所以被玩家们称为神作是因为真的好玩,那么游戏的精髓到底在哪呢?个人觉得还要算其出色的装备强化系统,如果应用在现在的部分作品中,暗黑破坏神2的特色可以总结为肝,彻底肝。但它又区别于传统的必须肝&…

c语言api_用C语言来拓展python的功能

python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型软件系统的开发过程中。与其它…

html模拟在线股票走势,基于Html5的股票行情k线图源码

K线图 滑块控制这个K线图和flash实现的K线图非常接近,滑块控制是实现的难点,这里是根据滑块滑动的位置计算k线数据的范围,并实时重画,事实证明html5 canvas标签的性能还是相当的好的,在PC机上每秒可以重画20次以上&…

html5 css 三角形,css怎么画三角形?

css怎么画三角形?下面本篇文章就来给大家介绍一下使用CSS画三角形的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。css怎么画三角形?三角形实现原理:宽度width为0;height为0&#…

springboot整合JPA 多表关联 :一对多 多对多

补充一下自定义SQL 这是连表查询,可以任意查出字符,用Map接收 Testvoid test3() {JPAQueryFactory jpaQueryFactory new JPAQueryFactory(em);QStudent student QStudent.student;QMessage message QMessage.message;//constructor(StuMesDto.class, …

python网络库_python的网络库

最近新功能上线,帮忙加了几个监控脚本。上次用的perl,语法太随意了,看起来很是不整洁,自己写的都觉得不好,更不要说给别人看。好久没用python了,反正这次准备使用新的监控设计方案,刚好换一下。…

求一批整数中出现最多的个位数字_(43)C++面试之从1到n整数中1出现的次数

// 面试题43:从1到n整数中1出现的次数// 题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如// 输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。#incl…

j2me安装_Java第一步 JDK安装

安装JDK之前需要了解Windows下DOS命令winr 输入cmddir: 列出当前目录下的文件以及文件夹md:创建目录[文件夹]rd: 删除目录cd: 进入指定目录cd..:从当前目录退回到上一级目录cd:从当前目录退回到根目录&…

sql left join用法_图解 SQL 中 JOIN 的各种用法

点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!作者:CodingStarcnblogs.com/BoyceYang/p/3145279.html一、概要JOIN对于接触过数据库的人,这个词都不陌生,而且很多人很清楚各种JOIN,还有很…

超级计算机清华,从清华到华科 名校为何主办超级计算机大赛?

古罗马政治家、哲学家塞涅卡曾经说过:“自然赐给了我们知识的种子,而不是知识的本身。”在超级计算机领域,ASC世界大学生超级计算机竞赛正是这样一颗“种子”,北京、上海、广州、太原、武汉……ASC竞赛正在将超算的知识播撒到全球…