尝试编写 C++ 包装函数时,无法在 Cython 中将 Numpy 数组转换为 OpenCV Mat

2024-03-13

我正在尝试实施cv::cuda::warpPerspective在 python2 中,有一篇关于如何做到这一点的非常精彩的文章:link https://stackoverflow.com/a/42401559/7555390。我按照该帖子中描述的说明进行操作,但是,我得到了Segmentation fault (core dumped) error.

我能够将错误分配给GpuWrapper.pyx文件第 11 行:

pyopencv_to(<PyObject*> _src, src_mat)

似乎无法将 numpy 数组转换为 opencv Mat。

我不确定哪里出了问题以及如何修复。

得到的python脚本Segmentation fault (core dumped)错误如下:

import cv2
import numpy as np
import csv
import timeit
import GpuWrapper

while (1):
    start = timeit.default_timer()
    eo_img = cv2.imread('./sample/eo.png', 1)
    nir_img = cv2.imread('./sample/nir.png', 0)
    with open('./sample/reg.csv', 'rb') as f:
        line = csv.reader(f)
        reg_line = list(line)
    reg = np.array(reg_line[0], dtype=np.float32)
    new_reg = reg.reshape((3,3))
    print nir_img.shape
    dist = GpuWrapper.cudaWarpPerspectiveWrapper(nir_img, new_reg, (2448,2048))
    cv2.imwrite('./sample/result.png', dist)
    end = timeit.default_timer()
    print end-start

另外值得一提的是,在编译 cython 代码时,它有一些警告:

[1/1] Cythonizing GpuWrapper.pyx
running build_ext
building 'GpuWrapper' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/home/xinyao/Tensorflow/local/lib/python2.7/site-packages/numpy/core/include -I-I/usr/local/include/opencv -I-I/usr/local/include -I/usr/include/python2.7 -c GpuWrapper.cpp -o build/temp.linux-x86_64-2.7/GpuWrapper.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
In file included from /home/xinyao/Tensorflow/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1809:0,
                 from /home/xinyao/Tensorflow/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:18,
                 from pyopencv_converter.cpp:2,
                 from GpuWrapper.cpp:544:
/home/xinyao/Tensorflow/local/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
 #warning "Using deprecated NumPy API, disable it by " \
  ^
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/GpuWrapper.o -o /home/xinyao/projects/image_reg/GpuWrapper.so -L/usr/local/lib -lopencv_cudabgsegm -lopencv_cudaobjdetect -lopencv_cudastereo -lopencv_dnn -lopencv_ml -lopencv_shape -lopencv_stitching -lopencv_cudafeatures2d -lopencv_superres -lopencv_cudacodec -lopencv_videostab -lopencv_cudaoptflow -lopencv_cudalegacy -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_photo -lopencv_imgcodecs -lopencv_cudawarping -lopencv_cudaimgproc -lopencv_cudafilters -lopencv_video -lopencv_objdetect -lopencv_imgproc -lopencv_flann -lopencv_cudaarithm -lopencv_viz -lopencv_core -lopencv_cudev

根据这似乎没问题here https://stackoverflow.com/questions/25789055/cython-numpy-warning-about-npy-no-deprecated-api-when-using-memoryview.

环境: CUDA 8.0 OpenCV 3.3 无需额外模块 乌班图16.04 Python 2.7 赛通0.26

我努力了cv::cuda::warpPerspective在 C++ 中,它在 GPU 支持下工作得很好。我也尝试过cv2.warpPerspective在 python 中,没有任何问题(所以我的 python opencv 被正确编译)。

