示例#1
0
 def test_paste_when_location_is_inside_image_4_channels_no_blending_when_source_alpha_is_255(
         self):
     image_target = Image(img=np.full((10, 10, 4), 30.0, np.uint8))
     image_src = Image(img=np.full((1, 1, 4), 255.0, np.uint8))
     a = np.sum(image_src.img[0:1, 0:1, 0:3])
     image_target.paste(image_src, 0, 0)
     b = np.sum(image_target.img[0:1, 0:1, 0:3])
     self.assertEquals(a, b)  #target changed into source
示例#2
0
 def test_paste_when_location_is_inside_image_4_channels_blending_works(
         self):
     image_target = Image(img=np.full((10, 10, 4), 10, np.uint8))
     image_src = Image(img=np.full((1, 1, 4), 25, np.uint8))
     image_target.paste(image_src, 0, 0)
     a = np.sum(image_src.img[0:1, 0:1, 0:3])
     b = np.sum(image_target.img[0:1, 0:1, 0:3])
     self.assertNotEquals(a, b)
     self.assertEquals(b, 33)
示例#3
0
    def target_image_alpha_becomes_255_after_paste(self):
        image_target = Image(img=np.full((5, 5, 4), 10, np.uint8))
        max_alpha_before_paste = np.max(image_target.img[:, :, 3])
        image_src = Image(img=np.full((1, 1, 4), 25, np.uint8))
        image_target.paste(image_src, 0, 0)
        max_alpha_after_paste = np.max(image_target.img[:, :, 3])

        self.assertEquals(max_alpha_before_paste, 10)
        self.assertEquals(max_alpha_after_paste,
                          255)  #I expected it to be as it was before
示例#4
0
 def test_paste_when_location_is_outside_image_negative_coordinates_3_channels(
         self):
     image_target = Image.blank(10, 10)
     image_src = Image(img=np.full((2, 2, 3), 2, np.uint8))
     image_target.paste(image_src, -10, 0)
     a = np.sum(image_target.img)
     self.assertEquals(a, 0)
示例#5
0
    def _adaptive_threshold(image, block_size, c):
        """ Perform an adaptive threshold operation on the image, reducing it to a binary image.
        """
        thresh = cv2.adaptiveThreshold(image, 255.0,
                                       cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, block_size, c)

        return Image(thresh)
示例#6
0
    def test_paste_when_location_is_inside_image_4_target_alpha_does_not_matter(
            self):
        image_target = Image(img=np.full((10, 10, 4), 10, np.uint8))
        image_src = Image(img=np.full((1, 1, 4), 25, np.uint8))
        image_target.paste(image_src, 0, 0)
        b = np.sum(image_target.img[0:1, 0:1, 0:3])
        self.assertEquals(b, 33)

        array = np.full((10, 10, 4), 10, np.uint8)
        array[:, :, 3] = np.ones((10, 10), np.uint8)
        image_target_new = Image(img=array)
        image_src_new = Image(img=np.full((1, 1, 4), 25, np.uint8))
        image_target_new.paste(image_src_new, 0, 0)
        c = np.sum(image_target_new.img[0:1, 0:1, 0:3])
        self.assertEquals(c, 33)
        self.assertEquals(b, c)
示例#7
0
    def _process_frame(self, frame, config, overlay_queue, result_queue,
                       message_queue):
        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 = self._scanner.scan_next_frame(gray_image)

        if config.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 puck
            self._last_puck_time = time.time()

            plate = scan_result.plate()
            if scan_result.any_valid_barcodes():
                overlay_queue.put(PlateOverlay(plate, config))
                self._plate_beep(plate, config.scan_beep.value())

            if scan_result.any_new_barcodes():
                result_queue.put((plate, image))
        elif scan_result.any_valid_barcodes():
            # We have read valid barcodes but they are not new, so the scanner didn't even output a plate
            self._last_puck_time = time.time()
            message_queue.put(NoNewBarcodeMessage())
        elif scan_result.error() is not None and (
                time.time() - self._last_puck_time > NO_PUCK_TIME):
            message_queue.put(ScanErrorMessage(scan_result.error()))
示例#8
0
 def test_paste_when_location_is_inside_image_3_channels(self):
     image_target = Image.blank(10, 10)
     image_src = Image(img=np.full((1, 1, 3), 2, np.uint8))
     image_target.paste(image_src, 0, 0)
     a = np.sum(image_target.img)
     self.assertEquals(a, 6)
     self.assertEquals(image_target.img[0, 0, 1], 2)
     self.assertEquals(image_target.img[0, 1, 1], 0)
