Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/issue 21 #22

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
74 changes: 46 additions & 28 deletions cython/factory.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<Camera {0} open={1}>'.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

Expand All @@ -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 = (<string>(ACCESS_CGrabResultPtr_GetErrorDescription(ptr_grab_result))).decode()
raise RuntimeError(error_desc)

if not ACCESS_CGrabResultPtr_GrabSucceeded(ptr_grab_result):
error_desc = (<string>(ACCESS_CGrabResultPtr_GetErrorDescription(ptr_grab_result))).decode()
raise RuntimeError(error_desc)
img = &(<IImage&>ptr_grab_result)
if not img.IsValid():
raise RuntimeError('Graped IImage is not valid.')

img = &(<IImage&>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((<char*>img.GetBuffer())[:img.GetImageSize()], dtype='uint'+bits_per_pixel_prop[3:])

img_data = np.frombuffer((<char*>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))
Expand Down Expand Up @@ -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))
return Camera.create(tl_factory.CreateDevice(dev_info.dev_info))
4 changes: 3 additions & 1 deletion cython/pylon_def.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
uint32_t ACCESS_CGrabResultPtr_GetErrorCode(CGrabResultPtr ptr)