另一件事是我不能直接用 g++ 编译 opencv C++ 代码,我需要添加额外的标志来做到这一点,就像这样:g++ -o main main.cc `pkg-config opencv --cflags --libs否则我在寻找 opencv 时会遇到问题:

main.cc:(.text+0x45): undefined reference to `cv::cuda::GpuMat::defaultAllocator()'
main.cc:(.text+0x9b): undefined reference to `cv::imread(cv::String const&, int)'
main.cc:(.text+0x104): undefined reference to `cv::imread(cv::String const&, int)'
main.cc:(.text+0x140): undefined reference to `cv::cuda::GpuMat::defaultAllocator()'
main.cc:(.text+0x1a5): undefined reference to `cv::Mat::eye(int, int, int)'
main.cc:(.text+0x31f): undefined reference to `cv::cuda::Stream::Null()'
main.cc:(.text+0x3d6): undefined reference to `cv::cuda::warpPerspective(cv::_InputArray const&, cv::_OutputArray const&, cv::_InputArray const&, cv::Size_<int>, int, int, cv::Scalar_<double>, cv::cuda::Stream&)'
main.cc:(.text+0x487): undefined reference to `cv::imwrite(cv::String const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)'

不确定这是否是一个因素,但我也无法解决它。

UPDATE:我能够使用 pdb 来分配错误:

>$gdb --args python opencv_reg_cuda.py
>$run

    Starting program: /usr/bin/python opencv_reg_cuda.py
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    [New Thread 0x7fffc6b83700 (LWP 10933)]
    [New Thread 0x7fffc4382700 (LWP 10934)]
    [New Thread 0x7fffc1b81700 (LWP 10935)]
    [New Thread 0x7fffc1380700 (LWP 10936)]
    [New Thread 0x7fffbcb7f700 (LWP 10937)]
    [New Thread 0x7fffba37e700 (LWP 10938)]
    [New Thread 0x7fffb7b7d700 (LWP 10939)]
    (2048, 2448)

    Thread 1 "python" received signal SIGSEGV, Segmentation fault.
    pyopencv_to (o=o@entry=0x7fffb37e3b70, m=..., info=...) at pyopencv_converter.cpp:210
    210     if( !PyArray_Check(o) )

>$bt

    #0  pyopencv_to (o=o@entry=0x7fffb37e3b70, m=..., info=...) at pyopencv_converter.cpp:210
    #1  0x00007fffb33c56f5 in pyopencv_to<cv::Mat> (name=0x7fffb33c98d8 "<unknown>", m=..., o=0x7fffb37e3b70) at pyopencv_converter.cpp:349
    #2  __pyx_pf_10GpuWrapper_cudaWarpPerspectiveWrapper (__pyx_v(short, long double, char)=__pyx_v(short, long double, char)@entry=0x7fffb37e3b70, __pyx_v__M=__pyx_v__M@entry=0x7fffb37e3c60, 
        __pyx_v__size_tuple=__pyx_v__size_tuple@entry=0x7ffff7e80b90, __pyx_v__flags=<optimized out>, __pyx_self=<optimized out>) at GpuWrapper.cpp:1796
    #3  0x00007fffb33c76a2 in __pyx_pw_10GpuWrapper_1cudaWarpPerspectiveWrapper (__pyx_self=<optimized out>, __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at GpuWrapper.cpp:1737
    #4  0x00000000004c468a in PyEval_EvalFrameEx ()
    #5  0x00000000004c2765 in PyEval_EvalCodeEx ()
    #6  0x00000000004c2509 in PyEval_EvalCode ()
    #7  0x00000000004f1def in ?? ()
    #8  0x00000000004ec652 in PyRun_FileExFlags ()
    #9  0x00000000004eae31 in PyRun_SimpleFileExFlags ()
    #10 0x000000000049e14a in Py_Main ()
    #11 0x00007ffff7810830 in __libc_start_main (main=0x49dab0 <main>, argc=2, argv=0x7fffffffde38, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffde28)
        at ../csu/libc-start.c:291
    #12 0x000000000049d9d9 in _start ()

>list

    205             }
    206         }
    207         return true;
    208     }
    209 
    210     if( !PyArray_Check(o) )
    211     {
    212         failmsg("%s is not a numpy array, neither a scalar", info.name);
    213         return false;
    214     }

似乎它无法将 o 传递给 PyArray_Check,但我不知道发生了什么以及如何修复它。


最后我找到了答案。 为了使用 numpy,我们必须调用numpy.import_array()。详细信息请参见Here https://docs.scipy.org/doc/numpy-1.10.0/user/c-info.how-to-extend.html#required-subroutine.

找到在哪里调用它可能很棘手,对于我的情况,我只是调用我的 .pyx 脚本:

import numpy as np  # Import Python functions, attributes, submodules of numpy
cimport numpy as np  # Import numpy C/C++ API

np.import_array()

def cudaWarpPerspectiveWrapper(np.ndarray[np.uint8_t, ndim=2] _src,
                               np.ndarray[np.float32_t, ndim=2] _M,
                               _size_tuple,
                               int _flags=INTER_NEAREST):
    # Create GPU/device InputArray for src

    cdef Mat src_mat
    cdef GpuMat src_gpu
    pyopencv_to(<PyObject*> _src, src_mat)
    src_gpu.upload(src_mat)

    # Create CPU/host InputArray for M
    cdef Mat M_mat = Mat()
    pyopencv_to(<PyObject*> _M, M_mat)

    # Create Size object from size tuple
    # Note that size/shape in Python is handled in row-major-order -- therefore, width is [1] and height is [0]
    cdef Size size = Size(<int> _size_tuple[0], <int> _size_tuple[1])

    # Create empty GPU/device OutputArray for dst
    cdef GpuMat dst_gpu = GpuMat()
    warpPerspective(src_gpu, dst_gpu, M_mat, size, 2)

    # Get result of dst
    cdef Mat dst_host
    dst_gpu.download(dst_host)
    cdef np.ndarray out = <np.ndarray> pyopencv_from(dst_host)
    return out

然后一切都像魔术一样运作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试编写 C++ 包装函数时,无法在 Cython 中将 Numpy 数组转换为 OpenCV Mat 的相关文章

随机推荐

  • 在 if 语句中展开多个选项

    我想在一个 if 语句中解开两个选项 但编译器抱怨密码常量运算符后的预期表达式 可能是什么原因 if let email self emailField text let password self passwordField text d
  • 如何强制 Google Charts vAxes 渲染?

    目前 我在页面上渲染两个图表 我正在使用谷歌的可视化图表库 由于页面大小问题 vAxes 在某些 大部分时间拒绝渲染 如果我给它足够的空间 它就会很好地渲染轴 但如果它稍微偏离 即使有足够的空间容纳这些该死的轴 它们也会拒绝渲染 我不能这样
  • Windows Phone IE 移动 bug 具有透明背景图像和底部绝对定位

    我在使用 WP IE 时遇到两个问题 透明背景图像的透明边框上有伪影 绝对定位的 div 到页面底部在浏览器导航栏和页面底部之间留下约 5px 的白色间隙 请注意 我使用 div 而不是 img 来处理CSS 视网膜图像替换 http co
  • 透明状态栏不适用于 windowTranslucentNavigation="false"

    我正在开发一个Activity我需要在运行 5 0 API 21 的设备上使导航栏不透明 并使状态栏透明 下面是我使用的样式 以及对我的问题的解释 AppTheme延伸Theme AppCompat Light NoActionBar
  • 从非托管 C 调用托管代码

    因此 经过大约一天半的时间 我的进展为零 我需要用 C 语言编写一个 DLL 用作现有应用程序的插件 DLL 必须由 Visual Studio 2008 编译器使用以下选项进行编译 cl DNT40 DPOMDLL DCRTAPI1 cd
  • MySQL 多 ID 查找

    我正在尝试向系统添加全文搜索 我想要编写的查询需要涉及多次查找 然后进行搜索 如果可能的话 我有一张教师表和一张科目表 teacherProfile teacherId int primary key subjectOneId int su
  • 读取时出现 Ruby CSV UTF8 编码错误

    这就是我正在做的 csv CSV open file name r 我用它来测试 line csv shift while not line nil puts line line csv shift end 我遇到了这个 ArgumentE
  • html中有vr(垂直规则)吗?

    我知道html中有hr 水平规则 但我不相信有vr 垂直规则 我错了吗 如果没有 为什么没有垂直规则 不 没有垂直规则 编辑 现在是 2021 年 我回答这个问题十二年后 我不再认为我原来的解释是正确的 原文解释 拥有一个没有逻辑意义 HT
  • 具有相同名称/路径的多个 cookie 的浏览器行为

    我对当存在多个具有相同名称和路径且对当前域有效的 cookie 时各种浏览器的行为感兴趣 例如 浏览器存储了这两个cookie key value path domain foo bar baz key value path domain
  • 为什么 svn import 选项无法检测文件重复

    如果我想签入 SVN 中已存在的同名文件 在这种情况下我将无法提交 例如 Name doc and name doc 但是 在这种情况下我将能够导入 这种情况甚至适用于文件夹名称 这可以防止将来进行结账操作 有没有办法防止文件或文件夹重复
  • 运行桌面版 libgdx 示例 gdx-invaders 时出现 java.lang.NoClassDefFoundError

    我正在构建 libgdx 的 gdx invaders 示例 有两个项目 gdx入侵者 基础项目 作为桌面 Java 应用程序运行gdx 入侵者 android项目 依赖于 gdx invaders 并作为 Android 应用程序运行 我
  • Golang反射:无法设置包装结构的接口字段

    我正在尝试实现一种方法 该方法可以更改可以具有任意结构的对象中的字段值 当我有指向结构的指针时 字段的遍历没有问题 但是 当我有一个接口不包装指向结构的指针而是包装结构本身时 我无法设法更改字段 简而言之 The following doe
  • 我什么时候必须声明 session_start(); ?

    所以我是 PHP 的初学者 所以我需要一些帮助 我正在尝试确定何时开始会议 我应该在用户首次注册时执行此操作还是在用户登录时执行此操作 另外 会话是否 通用 意味着当我检查会话时它会起作用还是我必须在所有页面中包含一个文件来检查某人是否有会
  • .NET 中的 DDD / 聚合

    我一直在阅读 Evans 关于 DDD 的书 并且正在思考应该如何在 NET 中实现聚合 目前 我只能想出一种方法 将聚合隔离在单独的类库中 然而 这似乎有点矫枉过正 我更愿意将所有域对象保留在一个库中 我想知道是否有不同的方法 1 lib
  • 使用 Criteria API 从 NHibernate 获取不同的结果集?

    我试图使用 NHibernate 中的 Criteria API 获得不同的结果 我知道使用 HQL 可以做到这一点 但我更喜欢使用 Criteria API 来执行此操作 因为我的应用程序的其余部分仅使用此方法编写 我找到这个论坛帖子 h
  • 使用 NEON 对 ARM 汇编中的四字向量中的所有元素求和

    我对组装相当陌生 尽管手臂信息中心通常很有帮助 但有时这些说明可能会让新手感到有点困惑 基本上我需要做的就是对四字寄存器中的 4 个浮点值求和 并将结果存储在单个精度寄存器中 我认为 VPADD 指令可以满足我的需要 但我不太确定 你可以尝
  • 如何从NLP Tree中提取元素?

    我正在使用NLP包来解析句子 我怎样才能从Tree创建的输出 例如 我想抓住名词短语 NP 来自下面的示例 library NLP library openNLP s lt c Really I like chocolate because
  • 在所有页面中正确包含 php 标头

    我会包含一个 php 标头 mysite com header php 在站点的所有页面中 怎样做才正确呢 有相关链接 这没有帮助 你可以这样做 include SERVER DOCUMENT ROOT header php
  • 侦听大多数端口时出现 Node.js EACCES 错误

    我正在测试一个应用程序 希望在heroku 上运行 但在本地也遇到问题 当它运行 http Server listen 时 它给我一个 EACCES 错误 但它只发生在某些端口上 所以 我在本地运行 joe joebuntu node gt
  • 尝试编写 C++ 包装函数时,无法在 Cython 中将 Numpy 数组转换为 OpenCV Mat

    我正在尝试实施cv cuda warpPerspective在 python2 中 有一篇关于如何做到这一点的非常精彩的文章 link https stackoverflow com a 42401559 7555390 我按照该帖子中描述