示例#9
0
    def draw_on_image(self, img):
        """ Draw the status message to the image.
        """
        image = Image(img)

        # If the overlay has not expired, draw on the plate highlight and/or the status message
        if not self.has_expired():
            image.draw_text(self._text, image.center(), self._color,
                            centered=True, scale=2, thickness=3)
示例#10
0
 def _do_close_morph(threshold_image, morph_size):
     """ Perform a generic morphological operation on an image. """
     element = cv2.getStructuringElement(cv2.MORPH_RECT,
                                         (morph_size, morph_size))
     closed = cv2.morphologyEx(threshold_image.img,
                               cv2.MORPH_CLOSE,
                               element,
                               iterations=1)
     return Image(closed)
示例#11
0
    def draw_on_image(self, img):
        """ Draw the plate highlight  to the image.
        """
        image = Image(img)

        # If the overlay has not expired, draw on the plate highlight and/or the status message
        if not self.has_expired():
            self._plate.draw_plate(image, Color.Blue())
            self._plate.draw_pins(image, self._options)
示例#12
0
    def _run_capture(self, stream, camera_positon, task_queue, view_queue,
                     overlay_queue, stop_queue, message_queue):
        # Store the latest image overlay which highlights the puck
        latest_overlay = Overlay(0)
        last_time = time.time()

        display = True
        while stop_queue.empty():
            if display:
                print("--- capture inside loop")
                display = False

            # Capture the next frame from the camera
            frame = stream.get_frame()
            if frame is None:
                message_queue.put(CameraErrorMessage(camera_positon))
                return

            # Add the frame to the task queue to be processed
            # NOTE: the rate at which frames are pushed to the task queue is lower than the rate at which frames are acquired
            if task_queue.qsize() < Q_LIMIT and (time.time() - last_time >=
                                                 INTERVAL):
                # Make a copy of image so the overlay doesn't overwrite it
                task_queue.put(frame.copy())
                last_time = time.time()

            # All frames (scanned or not) are pushed to the view queue for display
            # Get the latest overlay - it won't be generated from the current frame but it doesn't matter
            while not overlay_queue.empty():
                try:
                    latest_overlay = overlay_queue.get(False)
                except queue.Empty:
                    # Race condition where the scanner worker was stopped and the overlay queue cleared between
                    # our calls to queue.empty() and queue.get(False)
                    latest_overlay = Overlay(0)

            # Draw the overlay on the frame
            latest_overlay.draw_on_image(frame)

            view_queue.put(Image(frame))

        print("CAPTURE stop & flush queues")
        self._flush_queue(task_queue)
        print("--- capture task Q flushed")
        self._flush_queue(view_queue)
        print("--- capture view Q flushed")
示例#13
0
    def _DEBUG_WIGGLES_READ(self, barcode, locate_type, side_length):
        if not self.DEBUG:
            return

        if barcode.is_valid():
            print("DEBUG - WIGGLES SUCCESSFUL - " + locate_type)
            result = "_SUCCESS"
        else:
            result = "_FAIL"

        slot_img = Image(barcode._image).to_alpha()

        self._DEBUG_SAVE_IMAGE(slot_img, locate_type + result, side_length - 1)

        fp = barcode._finder_pattern
        fp.draw_to_image(slot_img, Color.Green())

        self._DEBUG_SAVE_IMAGE(slot_img, locate_type + result, side_length - 1)
示例#14
0
    def __init__(self, original_frame):
        self._frame = original_frame

        self._image =  Image(self._frame)
示例#15
0
def polygon_image(lines):
    blank = Image.blank(image_original.width, image_original.height, 3, 255)
    img = cv2.drawContours(blank.img, lines, -1, (0, 255, 0), 1)
    return Image(img)
示例#16
0
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()))
示例#17
0
 def test_paste_when_location_is_outside_image_x_off(self):
     image_target = Image.blank(10, 10)
     image_src = Image(img=np.full((5, 5, 3), 2, np.uint8))
     image_target.paste(image_src, 20, 0)
     a = np.sum(image_target.img)
     self.assertEquals(a, 0)
示例#18
0
 def _do_threshold(gray_image, block_size, c):
     """ Perform an adaptive threshold operation on the image. """
     raw = gray_image.img
     thresh = cv2.adaptiveThreshold(raw, 255.0, cv2.ADAPTIVE_THRESH_MEAN_C,
                                    cv2.THRESH_BINARY, block_size, c)
     return Image(thresh)