def _scanner_worker(task_queue, overlay_queue, result_queue, options): """ Function used as the main loop of a worker process. Scan images for barcodes, combining partial scans until a full puck is reached. Keep the record of the last scan which was at least partially successful (aligned geometry and some barcodes scanned). For each new frame, we can attempt to merge the results with this previous plates so that we don't have to re-read any of the previously captured barcodes (because this is a relatively expensive operation). """ last_plate_time = time.time() SlotScanner.DEBUG = options.slot_images.value() SlotScanner.DEBUG_DIR = options.slot_image_directory.value() plate_type = options.plate_type.value() barcode_size = options.barcode_size.value() if plate_type == "None": scanner = OpenScanner(barcode_size) else: scanner = GeometryScanner(plate_type, barcode_size) while True: # Get next image from queue (terminate if a queue contains a 'None' sentinel) frame = task_queue.get(True) if frame is None: break # Make grayscale version of image image = Image(frame) gray_image = image.to_grayscale() # If we have an existing partial plate, merge the new plate with it and only try to read the # barcodes which haven't already been read. This significantly increases efficiency because # barcode read is expensive. scan_result = scanner.scan_next_frame(gray_image) if options.console_frame.value(): scan_result.print_summary() if scan_result.success(): # Record the time so we can see how long its been since we last saw a plate last_plate_time = time.time() plate = scan_result.plate() if scan_result.already_scanned(): overlay_queue.put(TextOverlay(SCANNED_TAG, Color.Green())) elif scan_result.any_valid_barcodes(): overlay_queue.put(PlateOverlay(plate, options)) _plate_beep(plate, options) if scan_result.any_new_barcodes(): result_queue.put((plate, image)) else: time_since_plate = time.time() - last_plate_time if time_since_plate > NO_PUCK_TIME: overlay_queue.put(TextOverlay(scan_result.error(), Color.Red()))
def _scan_file_image(self): """Load and process (scan for barcodes) an image from file """ filepath = str(QtGui.QFileDialog.getOpenFileName(self, "Open file")) if filepath: cv_image = Image.from_file(filepath) gray_image = cv_image.to_grayscale() # Scan the image for barcodes plate_type = self._config.plate_type.value() barcode_size = self._config.barcode_size.value() SlotScanner.DEBUG = self._config.slot_images.value() SlotScanner.DEBUG_DIR = self._config.slot_image_directory.value() if plate_type == "None": scanner = OpenScanner(barcode_size) else: scanner = GeometryScanner(plate_type, barcode_size) scan_result = scanner.scan_next_frame(gray_image, is_single_image=True) plate = scan_result.plate() # If the scan was successful, store the results if plate is not None: self.recordTable.add_record(plate, cv_image) else: error = "There was a problem scanning the image:\n{}".format(scan_result.error()) QtGui.QMessageBox.warning(self, "Scanning Error", error)
def _scan_file_image(self): """Load and process (scan for barcodes) an image from file """ filepath = str(QtGui.QFileDialog.getOpenFileName(self, 'Open file')) if filepath: cv_image = Image.from_file(filepath) gray_image = cv_image.to_grayscale() # Scan the image for barcodes plate_type = self._config.plate_type.value() barcode_size = self._config.barcode_size.value() SlotScanner.DEBUG = self._config.slot_images.value() SlotScanner.DEBUG_DIR = self._config.slot_image_directory.value() if plate_type == "None": scanner = OpenScanner(barcode_size) else: scanner = GeometryScanner(plate_type, barcode_size) scan_result = scanner.scan_next_frame(gray_image, is_single_image=True) plate = scan_result.plate() # If the scan was successful, store the results if plate is not None: self.recordTable.add_record(plate, cv_image) else: error = "There was a problem scanning the image:\n{}".format(scan_result.error()) QtGui.QMessageBox.warning(self, "Scanning Error", error)