无法在 Cython 中将 Numpy 数组转换为 OpenCV Mat

问题描述

我正在尝试将 numpy 数组转换为 cython 中的 opencv4 mat 以使用 cython 处理图像。为此,我按照tutorial(根据opencv4修改路径)并编写了我的opencvsample.pyx文件-

import numpy as np
cimport numpy as np # for np.ndarray
from cpython.ref cimport PyObject
from libcpp.string cimport string
from libc.string cimport memcpy

#ctypedef void* int_parameter
#ctypedef int_parameter two "2"
#ctypedef Point_[float,two] Point2f

cdef extern from "opencv2/core.hpp":
  cdef int  CV_WINDOW_AUTOSIZE
  cdef int CV_8UC3
 
cdef extern from "opencv2/core.hpp" namespace "cv":
  cdef cppclass Mat:
    Mat() except +
    void create(int,int,int)
    void* data
 
#cdef extern from "opencv2/highgui/highgui_c.h" namespace "cv":
cdef extern from "opencv2/opencv.hpp" namespace "cv":
  #void namedWindow(const string,int flag)
  void imshow(const string,Mat)
  int  waitKey(int delay)
 
cdef void ary2cvMat(np.ndarray ary,Mat& out):
  assert(ary.ndim==3 and ary.shape[2]==3,"ASSERT::3channel RGB only!!")
  ary = np.dstack((ary[...,2],ary[...,1],0])) #RGB -> BGR
   
  cdef np.ndarray[np.uint8_t,ndim=3,mode = 'c'] np_buff = np.ascontiguousarray(ary,dtype = np.uint8)
  cdef unsigned int* im_buff = <unsigned int*> np_buff.data
  cdef int r = ary.shape[0]
  cdef int c = ary.shape[1]
  out.create(r,c,CV_8UC3)
  memcpy(out.data,np_buff.data,r*c*3)
  #memcpy(out.data,im_buff,r*c*3)    # This doesn't work too
 
cdef showMat(Mat m):
  #namedWindow( "WIN",CV_WINDOW_AUTOSIZE )
  imshow("WIN".encode('UTF-8'),m)
  waitKey(0)
 
def openImage(pil_img):
  cdef Mat m
  ary2cvMat(np.array(pil_img),m)
  showMat(m)

和 setup.py-

import subprocess
from distutils.core import setup
from distutils.extension import Extension

import numpy
from Cython.Build import cythonize
from Cython.Distutils import build_ext

proc_libs = subprocess.check_output("pkg-config --libs opencv4".split())
proc_incs = subprocess.check_output("pkg-config --cflags opencv4".split())
libs = [lib for lib in str(proc_libs,"utf-8").split()]
# print("OPENCV LIBS=",libs)
print(numpy.get_include())

setup(
    cmdclass={"build_ext": build_ext},ext_modules=cythonize(
        Extension(
            "opencvsample",sources=["opencvsample.pyx"],language="c++",include_dirs=[
                numpy.get_include(),"/usr/include/opencv4/",],extra_link_args=libs,),compiler_directives={"language_level": "3"},annotate=True,)

然后我执行下面的命令来构建cython代码-

python3.8 setup.py build_ext --inplace 

成功构建后,我运行-

python3.8 -c "import opencvsample as to; from PIL import Image; to.openImage(Image.open('test.jpg'))" 

这给出了以下错误(我在 pwd 中有 test.jpg)-

<path/to/opencvsample.so> undefined symbol: _ZN2cv3Mat6createEiii

如何解决这个问题?看到错误,我认为是在 out.create 行。我不知道如何进一步。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)