async def acquisition_async( self, num=np.inf, timeout=None, raw=False, initialising_cams=None, raise_on_timeout=True, ): """Concrete implementation of :meth:`pymanip.video.Camera.acquisition_async` for the Andor camera. .. todo:: add support for initialising_cams """ loop = asyncio.get_event_loop() # Make sure no acquisition is running & flush if self.CameraAcquiring.getValue(): self.AcquisitionStop() SDK3.Flush(self.handle) self.buffer_queued = False # Set acquisition mode self.CycleMode.setString("Continuous") # self.FrameRate.setValue(float(framerate)) self.MetadataEnable.setValue(True) pc_clock = time.time() timestamp_clock = self.TimestampClock.getValue() timestamp_frequency = self.TimestampClockFrequency.getValue() print("ts clock =", timestamp_clock) print("ts freq =", timestamp_frequency) # Init buffers bufSize = self.ImageSizeBytes.getValue() buf = np.empty(bufSize, "uint8") rbuf, cbuf = self.AOIWidth.getValue(), self.AOIHeight.getValue() img = np.empty((rbuf, cbuf), np.uint16) xs, ys = img.shape[:2] a_s = self.AOIStride.getValue() dt = self.PixelEncoding.getString() print("Original pixel encoding:", dt) # Start acquisition self.AcquisitionStart() print("Started acquisition at framerate:", self.FrameRate.getValue()) print("Exposure time is {:.1f} ms".format(self.ExposureTime.getValue() * 1000)) if timeout is None: exposure_ms = self.ExposureTime.getValue() * 1000 framerate_ms = 1000 / self.FrameRate.getValue() timeout_ms = int(max((2 * exposure_ms, 2 * framerate_ms, 1000))) timeout = timeout_ms try: count = 0 while count < num: if not self.buffer_queued: SDK3.QueueBuffer( self.handle, buf.ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), buf.nbytes, ) self.buffer_queued = True try: pData, lData = await loop.run_in_executor( None, SDK3.WaitBuffer, self.handle, timeout ) except Exception: if raise_on_timeout: raise CameraTimeout() else: stop_signal = yield None if stop_signal: break else: continue # Convert buffer and yield image SDK3.ConvertBuffer( buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), img.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), xs, ys, a_s, dt, "Mono16", ) ticks = parse_metadata(buf) ts = (ticks - timestamp_clock) / timestamp_frequency + pc_clock # if count == 5: # print('image min max:', np.min(img), np.max(img)) # if count < 10: # print('FPGA ticks =', ticks) # print('Timestamp =', ts) self.buffer_queued = False stop_signal = yield MetadataArray( img.reshape((cbuf, rbuf), order="C"), metadata={"counter": count, "timestamp": ts}, ) count = count + 1 if stop_signal: break finally: self.AcquisitionStop() if stop_signal: yield True
async def acquisition_async( self, num=np.inf, timeout=1000, raw=False, framerate=None, external_trigger=False, initialising_cams=None, raise_on_timeout=True, ): """Concrete implementation of :meth:`pymanip.video.Camera.acquisition_async` for the AVT camera. """ self.camera.AcquisitionMode = "Continuous" if framerate is not None: # Not usable if HighSNRIImages>0, external triggering or # IIDCPacketSizeAuto are active self.camera.AcquisitionFrameRate = framerate if external_trigger: self.camera.TriggerMode = "On" self.camera.TriggerSource = "InputLines" self.frame = self.camera.getFrame() self.frame.announceFrame() self.camera.startCapture() self.camera.runFeatureCommand("AcquisitionStart") self.buffer_queued = False try: count = 0 while count < num: if not self.buffer_queued: self.frame.queueFrameCapture() self.buffer_queued = True if (count == 0 and initialising_cams is not None and self in initialising_cams): initialising_cams.remove(self) errorCode = await self.frame.waitFrameCapture_async( int(timeout)) if errorCode == -12: if raise_on_timeout: raise CameraTimeout("cam" + str(self.num) + " timeout") else: stop_signal = yield None if stop_signal: break else: continue elif errorCode != 0: raise VimbaException(errorCode) if self.frame.pixel_bytes == 1: dt = np.uint8 elif self.frame.pixel_bytes == 2: dt = np.uint16 else: raise NotImplementedError self.buffer_queued = False stop_signal = yield MetadataArray( np.ndarray( buffer=self.frame.getBufferByteData(), dtype=dt, shape=(self.frame.height, self.frame.width), ), metadata={ "counter": count, "timestamp": self.frame.timestamp * 1e-7, }, ) count += 1 if stop_signal: break finally: self.camera.runFeatureCommand("AcquisitionStop") self.camera.endCapture() self.camera.revokeAllFrames() if stop_signal: yield True
async def acquisition_async( self, num=np.inf, timeout=None, raw=False, initialising_cams=None, raise_on_timeout=True, ): """ Multiple image acquisition yields a shared memory numpy array valid only before generator object cleanup. timeout in milliseconds """ loop = asyncio.get_event_loop() if timeout is None: delay, exposure = self.current_delay_exposure_time() timeout = int(max((2000 * exposure, 1000))) # Arm camera if pf.PCO_GetRecordingState(self.handle): pf.PCO_SetRecordingState(self.handle, False) pf.PCO_ArmCamera(self.handle) warn, err, status = self.health_status() if err != 0: raise RuntimeError("Camera has error status!") XResAct, YResAct, XResMax, YResMax = pf.PCO_GetSizes(self.handle) with PCO_Buffer(self.handle, XResAct, YResAct) as buf1, PCO_Buffer( self.handle, XResAct, YResAct) as buf2, PCO_Buffer( self.handle, XResAct, YResAct) as buf3, PCO_Buffer(self.handle, XResAct, YResAct) as buf4: buffers = (buf1, buf2, buf3, buf4) try: pf.PCO_SetImageParameters( self.handle, XResAct, YResAct, pf.IMAGEPARAMETERS_READ_WHILE_RECORDING, ) pf.PCO_SetRecordingState(self.handle, True) for buffer in buffers: pf.PCO_AddBufferEx(self.handle, 0, 0, buffer.bufNr, XResAct, YResAct, 16) count = 0 buffer_ring = itertools.cycle(buffers) while count < num: if (count == 0 and initialising_cams is not None and self in initialising_cams): initialising_cams.remove(self) waitstat = await loop.run_in_executor( None, win32event.WaitForMultipleObjects, [buffer.event_handle for buffer in buffers], 0, timeout, ) if waitstat == win32event.WAIT_TIMEOUT: if raise_on_timeout: raise CameraTimeout(f"Timeout ({timeout:})") else: stop_signal = yield None if not stop_signal: continue else: break for ii, buffer in zip(range(4), buffer_ring): waitstat = await loop.run_in_executor( None, win32event.WaitForSingleObject, buffer.event_handle, 0) if waitstat == win32event.WAIT_OBJECT_0: win32event.ResetEvent(buffer.event_handle) statusDLL, statusDrv = pf.PCO_GetBufferStatus( self.handle, buffer.bufNr) if statusDrv != 0: raise RuntimeError( "buffer {:} error status {:}".format( buffer.bufNr, statusDrv)) if raw: data = {"buffer": buffer.bytes()} if self.timestamp_mode: counter, dt = PCO_get_binary_timestamp( buffer.bufPtr[:14]) data["counter"] = counter data["timestamp"] = dt stop_signal = yield data else: if self.metadata_mode: metadata = pf.PCO_GetMetaData( self.handle, buffer.bufNr) stop_signal = yield MetadataArray( buffer.as_array(), metadata=metadata) elif self.timestamp_mode: counter, dt = PCO_get_binary_timestamp( buffer.bufPtr[:14]) stop_signal = yield MetadataArray( buffer.as_array(), metadata={ "counter": counter, "timestamp": dt }, ) else: stop_signal = yield buffer.as_array() count += 1 pf.PCO_AddBufferEx(self.handle, 0, 0, buffer.bufNr, XResAct, YResAct, 16) else: break if stop_signal: break if stop_signal: break finally: pf.PCO_SetRecordingState(self.handle, False) pf.PCO_CancelImages(self.handle) if stop_signal: yield True