Common API: Imaging devices
campagnola opened this issue · 7 comments
Let's see how hard it is to come up with a common API that we all like for controlling cameras / imaging devices (including laser-scanning systems). Post links to code (gists are good) showing an abstract base Camera or ImagingDevice class, and usage examples.
A suggestion here.
This is about as simple as it gets. It leaves it up the API user to add things like a thread to poll the camera, how to deal with the images, etc.
-
As other suggested this would recycle the images memory. The size of the amount of memory to use would be a user parameter.
-
The class would be aware of whether images were getting overwritten before they had been processed (by calling getFrames()), and possible throwing an exception in this case.
-
Many cameras requires some library initialization upfront that would probably be most easily handled by a separate module level function. Perhaps clean up as well.
-
The properties (or parameters) would probably be some sort of object (not just strings, etc.) to make introspection easier, and perhaps also support "complicated" properties. The property class would be common to the entire project.
Issues:
-
Properties often depend on other properties. For example the allowed range of "fps" property would depend on the current ROI size. Would a mechanism be provided for tracking properties that had become stale? Or is the user going to be expected to query for possible changes?
-
Would there be a locking mechanism for images so that an exception would get thrown if the imaging device tried to write over a frame that was still being processed?
-
Do we try and follow the vendors property nomenclature? Or for common properties like frame rate do we use say "fps" regardless of what the vendor choose to call it?
Great start! I'll post a copy with some modifications..
Properties often depend on other properties
Agree there needs to be some way to inform the user of property changes (especially so gui values / limits can be updated). One possibility is to return information about these changes from setProperty
.
Do we try and follow the vendors property nomenclature
For common parameters like exposure time, binning, region, trigger mode, etc. I favor standardizing all of the names. For everything else, just use the vendor-provided names.
I have extended @HazenBabcock's suggestion here
Changelog:
- Added ImageData class for holding acquisition results
- contains metadata: timestamp, camera properties, image format, etc.
- gives us a structure for representing all acquired frames while not necessarily keeping all of the image data
- some cameras can change parameters while running; this lets us know exactly which parameters each frame was acquired with
- allows subclasses to customize the way image data is accessed (for example, some cameras stream directly to disk; you don't necessarily want to return this to the user as a numpy array)
- Added ImagingDevice.open(). This lets subclasses override this method without changing init, and also adds the possibility to close/reopen the device without creating a new instance
- Made get_properties / set_properties plural because some cameras have a long
round-trip time for setting properties (it can be much more efficient to set
them in bulk) - Set_properties returns information about the effects of the request
- Added list_devices, is_acquiring(), and set_callback()
- More PEP8-compliant
A few suggestions.
- It looks like
fixed_frame_count
is being used for two purposes, one is to set the length of a fixed length acquisition and the other is to set the frame buffer size? If so, I think these should be separated in order to allow really long but still fixed length acquisitions (like 100k frames). - I think camera properties should be an object in case we find we need the additional flexibility in the future. For convenience
set_properties()
would accept a dictionary or a list of property objects, but it would return a list of properties innew_values
. - The
ImagingDevice
class should keep track of which properties the user was actually interested in and only return those forset_properties
. Some cameras (like those from FLIR) have hundreds of parameters and keeping track of all the parameters that might be changed byset_properties
could be a lot extra effort without much benefit.
@campagnola Maybe at this point it would be a good idea to create an actual repo starting from your gist? Then we could work towards a version 0 API using pull requests?
It looks like fixed_frame_count is being used for two purposes, one is to set the length of a fixed length acquisition and the other is to set the frame buffer size?
No, my intent was for buffer_size
to control the frame buffer size.
I think camera properties should be an object in case we find we need the additional flexibility in the future.
Tentatively agreed.
The ImagingDevice class should keep track of which properties the user was actually interested in
Definitely agreed.
It's here: https://github.com/python-data-acquisition/prototypes
Let's move this discussion over to that repo as well.