Last active
August 25, 2022 11:06
-
-
Save npyoung/1c160c9eee91fd44c587 to your computer and use it in GitHub Desktop.
Fast acquisition from a Vimba camera in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This demonstration assumes you have already installed Pymba and followed the installation instructions there: | |
https://github.com/morefigs/pymba | |
MoviePy is used to save the frames to a video file for later viewing, while the frame's mean intensity is | |
printed in real time. MoviePy can be installed from pip nicely. | |
""" | |
import pymba | |
from moviepy.video.io.ffmpeg_writer import FFMPEG_VideoWriter as VidWriter | |
from skimage.color import gray2rgb | |
import time | |
# Start by getting the Vimba API set up | |
# Using the context (i.e. 'with' syntax) is a good idea | |
# If something crashes, vimba.shutdown() will get called automatically | |
# and your camera will not get left in an unusable state! | |
with pymba.Vimba() as vimba: | |
print vimba.getVersion() | |
# Find any cameras that are attached | |
system = pymba.getSystem() | |
system.runFeatureCommand("GeVDiscoveryAllOnce") | |
time.sleep(0.2) # feature commands run in another thread, but need a moment to execute | |
camera_ids = vimba.getCameraIds() | |
# Just use the first camera we found | |
vmb_cam = vimba.getCamera(camera_ids[0]) | |
vmb_cam.openCamera() | |
# Set up the camera with the right parameters | |
# Includes examples of setting up the output TTLs | |
vmb_cam.PixelFormat = 'Mono8' | |
vmb_cam.AcquisitionMode = 'Continuous' | |
vmb_cam.BinningHorizontal = 4 | |
vmb_cam.BinningVertical = 4 | |
vmb_cam.Height = vmb_cam.HeightMax | |
vmb_cam.Width = vmb_cam.WidthMax | |
vmb_cam.AcquisitionFrameRateAbs = 60 | |
vmb_cam.SyncOutSelector = 'SyncOut1' | |
vmb_cam.SyncOutSource = 'Exposing' | |
vmb_cam.TriggerSource = 'FixedRate' | |
# Set up the video file where our frames will be logged | |
video_logger = VidWriter(filename="vimba_test.mp4", | |
size=(vmb_cam.Width, vmb_cam.Height), | |
fps=vmb_cam.AcquisitionFrameRateAbs, | |
code='mpeg4', | |
preset='ultrafast') | |
# Now we set up a callback that will process frames as they arrive | |
def frame_callback(frame): | |
frame_data = frame.getBufferByteData() | |
img = np.ndarray(buffer=frame_data, | |
dtype=np.uint8, | |
shape=(frame.height, frame.width)) | |
print img.mean() | |
video_logger.write_frame(gray2rgb(img)) | |
frame.queueFrameCapture(frame_callback) | |
# Finally, create a buffer of frames. Vimba's way of doing this | |
# is odd: you just make a bunch of frame objects and Vimba decides | |
# what order to fill them in. | |
n_vimba_frames = 10 | |
frame_pool = [vmb_cam.getFrame() for _ in xrange(n_vimba_frames)] | |
for frame in frame_pool: | |
frame.announceFrame() # now Vimba knows about the frame... also odd design choice | |
frame.queueFrameCapture(frame_callback) | |
# Start capturing frames! | |
vmb_cam.startCapture() | |
vmb_cam.runFeatureCommand('AcquisitionStart') | |
time.sleep(30) # 30 seconds of acquisition, proves that frames are written on another thread | |
vmb_cam.runFeatureCommand('AcquisitionStop') | |
time.sleep(0.2) | |
vmb_cam.flushCaptureQueue() # unqueues all frames, must be called before endCapture() | |
vmb_cam.endCapture() | |
vmb_cam.revokeAllFrames() # makes Vimba forget about the frames it's just unqueued |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I was scratching my head on how to modify some methods for the
vmb_cam
object. A convenient approach to figuring out which methods can be called for a particular object is to employ dir():obj_mth = [mth_nam for mth_nam in dir(vmb_cam) if callable(getattr(vmb_cam, mth_nam))]
For vmb_cam, this yields:
['__class__', '__delattr__', '__dir__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_feature_info', '_feature_infos', '_streaming_callback', 'acquire_frame', 'arm', 'close', 'disarm', 'end_capture', 'feature', 'feature_command_is_done', 'feature_names', 'flush_capture_queue', 'new_frame', 'open', 'read_register', 'register_feature_invalidation_callback', 'revoke_all_frames', 'run_feature_command', 'start_capture', 'start_frame_acquisition', 'stop_frame_acquisition', 'unregister_all_feature_invalidation_callbacks', 'unregister_feature_invalidation_callback', 'write_register']