python - 将 numpy 数组传递给 cython 中的 C 函数

标签 python c arrays numpy cython

我正在用 Cython 包装第三方相机库接口(interface),这样我就可以从 Python 程序中调用它。在大多数情况下,一切都运行良好,但我在 acquireImage() 函数中遇到了障碍。我试图创建一个连续的 numpy 数组,将其传递给库,并在库完成填充后获取结果。最后,我想复制那个数组, reshape 它并返回它。 ( reshape 的东西还没有编码)

这是我的代码:

cpixis.pxd:

ctypedef bint rs_bool
ctypedef unsigned short uns16
ctypedef short int16
ctypedef unsigned int uns32
ctypedef unsigned int* uns32_ptr
ctypedef void* void_ptr
ctypedef char* char_ptr
ctypedef short* int16_ptr
ctypedef struct rgn_type:
        short s1
        short s2
        short sbin
        short p1
        short p2
        short pbin
ctypedef rgn_type* rgn_const_ptr
ctypedef rgn_type* rgn_ptr

#cdef CAM_NAME_LEN 32

cdef extern from "/usr/local/pvcam/examples/pvcam.h":
    cdef enum cam_open:
        OPEN_EXCLUSIVE
    cdef enum exposure:
        TIMED_MODE, STROBED_MODE, BULB_MODE, TRIGGER_FIRST_MODE, FLASH_MODE, VARIABLE_TIMED_MODE, INT_STROBE_MODE
    cdef enum readout:
        READOUT_NOT_ACTIVE, EXPOSURE_IN_PROGRESS, READOUT_IN_PROGRESS, READOUT_COMPLETE, 
        FRAME_AVAILABLE = READOUT_COMPLETE, READOUT_FAILED, ACQUISITION_IN_PROGRESS, MAX_CAMERA_STATUS
    rs_bool pl_pvcam_init()
    rs_bool pl_pvcam_uninit()
    rs_bool pl_cam_get_name(int16 cam_num, char_ptr camera_name)
    rs_bool pl_cam_open(char_ptr camera_name, int16_ptr hcam, int16 o_mode)
    rs_bool pl_cam_close(int16 hcam)
    rs_bool pl_pvcam_uninit()
    rs_bool pl_exp_init_seq()
    rs_bool pl_exp_setup_seq (int16 hcam, uns16 exp_total,
                              uns16 rgn_total, rgn_const_ptr rgn_array,
                              int16 exp_mode, uns32 exposure_time,
                              uns32_ptr exp_bytes)
    rs_bool pl_exp_start_seq (int16 hcam, void_ptr pixel_stream)
    rs_bool pl_exp_check_status (int16 hcam, int16_ptr status, uns32_ptr bytes_arrived)
    int16 pl_error_code()
    rs_bool pl_exp_finish_seq (int16 hcam, void_ptr pixel_stream, int16 hbuf)
    rs_bool pl_exp_uninit_seq ()

像素.pyx:

cimport cpixis
from cpython.mem cimport PyMem_Malloc, PyMem_Free
cimport numpy as np
import ctypes


cdef class Camera:
    cdef cpixis.rgn_type* _region
    cdef cpixis.int16 _cam_selection
    cdef cpixis.int16 _num_frames
    cdef cpixis.uns32 _exp_time
    cdef char _cam_name[32]
    cdef cpixis.int16 _hCam
    cdef cpixis.uns32 _size
    cdef cpixis.int16 _status
    cdef cpixis.uns32 _notNeeded
    #cdef cpixis.uns16* _frame



    def __cinit__(self):
        self._region = <cpixis.rgn_type *> PyMem_Malloc(sizeof(cpixis.rgn_type))
        if self._region is NULL:
            raise MemoryError()
        #self._frame = <cpixis.uns16 *> PyMem_Malloc( self._size *2 )
        if self._region is NULL:
            raise MemoryError()
        self._cam_selection = 0
        self._num_frames = 1
        self._exp_time = 100
    def __dealloc__(self):
        cpixis.pl_cam_close(self._hCam)
        cpixis.pl_pvcam_uninit()
        if self._region is not NULL:
            PyMem_Free(self._region)
        #if self._frame is not NULL:
        #   PyMem_Free(self._frame)
    def initCamera(self):
        if cpixis.pl_pvcam_init() == False:
            print "Camera failed to init"
            quit()
        if cpixis.pl_cam_get_name(self._cam_selection, self._cam_name) == False:
            print "Didn't get camera name"
            quit()
        if cpixis.pl_cam_open(self._cam_name, &self._hCam, cpixis.OPEN_EXCLUSIVE ) == False:
            print "Camera did not open"
            quit()
    def setRegionOfInterest(self, s1, s2, sbin, p1, p2, pbin):
        self._region.s1 = s1
        self._region.s2 = s2
        self._region.sbin = sbin
        self._region.p1 = p1
        self._region.p2 = p2
        self._region.pbin = pbin
    def acquireImage(self, exposureTime):
        cdef np.ndarray[np.uint16_t, ndim=1] _frame
        self._exp_time = exposureTime
        if cpixis.pl_exp_init_seq() == False:
            print "init_seq Failed"
        if cpixis.pl_exp_setup_seq( self._hCam, 1, 1, self._region, cpixis.TIMED_MODE, self._exp_time, &self._size ) == False:
            print "Experiment failed"
        self.image = np.ndarray(shape=(self._size), dtype=np.uint16, order='C')
        self._frame = np.ascontiguousarray(self.image, dtype=ctypes.c_ushort)
        cpixis.pl_exp_start_seq( self._hCam, &self._frame[0] ); # start image acqusition
        while cpixis.pl_exp_check_status(self._hCam, &self._status, &self._notNeeded) \
              and (self._status != cpixis.READOUT_COMPLETE and self._status != cpixis.READOUT_FAILED):
            pass
        cpixis.pl_exp_finish_seq(self._hCam, &self._frame[0], 0)
        cpixis.pl_exp_uninit_seq()
        self.image = np.copy(self._frame)
        return self.image

第 64 行和第 66 行有相同的错误,即“无法获取 Python 变量的地址。”我一直在处理另一个类似的问题 here .

有什么方法可以解决这个问题,还是我应该以不同的方式解决这个问题?

谢谢!

最佳答案

在 acquireImage() 函数中,我使用了正确的想法,但忘记从 self._frame 引用中删除“self”。我开始时将 _frame 声明为非局部变量,但是当我将它移动到局部范围时忘记更新函数中的引用。我删除了多余的 self ,问题就消失了。

关于python - 将 numpy 数组传递给 cython 中的 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29832920/

相关文章:

TOR上的Python urllib?

用于 Web 浏览器的 Python URL 处理程序

通过 stdin 检查文件是否存在 (C)

c - 如何通过 native ODBC 绑定(bind)数组参数(存储过程)

c++ - 如何添加到对象数组指针C++

java - 将数组初始化为 null 但 null 比较失败

python - 使用 zip 文件从 URL 中提取数据时出现属性错误

Python Ctype 标题不同语言

c - PEM_read_RSAPublicKey() 在主应用程序代码中崩溃,但在示例代码中工作正常。我该如何解决这个问题?

javascript - 对 Javascript 中给定代码的解释