class VimbaCamera(FrameSource): """ **SUMMARY** VimbaCamera is a wrapper for the Allied Vision cameras, such as the "manta" series. This requires the 1) Vimba SDK provided from Allied Vision http://www.alliedvisiontec.com/us/products/software/vimba-sdk.html 2) Pyvimba Python library TODO: <INSERT URL> Note that as of time of writing, the VIMBA driver is not available for Mac. All camera properties are directly from the Vimba SDK manual -- if not specified it will default to whatever the camera state is. Cameras can either by **EXAMPLE** >>> cam = VimbaCamera(0, {"width": 656, "height": 492}) >>> >>> img = cam.getImage() >>> img.show() """ def _setupVimba(self): from pymba import Vimba self._vimba = Vimba() self._vimba.startup() system = self._vimba.getSystem() if system.GeVTLIsPresent: system.runFeatureCommand("GeVDiscoveryAllOnce") time.sleep(0.2) def __del__(self): #This function should disconnect from the Vimba Camera if self._camera is not None: if self.threaded: self._thread.stop() time.sleep(0.2) if self._frame is not None: self._frame.revokeFrame() self._frame = None self._camera.closeCamera() self._vimba.shutdown() def shutdown(self): """You must call this function if you are using threaded=true when you are finished to prevent segmentation fault""" # REQUIRED TO PREVENT SEGMENTATION FAULT FOR THREADED=True if (self._camera): self._camera.closeCamera() self._vimba.shutdown() def __init__(self, camera_id = -1, properties = {}, threaded = False): if not VIMBA_ENABLED: raise Exception("You don't seem to have the pymba library installed. This will make it hard to use a AVT Vimba Camera.") self._vimba = None self._setupVimba() camlist = self.listAllCameras() self._camTable = {} self._frame = None self._buffer = None # Buffer to store images self._buffersize = 10 # Number of images to keep in the rolling image buffer for threads self._lastimage = None # Last image loaded into memory self._thread = None self._framerate = 0 self.threaded = False self._properties = {} self._camera = None i = 0 for cam in camlist: self._camTable[i] = {'id': cam.cameraIdString} i += 1 if not len(camlist): raise Exception("Couldn't find any cameras with the Vimba driver. Use VimbaViewer to confirm you have one connected.") if camera_id < 9000: #camera was passed as an index reference if camera_id == -1: #accept -1 for "first camera" camera_id = 0 if (camera_id > len(camlist)): raise Exception("Couldn't find camera at index %d." % camera_id) cam_guid = camlist[camera_id].cameraIdString else: raise Exception("Index %d is too large" % camera_id) self._camera = self._vimba.getCamera(cam_guid) self._camera.openCamera() self.uniqueid = cam_guid self.setProperty("AcquisitionMode","SingleFrame") self.setProperty("TriggerSource","Freerun") # TODO: FIX if properties.get("mode", "RGB") == 'gray': self.setProperty("PixelFormat", "Mono8") else: fmt = "RGB8Packed" # alternatively use BayerRG8 self.setProperty("PixelFormat", "BayerRG8") #give some compatablity with other cameras if properties.get("mode", ""): properties.pop("mode") if properties.get("height", ""): properties["Height"] = properties["height"] properties.pop("height") if properties.get("width", ""): properties["Width"] = properties["width"] properties.pop("width") for p in properties: self.setProperty(p, properties[p]) if threaded: self._thread = VimbaCameraThread(self) self._thread.daemon = True self._buffer = deque(maxlen=self._buffersize) self._thread.start() self.threaded = True self._refreshFrameStats() def restart(self): """ This tries to restart the camera thread """ self._thread.stop() self._thread = VimbaCameraThread(self) self._thread.daemon = True self._buffer = deque(maxlen=self._buffersize) self._thread.start() def listAllCameras(self): """ **SUMMARY** List all cameras attached to the host **RETURNS** List of VimbaCamera objects, otherwise empty list VimbaCamera objects are defined in the pymba module """ cameraIds = self._vimba.getCameraIds() ar = [] for cameraId in cameraIds: ar.append(self._vimba.getCamera(cameraId)) return ar def runCommand(self,command): """ **SUMMARY** Runs a Vimba Command on the camera Valid Commands include: * AcquisitionAbort * AcquisitionStart * AcquisitionStop **RETURNS** 0 on success **EXAMPLE** >>>c = VimbaCamera() >>>c.runCommand("TimeStampReset") """ return self._camera.runFeatureCommand(command) def getProperty(self, name): """ **SUMMARY** This retrieves the value of the Vimba Camera attribute There are around 140 properties for the Vimba Camera, so reference the Vimba Camera pdf that is provided with the SDK for detailed information Throws VimbaException if property is not found or not implemented yet. **EXAMPLE** >>>c = VimbaCamera() >>>print c.getProperty("ExposureMode") """ return self._camera.__getattr__(name) #TODO, implement the PvAttrRange* functions #def getPropertyRange(self, name) def getAllProperties(self): """ **SUMMARY** This returns a dict with the name and current value of the documented Vimba attributes CAVEAT: it addresses each of the properties individually, so this may take time to run if there's network latency **EXAMPLE** >>>c = VimbaCamera(0) >>>props = c.getAllProperties() >>>print props['ExposureMode'] """ from pymba import VimbaException # TODO ar = {} c = self._camera cameraFeatureNames = c.getFeatureNames() for name in cameraFeatureNames: try: ar[name] = c.__getattr__(name) except VimbaException: # Ignore features not yet implemented pass return ar def setProperty(self, name, value, skip_buffer_size_check=False): """ **SUMMARY** This sets the value of the Vimba Camera attribute. There are around 140 properties for the Vimba Camera, so reference the Vimba Camera pdf that is provided with the SDK for detailed information Throws VimbaException if property not found or not yet implemented **Example** >>>c = VimbaCamera() >>>c.setProperty("ExposureAutoRate", 200) >>>c.getImage().show() """ ret = self._camera.__setattr__(name, value) #just to be safe, re-cache the camera metadata if not skip_buffer_size_check: self._refreshFrameStats() return ret def getImage(self): """ **SUMMARY** Extract an Image from the Camera, returning the value. No matter what the image characteristics on the camera, the Image returned will be RGB 8 bit depth, if camera is in greyscale mode it will be 3 identical channels. **EXAMPLE** >>>c = VimbaCamera() >>>c.getImage().show() """ if self.threaded: self._thread.lock.acquire() try: img = self._buffer.pop() self._lastimage = img except IndexError: img = self._lastimage self._thread.lock.release() else: img = self._captureFrame() return img def setupASyncMode(self): self.setProperty('AcquisitionMode','SingleFrame') self.setProperty('TriggerSource','Software') def setupSyncMode(self): self.setProperty('AcquisitionMode','SingleFrame') self.setProperty('TriggerSource','Freerun') def _refreshFrameStats(self): self.width = self.getProperty("Width") self.height = self.getProperty("Height") self.pixelformat = self.getProperty("PixelFormat") self.imgformat = 'RGB' if self.pixelformat == 'Mono8': self.imgformat = 'L' def _getFrame(self): if not self._frame: self._frame = self._camera.getFrame() # creates a frame self._frame.announceFrame() return self._frame def _captureFrame(self, timeout = 5000): try: c = self._camera f = self._getFrame() colorSpace = Factory.Image.BGR if self.pixelformat == 'Mono8': colorSpace = Factory.Image.GRAY c.startCapture() f.queueFrameCapture() c.runFeatureCommand('AcquisitionStart') c.runFeatureCommand('AcquisitionStop') try: f.waitFrameCapture(timeout) except Exception, e: print "Exception waiting for frame: %s: %s" % (e, traceback.format_exc()) raise(e) imgData = f.getBufferByteData() moreUsefulImgData = np.ndarray(buffer = imgData, dtype = np.uint8, shape = (f.height, f.width, 1)) rgb = cv2.cvtColor(moreUsefulImgData, cv2.COLOR_BAYER_RG2RGB) c.endCapture() return Factory.Image(rgb, colorSpace=colorSpace) except Exception, e: print "Exception acquiring frame: %s: %s" % (e, traceback.format_exc()) raise(e)
class AvtCamera(Camera): """Class for controlling an AVT camera. Uses the Vimba interface pymba (module documentation `here <https://github.com/morefigs/pymba>`_). Parameters ---------- Returns ------- """ def __init__(self, downsampling=None, **kwargs): # Set timeout for frame acquisition. Give this as input? self.timeout_ms = 1000 super().__init__(**kwargs) try: self.vimba = Vimba() except NameError: print("The pymba package must be installed to use an AVT camera!") self.frame = None def open_camera(self): """ """ self.vimba.startup() # If there are multiple cameras, only the first one is used (this may # change): camera_ids = self.vimba.getCameraIds() if self.debug: if len(camera_ids) > 1: print("Multiple cameras detected: {}. {} wiil be used.".format( camera_ids, camera_ids[0])) else: print("Detected camera {}.".format(camera_ids[0])) self.cam = self.vimba.getCamera(camera_ids[0]) # Start camera: self.cam.openCamera() self.frame = self.cam.getFrame() self.frame.announceFrame() self.cam.startCapture() self.frame.queueFrameCapture() self.cam.runFeatureCommand("AcquisitionStart") def set(self, param, val): """ Parameters ---------- param : val : Returns ------- """ try: if param == "exposure": # camera wants exposure in us: self.cam.ExposureTime = int(val * 1000) if param == "framerate": # To set new frame rate for AVT cameras acquisition has to be # interrupted: # TODO Handle this in a cleaner way if val < 210: # empirically found maximum frame rate to be set self.frame.waitFrameCapture(self.timeout_ms) self.cam.runFeatureCommand("AcquisitionStop") self.cam.endCapture() self.cam.revokeAllFrames() self.cam.AcquisitionFrameRate = val self.cam.startCapture() self.frame.queueFrameCapture() self.cam.runFeatureCommand("AcquisitionStart") except VimbaException: print("Invalid value! The parameter will not be changed.") def read(self): """ """ try: self.frame.waitFrameCapture(self.timeout_ms) self.frame.queueFrameCapture() raw_data = self.frame.getBufferByteData() frame = np.ndarray( buffer=raw_data, dtype=np.uint8, shape=(self.frame.height, self.frame.width), ) except VimbaException: frame = None if self.debug: print("Unable to acquire frame") return frame def release(self): """ """ self.frame.waitFrameCapture(self.timeout_ms) self.cam.runFeatureCommand("AcquisitionStop") self.cam.endCapture() self.cam.revokeAllFrames() self.vimba.shutdown()