def save_vid(self, startframe=1, stopframe=100, ext='.mp4', filename=None): if startframe == 0: print('Frame numbers start from 1 setting startframe to 1') startframe = 1 if filename is None: date_time = self.datetimestr() filename_op = self.filename_base + str(date_time) + ext else: filename_op = filename + ext writevid = WriteVideo( filename=filename_op, frame_size=(self.camset.cam_dict['frameformat'][2][3], self.camset.cam_dict['frameformat'][2][2])) for frame in range(startframe, stopframe, 1): img_ptr = SISO.Fg_getImagePtrEx(self.fg, int(frame), 0, self.memHandle) nImg = SISO.getArrayFrom(img_ptr, self.camset.cam_dict['frameformat'][2][2], self.camset.cam_dict['frameformat'][2][3]) writevid.add_frame(nImg) writevid.close() print('Finished writing video')
def grabStart(self): """ Start grabbing images in a non-blocking way and store those images in an internal variable See Also -------- self.grabStop() """ # Register apc control and callback function (see below this class) # Used to control asynchronous image acquisition apcCtrl = s.FgApcControl(5, s.FG_APC_DEFAULTS) self._apc_data = _MyApcData(self.device, self.device_handle, self._free_run_buffer, (self._width, self._height)) s.setApcCallbackFunction(apcCtrl, _frameCallback, self._apc_data) err = s.Fg_registerApcHandler(self.device, self.device_handle, apcCtrl, s.FG_APC_CONTROL_BASIC) if err != s.FG_OK: raise _MicroEnableException(err) err = s.Fg_AcquireEx(self.device, self.device_handle, s.GRAB_INFINITE, s.ACQ_STANDARD, self._free_run_buffer) if err != s.FG_OK: raise _MicroEnableException(err)
def get_pixmap_image(self, frame): img_ptr = SISO.Fg_getImagePtrEx(self.fg, int(frame), 0, self.memHandle) nImg = SISO.getArrayFrom(img_ptr, self.camset.cam_dict['frameformat'][2][2], self.camset.cam_dict['frameformat'][2][3]) pixmap = QPixmap.fromImage(array2qimage(nImg)) return pixmap
def snap_max_array(self): cur_pic_nr = SISO.Fg_getLastPicNumberEx(self.fg, 0, self.memHandle) img_ptr = SISO.Fg_getImagePtrEx(self.fg, cur_pic_nr, 0, self.memHandle) nImg = SISO.getArrayFrom(img_ptr, self.camset.cam_dict['frameformat'][3][0][1], self.camset.cam_dict['frameformat'][3][1][1]) return nImg
def __del__(self): """ Frees memory and grabber when closing. """ s.Fg_FreeMemEx(self.device, self._free_run_buffer) if self._buffer_handle is not None: s.Fg_FreeMemEx(self.device, self._buffer_handle) s.clSerialClose(self._clser_ref[1]) self.closeDevice()
def _frameCallback(imgNr, userData): """ Callback function which will be used for asynchronous acquisition. """ img_data = s.Fg_getImagePtrEx(userData.fg, imgNr, userData.port, userData.mem) img = s.getArrayFrom(img_data, userData.width, userData.height) userData.img_list.append(img.copy()) return 0
def initialise(self): totalBufferSize = self.camset.cam_dict['frameformat'][2][ 2] * self.camset.cam_dict['frameformat'][2][ 3] * self.camset.cam_dict['numpicsbuffer'][2] self.memHandle = SISO.Fg_AllocMemEx( self.fg, totalBufferSize, self.camset.cam_dict['numpicsbuffer'][2]) self.display = SISO.CreateDisplay( 8, self.camset.cam_dict['frameformat'][2][2], self.camset.cam_dict['frameformat'][2][3]) SISO.SetBufferWidth(self.display, self.camset.cam_dict['frameformat'][2][2], self.camset.cam_dict['frameformat'][2][3])
def display_img(self): cur_pic_nr = SISO.Fg_getLastPicNumberEx(self.fg, 0, self.memHandle) if cur_pic_nr == self.numpics: self.display_timer.stop() if self.autosave: self.save_vid(self.filename_base, 1, self.numpics) self.resource_cleanup() else: win_name_img = "Source Image (SiSo Runtime)" # get image pointer img_ptr = SISO.Fg_getImagePtrEx(self.fg, cur_pic_nr, 0, self.memHandle) SISO.DrawBuffer(self.display, img_ptr, cur_pic_nr, win_name_img)
def snap(self, filename=None, ext='.png'): if filename is not None: self.filename_base = filename.split('.')[0] img_filename = self.filename_base.split('Videos/')[ 0] + 'Pictures/' + self.filename_base.split('Videos/')[1] print(img_filename) date_time = self.datetimestr() cur_pic_nr = SISO.Fg_getLastPicNumberEx(self.fg, 0, self.memHandle) img_ptr = SISO.Fg_getImagePtrEx(self.fg, cur_pic_nr, 0, self.memHandle) nImg = SISO.getArrayFrom(img_ptr, self.camset.cam_dict['frameformat'][2][2], self.camset.cam_dict['frameformat'][2][3]) cv2.imwrite(img_filename + date_time + ext, nImg)
def _prepareImageBuffer(self, numImages=1): """ Prepares a bigger buffer for e.g. more than 1 triggered image. Notes: This function uses a sleep function to guarantee allocated memory. Parameters ---------- numImages : int Number of expected images. Returns ------- buffer: memory_handle Memory handle which adresses the allocated buffer memory """ # Calculate buffer size # TODO: bytePerSample may have to be changed when using different pixel formats samplePerPixel = 1 bytePerSample = 1 nbBuffers = numImages totalBufferSize = self._width * self._height * samplePerPixel * \ bytePerSample * nbBuffers buffer = s.Fg_AllocMemEx(self.device, totalBufferSize, nbBuffers) # Give time to allocate buffer - # tests without sleep/too short sleep failed time.sleep(.5) return buffer
def _setParamWithInt(self, parameter, value): """ Short form of Fg_setParameterWithInt to reduce line length (since self.device and self.device_handle are always passed). Parameters ---------- parameter : silicon software enum Defines the parameter, which should be read. value : int Value of parameter. """ # Set retval to value which is not expected to be set a value # to ensure at least one iteration through the while loop retval = -99 iterations = 0 s.Fg_setParameterWithInt(self.device, parameter, value, self.device_handle) while retval != value: retval = self._getParamWithInt(parameter) if iterations > MAX_ITER: raise TimeoutError( "Max iterations reached while waiting to set parameter!") iterations += 1 # Sleep to fully apply setting... there have been timing issues... time.sleep(.1)
def reset_default_config(self): copyfile(self.cam_config_dir + 'default_backup.ccf', self.cam_current_ccf) copyfile(self.cam_config_dir + 'default_backup.mcf', self.fg_current_mcf) self._load_cam_config() SISO.Fg_loadConfig(self.fg, self.cam_config_dir + 'current.mcf')
def save_config(self, filename=None, parent=None): if filename is None: filename = save_filename(directory=self.cam_config_dir, file_filter='*.ccf', parent=parent) save_dict_to_file(filename, self.cam_dict) SISO.Fg_saveConfig(self.fg, filename[:-3] + 'mcf') print('config saved')
def _getNrOfBoards(self): nrOfBoards = 0 (err, buffer, buflen) = s.Fg_getSystemInformation(None, s.INFO_NR_OF_BOARDS, s.PROP_ID_VALUE, 0) if (err == s.FG_OK): nrOfBoards = int(buffer) return nrOfBoards
def _liveView(self): """ Live image stream an visualization through OpenCV window. Leave _liveView by pressing "q" """ cv2.startWindowThread() cv2.namedWindow("IMG", 2) cv2.resizeWindow("IMG", 900, 900) s.Fg_AcquireEx(self.device, self.device_handle, s.GRAB_INFINITE, s.ACQ_STANDARD, self._free_run_buffer) last_img = -1 while True: cur_img_no = -1 iterations = 0 # Only refresh if new image is acquired while last_img == cur_img_no or cur_img_no <= 0: cur_img_no = s.Fg_getLastPicNumberEx(self.device, self.device_handle, self._free_run_buffer) if iterations > MAX_ITER: raise TimeoutError( "Max iterations reached while waiting for image! Missing a trigger signal?" ) iterations += 1 last_img = cur_img_no img_data = s.Fg_getImagePtrEx(self.device, cur_img_no, self.device_handle, self._free_run_buffer) # Convert to numpy array live_img = s.getArrayFrom(img_data, self._width, self._height) cv2.imshow("IMG", live_img) key = cv2.waitKey(1) & 0xFF if key == ord("q"): cv2.destroyAllWindows() break # Cleanup s.Fg_stopAcquireEx(self.device, self.device_handle, self._free_run_buffer, s.STOP_ASYNC) return
def grabStop(self): """ Stop grabbing images and return the images that have been recorded See Also -------- self.grabStart() """ # Unregister apc handler s.Fg_registerApcHandler(self.device, self.device_handle, None, s.FG_APC_CONTROL_BASIC) s.Fg_stopAcquireEx(self.device, self.device_handle, self._free_run_buffer, s.STOP_ASYNC) # Get image data from data class self._img_list = self._apc_data.img_list return self._img_list
def openDevice(self): """ Opens a camera device """ if not self.isOpen(): self.logger.debug('Creating grabber object') self.device = s.Fg_InitEx(self._applet, self.device_handle, 0) else: self.logger.debug('Grabber object already exists')
def load_config(self, filename=None, parent=None): if filename is None: filename = load_filename(directory=self.cam_config_dir, file_filter='*.ccf', parent=parent) self.cam_dict = load_dict_from_file(filename) self._load_cam_config() SISO.Fg_loadConfig(self.fg, filename[:-3] + 'mcf') print('new config loaded')
def write_single_fg_command(self, command, value, paramnum=None): ''' SDK Docs http://www.siliconsoftware.de/download/live_docu/RT5/en/documents/SDK/SDK.html#_2.3.1 2.4.1 lists all parameters and values. ''' if paramnum is None: parameter = self.cam_dict[command][1] else: parameter = self.cam_dict[command][1][paramnum] param = globals()[parameter] SISO.Fg_setParameterWithInt(self.fg, param, value, 0)
def closeDevice(self): """ Closes camera device """ self.logger.debug('Freeing the framegrabber device...') retval = s.Fg_FreeGrabber(self.device) if retval == s.FG_OK: self.device = None self.logger.debug('Freed successfully!') else: raise _MicroEnableException(retval)
def record(self): """ Blocking image acquisition of a previously defined number of images (see prepareRecording). Returns ------- imgs : list List of numpy arrays containing the recorded images """ s.Fg_AcquireEx(self.device, self.device_handle, self._pics_to_be_recorded, s.ACQ_STANDARD, self._buffer_handle) iterations = 0 while s.Fg_getStatusEx(self.device, s.NUMBER_OF_GRABBED_IMAGES, 0, self.device_handle, self._buffer_handle) != self._pics_to_be_recorded: if iterations > MAX_ITER: raise TimeoutError('Maximum number of iterations reached. ' 'Missing a trigger signal?') iterations += 1 s.Fg_stopAcquireEx(self.device, self.device_handle, self._buffer_handle, s.STOP_ASYNC) for img_no in range(self._pics_to_be_recorded): img = s.Fg_getImagePtrEx(self.device, img_no + 1, self.device_handle, self._buffer_handle) self._img_list.append( s.getArrayFrom(img, self._width, self._height).copy()) # Free buffer and set handle to None self._freeImageBuffer() self._pics_to_be_recorded = None return self._img_list
def getImage(self, *args, **kwargs): """ Get an image from the camera device *args and **kwargs are ignored parameters! This function uses self.free_run_buffer to write images to. Returns ------- img : np.ndarray Current camera image """ s.Fg_AcquireEx(self.device, self.device_handle, s.GRAB_INFINITE, s.ACQ_STANDARD, self._free_run_buffer) cur_img_no = 0 iterations = 0 while cur_img_no == 0: cur_img_no = s.Fg_getLastPicNumberEx(self.device, self.device_handle, self._free_run_buffer) if iterations > MAX_ITER: raise TimeoutError( "Max iterations reached while waiting for image! Missing a trigger signal?" ) iterations += 1 img = s.Fg_getImagePtrEx(self.device, cur_img_no, self.device_handle, self._free_run_buffer) np_img = s.getArrayFrom(img, self._width, self._height) s.Fg_stopAcquireEx(self.device, self.device_handle, self._free_run_buffer, s.STOP_ASYNC) return np_img.copy()
def __init__(self, cam_config_dir='/opt/Microscope/ConfigFiles/', filename=None, ccf_file=None): self.cam_config_dir = cam_config_dir self.fg = SISO.Fg_InitConfig(cam_config_dir + 'current.mcf', 0) self.camset = CameraSettings(self.fg, cam_config_dir, ccf_file=ccf_file) if filename is None: filename = save_filename(caption='Select filename base', directory='/home/ppzmis/Videos/') self.filename_base = filename.split('.')[0] print(self.filename_base) self.autosave = False
def grab(self, numpics=0): if numpics == 0: self.numpics = SISO.GRAB_INFINITE else: self.numpics = numpics err = SISO.Fg_AcquireEx(self.fg, 0, self.numpics, SISO.ACQ_STANDARD, self.memHandle) if (err != 0): print('Fg_AcquireEx() failed:', SISO.Fg_getLastErrorDescription(self.fg)) self.resource_cleanup() self.display_timer = DisplayTimer(0.03, self.display_img) self.display_timer.start() if self.numpics != SISO.GRAB_INFINITE: while self.display_timer.is_running: time.sleep(0.1) #self.stop() if self.autosave: print(self.numpics) self.save_vid(startframe=1, stopframe=self.numpics) self.resource_cleanup()
def selectBoardDialog(): maxNrOfboards = 10 nrOfBoardsFound = 0 nrOfBoardsPresent = getNrOfBoards() maxBoardIndex = -1 minBoardIndex = None if nrOfBoardsPresent <= 0: print("No Boards found!") return -1 print('Found', nrOfBoardsPresent, 'Board(s)') for i in range(0, maxNrOfboards): skipIndex = False boardType = s.Fg_getBoardType(i) if boardType == s.PN_MICROENABLE5_LIGHTBRIDGE_VCL: boardName = "MicroEnable 5 LB-VCL" elif boardType == s.PN_MICROENABLE5_MARATHON_VCLx: boardName = "MicroEnable 5 MA-VCLx" elif boardType == s.PN_MICROENABLE5_MARATHON_VCL: boardName = "MicroEnable 5 MA-VCL" else: boardName = "Unknown / Unsupported Board" skipIndex = True if not skipIndex: sys.stdout.write("Board ID " + str(i) + ": " + boardName + " 0x" + format(boardType, '02X') + "\n") nrOfBoardsFound = nrOfBoardsFound + 1 maxBoardIndex = i if minBoardIndex is None: minBoardIndex = i if nrOfBoardsFound >= nrOfBoardsPresent: break if nrOfBoardsFound < 0: break if nrOfBoardsFound <= 0: print("No Boards found!") return -1 inStr = "=====================================\n\nPlease choose a board[{0}-{1}]: ".format( minBoardIndex, maxBoardIndex) # userInput = input(inStr) userInput = 0 return int(userInput)
def _getParamWithInt(self, parameter): """ Short form of Fg_getParameterWithInt to reduce line length (since self.device and self.device_handle are always passed). Parameters ---------- parameter : silicon software enum Defines the parameter, which should be read. Returns ------- value : int Value of requested parameter. """ err, retval = s.Fg_getParameterWithInt(self.device, parameter, self.device_handle) if err != s.FG_OK: raise _MicroEnableException(err) return retval
def updateDeviceHandles(self): """ Refresh the list of available devices """ self.logger.debug('Searching for frame grabber devices') nrOfBoardsFound = 0 nrOfBoardsPresent = self._getNrOfBoards() for i in range(self.maxNrOfboards): if s.Fg_getBoardType(i) == s.PN_MICROENABLE4VD4CL: self.device_handles.append(i) nrOfBoardsFound += 1 if nrOfBoardsFound >= nrOfBoardsPresent: break self.logger.debug( 'Found {num} frame grabber device(s): {devices}'.format( num=len(self.device_handles), devices=self.device_handles))
self.reset_config = QPushButton("Reset Config") self.reset_config.clicked.connect(self.reset_callback) self.layout().addWidget(self.load_config) self.layout().addWidget(self.save_config) self.layout().addWidget(self.reset_config) def load_callback(self): self.cam.resource_cleanup() self.cam.reset_display() self.cam.camset.load_config(parent=self.parent) self.cam.initialise() self.cam.grab() def save_callback(self): self.cam.camset.save_config(parent=self.parent) def reset_callback(self): self.cam.resource_cleanup() self.cam.reset_display() self.cam.camset.reset_default_config() self.cam.initialise() self.cam.grab() if __name__ == '__main__': cam_config_dir = '/opt/Microscope/ConfigFiles/' fg = SISO.Fg_InitConfig(cam_config_dir + 'current.mcf', 0) camsettings = CameraSettingsGUI()
def __init__(self, device_handle, applet='Acq_FullAreaGray8'): """ Implementation of the microEnable4-VD4 framegrabber. Launches the camera in freerun mode (triggerMode 'off'). # TODO: Init camera with previous applet or store settings? Parameters ---------- device_handle : int Framegrabber device handle to identify the frame grabber applet : str String defining the used applet. Settings may differ between different applets """ super(Camera, self).__init__(device_handle) self.logger = logging.getLogger(__name__) if LOGGING_LEVEL is not None: self.logger.setLevel(LOGGING_LEVEL) if s.Fg_getBoardType(device_handle) != s.PN_MICROENABLE4VD4CL: self.logger.error( 'Board {0} is not supported by this package!'.format( s.Fg_getBoardNameByType(s.Fg_getBoardType(device_handle), s.Fg_getBoardType(device_handle)))) raise TypeError("Board {board} is not supported by this package!" "".format(board=s.Fg_getBoardNameByType(s.Fg_getBoardType(device_handle), s.Fg_getBoardType(device_handle)))) self._applet = applet self.logger.debug('Initializing Framegrabber...') self.device = s.Fg_InitEx(self._applet, device_handle, 0) # error handling err = s.Fg_getLastErrorNumber(self.device) if err < 0: msg = s.Fg_getErrorDescription(err) self.logger.error("Error", err, ":", msg) raise _MicroEnableException(err) else: self.logger.debug("Grabber initialized successfully!") self._clser_ref = s.clSerialInit(0) # Setting Camera link factory profile # Resolution: 1280x1024, Image freq.: 430, Mode: 8x8, CL-Conf.: FULL factory_profile = ':f7' self._clSerialWrite(command=factory_profile) s.Fg_setParameterWithInt(self.device, s.FG_BITALIGNMENT, s.FG_LEFT_ALIGNED, self.device_handle) s.Fg_setParameterWithInt(self.device, s.FG_GEN_ENABLE, s.FG_CAMPORT, self.device_handle) s.Fg_setParameterWithInt(self.device, s.FG_TRIGGER_LEGACY_MODE, s.FG_ON, self.device_handle) self.setTriggerMode('off') self._width = \ s.Fg_getParameterWithInt(self.device, s.FG_WIDTH, self.device_handle)[1] self._height = \ s.Fg_getParameterWithInt(self.device, s.FG_HEIGHT, self.device_handle)[1] self._free_run_buffer = self._prepareImageBuffer(10) self._pics_to_be_recorded = None self._buffer_handle = None self._img_list = list() self._apc_data = None
def __init__(self, err): super(_MicroEnableException, self).__init__() self.message = 'Error {err}: {msg}' \ ''.format(err=err, msg=s.Fg_getErrorDescription(err))