Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)