diff --git a/cython/factory.pyx b/cython/factory.pyx index b316788..8d254aa 100644 --- a/cython/factory.pyx +++ b/cython/factory.pyx @@ -195,26 +195,34 @@ cdef class Camera: self.camera.Close() elif not self.opened and opened: self.camera.Open() - + + property is_grabbing: + def __get__(self): + return self.camera.IsGrabbing() + def open(self): self.camera.Open() def close(self): self.camera.Close() + def stop_grabbing(self): + if self.camera.IsGrabbing(): + self.camera.StopGrabbing() + def __del__(self): + self.stop_grabbing() self.close() self.camera.DetachDevice() def __repr__(self): return ''.format(self.device_info.friendly_name, self.opened) - def grab_images(self, int nr_images, unsigned int timeout=5000): + def grab_images(self, int nr_images = -1, unsigned int timeout=5000): + if not self.opened: raise RuntimeError('Camera not opened') - self.camera.StartGrabbing(nr_images) - cdef CGrabResultPtr ptr_grab_result cdef IImage* img @@ -224,36 +232,46 @@ cdef class Camera: assert image_format.startswith('Mono'), 'Only mono images allowed at this point' assert not image_format.endswith('p'), 'Packed data not supported at this point' - while self.camera.IsGrabbing(): + try: + if nr_images < 1: + self.camera.StartGrabbing() + else: + self.camera.StartGrabbing(nr_images) + + while self.camera.IsGrabbing(): + + with nogil: + # Blocking call into native Pylon C++ SDK code, release GIL so other python threads can run + self.camera.RetrieveResult(timeout, ptr_grab_result) - with nogil: - # Blocking call into native Pylon C++ SDK code, release GIL so other python threads can run - self.camera.RetrieveResult(timeout, ptr_grab_result) + if not ACCESS_CGrabResultPtr_GrabSucceeded(ptr_grab_result): + error_desc = ((ACCESS_CGrabResultPtr_GetErrorDescription(ptr_grab_result))).decode() + raise RuntimeError(error_desc) - if not ACCESS_CGrabResultPtr_GrabSucceeded(ptr_grab_result): - error_desc = ((ACCESS_CGrabResultPtr_GetErrorDescription(ptr_grab_result))).decode() - raise RuntimeError(error_desc) + img = &(ptr_grab_result) + if not img.IsValid(): + raise RuntimeError('Graped IImage is not valid.') - img = &(ptr_grab_result) - if not img.IsValid(): - raise RuntimeError('Graped IImage is not valid.') + if img.GetImageSize() % img.GetHeight(): + print('This image buffer is wired. Probably you will see an error soonish.') + print('\tBytes:', img.GetImageSize()) + print('\tHeight:', img.GetHeight()) + print('\tWidth:', img.GetWidth()) + print('\tGetPaddingX:', img.GetPaddingX()) - if img.GetImageSize() % img.GetHeight(): - print('This image buffer is wired. Probably you will see an error soonish.') - print('\tBytes:', img.GetImageSize()) - print('\tHeight:', img.GetHeight()) - print('\tWidth:', img.GetWidth()) - print('\tGetPaddingX:', img.GetPaddingX()) + assert not img.GetPaddingX(), 'Image padding not supported.' + # TODO: Check GetOrientation to fix oritentation of image if required. - assert not img.GetPaddingX(), 'Image padding not supported.' - # TODO: Check GetOrientation to fix oritentation of image if required. + img_data = np.frombuffer((img.GetBuffer())[:img.GetImageSize()], dtype='uint'+bits_per_pixel_prop[3:]) - img_data = np.frombuffer((img.GetBuffer())[:img.GetImageSize()], dtype='uint'+bits_per_pixel_prop[3:]) + # TODO: How to handle multi-byte data here? + img_data = img_data.reshape((img.GetHeight(), -1)) + # img_data = img_data[:img.GetHeight(), :img.GetWidth()] + yield img_data - # TODO: How to handle multi-byte data here? - img_data = img_data.reshape((img.GetHeight(), -1)) - # img_data = img_data[:img.GetHeight(), :img.GetWidth()] - yield img_data + except: + self.stop_grabbing() + raise def grab_image(self, unsigned int timeout=5000): return next(self.grab_images(1, timeout)) @@ -288,4 +306,4 @@ cdef class Factory: def create_device(self, DeviceInfo dev_info): cdef CTlFactory* tl_factory = &GetInstance() - return Camera.create(tl_factory.CreateDevice(dev_info.dev_info)) \ No newline at end of file + return Camera.create(tl_factory.CreateDevice(dev_info.dev_info)) diff --git a/cython/pylon_def.pxd b/cython/pylon_def.pxd index e5ccd59..b791bb9 100644 --- a/cython/pylon_def.pxd +++ b/cython/pylon_def.pxd @@ -116,8 +116,10 @@ cdef extern from "pylon/PylonIncludes.h" namespace 'Pylon': void IsCameraDeviceRemoved() void Open() except + void Close() except + + void StopGrabbing() except + bool IsOpen() except + IPylonDevice* DetachDevice() except + + void StartGrabbing() except + void StartGrabbing(size_t maxImages) except + #FIXME: implement different strategies bool IsGrabbing() # RetrieveResult() is blocking call into C++ native SDK, allow it to be called without GIL @@ -148,4 +150,4 @@ cdef extern from "pylon/PylonIncludes.h" namespace 'Pylon::CTlFactory': cdef extern from 'hacks.h': bool ACCESS_CGrabResultPtr_GrabSucceeded(CGrabResultPtr ptr) String_t ACCESS_CGrabResultPtr_GetErrorDescription(CGrabResultPtr ptr) - uint32_t ACCESS_CGrabResultPtr_GetErrorCode(CGrabResultPtr ptr) \ No newline at end of file + uint32_t ACCESS_CGrabResultPtr_GetErrorCode(CGrabResultPtr ptr)