![](/img/trans.png)
[英]Cython memoryviews: wrapping c function with array parameter to pass numpy array
[英]Pass a numpy array to a C function in cython
我使用Cython包裝了第三方相機庫接口,因此可以從python程序中調用它。 在大多數情況下,一切都很好,但是我在acquireImage()函數中遇到了麻煩。 我試圖創建一個連續的numpy數組,將其傳遞給庫,並在庫完成填充后獲取結果。 最后,我想復制該數組,調整其形狀並返回它。 (重塑的東西尚未編碼)
這是我的代碼:
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 ()
pixis.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變量的地址。”我已經從其他類似的問題,工作在這里 。
有沒有辦法使這項工作有效,還是應該以不同的方式來解決這個問題?
謝謝!
在acquireImage()函數中,我使用的是正確的主意,但是忘記從self._frame引用中刪除“ self”。 我最初將_frame聲明為非局部變量,但是當我將其移至局部范圍時卻忘了更新函數中的引用。 我刪除了多余的自我,問題消失了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.