def __init__(self, camera): super().__init__(camera) self.running = False self.xsize = 1080 self.ysize = 720 self.sb = SimBrownian((self.xsize, self.ysize)) self.maxX = 1800 self.maxY = 720 self.exposure = Q_('10ms') self.X = [0, self.maxX-1] self.Y = [0, self.maxY-1] self.logger = get_logger(name=__name__)
def from_units_to_volts(self, value, dev): units = Q_(dev.properties['calibration']['units']) slope = dev.properties['calibration']['slope'] * units offset = dev.properties['calibration']['offset'] * units value = value.to(units) value = value.m slope = slope.m offset = offset.m return (value - offset) / slope
def configure(self, properties: dict): self.logger.info('Updating config') update_cam = False update_roi = False update_exposure = False update_binning = False for k, new_prop in properties.items(): self.logger.debug('Updating {} to {}'.format(k, new_prop)) update_cam = True if k in self.config: old_prop = self.config[k] if new_prop != old_prop: update_cam = True else: update_cam = True if update_cam: if k in ['roi_x1', 'roi_x2', 'roi_y1', 'roi_y2']: update_roi = True elif k == 'exposure_time': update_exposure = True elif k in ['binning_x', 'binning_y']: update_binning = True if update_cam: if update_roi: X = sorted([properties['roi_x1'], properties['roi_x2']]) Y = sorted([properties['roi_y1'], properties['roi_y2']]) self.set_ROI(X, Y) self.config.update({ 'roi_x1': X[0], 'roi_x2': X[1], 'roi_y1': Y[0], 'roi_y2': Y[1] }) if update_exposure: exposure = properties['exposure_time'] if isinstance(exposure, str): exposure = Q_(exposure) new_exp = self.set_exposure(exposure) self.config['exposure_time'] = new_exp if update_binning: self.set_binning(properties['binning_x'], properties['binning_y']) self.config.update({ 'binning_x': properties['binning_x'], 'binning_y': properties['binning_y'] })
def analog_output_dc(self, conditions): """ Sets the analog output of the NI card. For the time being is thought as a DC constant value. :param dict conditions: specifies DEV and Value :return: """ dev = conditions['dev'] port = "Dev%s/ao%s" % (self.daq_num, dev.properties['port']) units = Q_(dev.properties['calibration']['units']) min_value = Q_(dev.properties['limits']['min']).to(units) max_value = Q_(dev.properties['limits']['max']).to(units) # Convert values to volts: value = conditions['value'].to(units) V = self.from_units_to_volts(value, dev) min_V = self.from_units_to_volts(min_value, dev) max_V = self.from_units_to_volts(max_value, dev) t = nidaq.Task() t.CreateAOVoltageChan(port, None, min_V, max_V, nidaq.DAQmx_Val_Volts, None) t.WriteAnalogScalarF64(nidaq.bool32(True), 0, V, None) t.StopTask() t.ClearTask()
def configure(self, properties): self.logger.info('Updating config') update_cam = False update_roi = False update_exposure = False update_binning = True for k in properties: new_prop = properties[k] self.logger.debug('Updating {} to {}'.format(k, new_prop)) update_cam = True if k in self.config: old_prop = self.config[k] if new_prop != old_prop: update_cam = True else: update_cam = True if update_cam: if k in ['roi_x1', 'roi_x2', 'roi_y1', 'roi_y2']: update_roi = True elif k == 'exposure_time': update_exposure = True elif k in ['binning_x', 'binning_y']: update_binning = True if update_cam: if update_roi: X = np.sort([properties['roi_x1'], properties['roi_x2']]) Y = np.sort([properties['roi_y1'], properties['roi_y2']]) self.setROI(X, Y) self.config.update({ 'roi_x1': X[0], 'roi_x2': X[1], 'roi_y1': Y[0], 'roi_y2': Y[1] }) if update_exposure: exposure = Q_(properties['exposure_time']) new_exp = self.setExposure(exposure) self.config['exposure_time'] = new_exp if update_binning: self.setBinning(properties['binning_x'], properties['binning_y']) self.config.update({ 'binning_x': properties['binning_x'], 'binning_y': properties['binning_y'] })
class Camera(BaseCamera): MODE_CONTINUOUS = 1 MODE_SINGLE_SHOT = 0 def __init__(self, camera): super().__init__(camera) self.running = False self.xsize = 1080 self.ysize = 720 self.sb = SimBrownian((self.xsize, self.ysize)) self.maxX = 1800 self.maxY = 720 self.exposure = Q_('10ms') self.X = [0, self.maxX-1] self.Y = [0, self.maxY-1] self.logger = get_logger(name=__name__) def initialize(self): """Initializes the camera. """ self.logger.info('Initializing camera') self.maxWidth = self.GetCCDWidth() self.maxHeight = self.GetCCDHeight() return True def trigger_camera(self): """Triggers the camera. """ return True def set_acquisition_mode(self, mode): """ Set the readout mode of the camera: Single or continuous. :param: int mode: One of self.MODE_CONTINUOUS, self.MODE_SINGLE_SHOT """ self.logger.debug('Setting acquisition mode') return self.get_acquisition_mode() def get_acquisition_mode(self): """Returns the acquisition mode, either continuous or single shot. """ return self.MODE_CONTINUOUS def acquisition_ready(self): """Checks if the acquisition in the camera is over. """ return True def set_exposure(self, exposure): """Sets the exposure of the camera. """ self.exposure = exposure self.sb.time_step = self.exposure.m_as('s') def get_exposure(self): """Gets the exposure time of the camera. """ return self.exposure def read_camera(self): moment = time.time() sample = self.sb.gen_image() sample = sample.astype('uint8') elapsed = time.time() - moment if elapsed > self.exposure.m_as('s'): self.logger.warning('Generating a frame takes longer than exposure time') else: self.logger.debug('Sleeping for {}'.format(self.exposure.m_as('s') - elapsed)) time.sleep(self.exposure.m_as('s') - elapsed) # to simulate exposure time corrected for data generation delay return [sample] def set_ROI(self, X, Y): """ Sets up the ROI. Not all cameras are 0-indexed, so this is an important place to define the proper ROI. :param X: array type with the coordinates for the ROI X[0], X[1] :param Y: array type with the coordinates for the ROI Y[0], Y[1] :return: """ X = np.sort(X) Y = np.sort(Y) self.xsize = abs(X[1] - X[0])+1 self.ysize = abs(Y[1] - Y[0])+1 # self.sb.resize_view((self.xsize, self.ysize)) self.X = X self.Y = Y self.X[1] -= 1 self.Y[1] -= 1 return self.get_size() def get_size(self): """ :return: Returns the size in pixels of the image being acquired. This is useful for checking the ROI settings. """ return self.xsize, self.ysize def getSerialNumber(self): """Returns the serial number of the camera. """ return "Serial Number" def GetCCDWidth(self): """ :return: The CCD width in pixels """ return self.maxX def GetCCDHeight(self): """ :return: The CCD height in pixels """ return self.maxY def set_binning(self, xbin, ybin): """Sets the binning of the camera if supported. Has to check if binning in X/Y can be different or not, etc. :param: xbin: binning in x :param: ybin: binning in y """ self.xbin = xbin self.ybin = ybin def stopAcq(self): pass def stop_camera(self): pass
def get_exposure(self) -> Q_: self.exposure = float(self.camera.ExposureTime.ToString()) * Q_('us') return self.exposure
def set_exposure(self, exposure: Q_) -> Q_: self.camera.ExposureTime.SetValue(exposure.m_as('us')) self.exposure = exposure return self.get_exposure()
self.camera.AcquisitionStop.Execute() def __str__(self): return self.friendly_name def __del__(self): self.camera.Close() if __name__ == '__main__': from time import sleep logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) logger.info('Starting Basler') basler = Camera(0) basler.initialize() basler.set_acquisition_mode(basler.MODE_SINGLE_SHOT) basler.set_exposure(Q_('.02s')) basler.trigger_camera() print(len(basler.read_camera())) basler.set_acquisition_mode(basler.MODE_CONTINUOUS) basler.trigger_camera() sleep(1) imgs = basler.read_camera() print(len(imgs))