示例#1
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()))
示例#2
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()))
示例#3
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)
示例#4
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)
示例#5
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
示例#6
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)
示例#7
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)
示例#8
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)
示例#9
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
示例#10
0
    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)
示例#11
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)
示例#12
0
    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 run_scans(img_file, expected_codes):
    filepath = os.path.join(TEST_IMG_DIR, img_file)
    cv_image = Image.from_file(filepath)
    gray_image = cv_image.to_grayscale()
    results = GeometryScanner("Unipuck",
                              [14]).scan_next_frame(gray_image,
                                                    is_single_image=True)
    plate = results.plate()
    store_scan(img_file, plate, cv_image)

    correctly_read_count = 0
    slots = [plate.slot(i) for i in range(16)]
    num_found = len([s for s in slots if s.state() == s.VALID])
    #barcodes_for_debug = [s.barcode_data() for s in slots]
    assert num_found == len(expected_codes)

    for expected_code in expected_codes:
        expected_code_text = expected_code[0]
        slot = expected_code[1]

        barcode_read = plate.slot(slot).barcode_data()
        #print(barcode_read, expected_code_text)
        if barcode_read == expected_code_text:
            correctly_read_count += 1

    assert correctly_read_count == len(expected_codes)
示例#14
0
 def test_draw_circle_thickness_equals_one(self):
     img = Image.blank(40, 40)
     circle = Circle(Point(20, 20), 10)
     img.draw_circle(circle, Color(200, 200, 200), 1)
     self.assertEquals(img.img[10][20][1], 200)
     self.assertEquals(img.img[9][20][1], 0)
     self.assertEquals(img.img[11][20][1], 0)
示例#15
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)
示例#16
0
def TRIANGLE_DEMO():
    """ Draw a set of axes and a triangle. Perform a series of random transformations
     on the triangle and display the results.
    """
    A = Point(143, 52)
    B = Point(17, 96.5)
    C = Point(0, 0)

    for i in range(10):
        # Create random transformation
        angle = random.random() * 2 * math.pi
        scale = random.random() * 3
        delX = (random.random() - 0.5) * 200
        delY = (random.random() - 0.5) * 200
        translate = Point(delX, delY)
        transform = Transform(translate, angle, scale)

        # Transform the triangle
        A_ = transform.transform(A)
        B_ = transform.transform(B)
        C_ = transform.transform(C)

        # From the line A-B and the transformed line A'-B', determine what the transformation was
        # This should be the same as the original transformation
        trans_calc = Transform.line_mapping(A, B, A_, B_)
        print("Angle: {:.2f}; {:.2f}".format(rad_to_deg(angle), rad_to_deg(trans_calc.rot)))
        print("Trans: ({}); ({})".format(translate, trans_calc.trans))
        print("Zoom: {:.2f}; {:.2f}".format(scale, trans_calc.zoom))

        # Display on image
        image = Image.blank(1000, 800)
        image.draw_offset = IMG_CENTER
        draw_axes(image, 300)

        # Draw original triangle
        image.draw_line(A, B, Color.Red(), 5)
        image.draw_line(C, B, Color.Red(), 5)
        image.draw_line(A, C, Color.Red(), 5)

        #Draw transformed triangle
        image.draw_line(A_, B_, Color.Green())
        image.draw_line(A_, C_, Color.Green())
        image.draw_line(C_, B_, Color.Green())

        # Check that the reverse transformation works properly
        A__ = transform.reverse(A_)
        B__ = transform.reverse(B_)
        C__ = transform.reverse(C_)

        # Draw the reverse transformation - this should overlap the origianl triangle
        image.draw_line(A__, B__, Color.Green(), 1)
        image.draw_line(A__, C__, Color.Green(), 1)
        image.draw_line(C__, B__, Color.Green(), 1)

        # Write the transformation on the image
        image.draw_text(transform.__str__(), Point(-450, 350), Color.White(), centered=False, scale=0.5, thickness=1)

        # Show the image
        image.popup()
示例#17
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)
示例#18
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)
示例#19
0
def edges_image(edge_sets):
    blank = Image.blank(image_original.width, image_original.height, 3, 255)

    for shape in edge_sets:
        for edge in shape:
            print(edge[1])
            blank.draw_line(Point.from_array(edge[0]), Point.from_array(edge[1]), Color.Green(), 1)

    return blank
示例#20
0
 def test_sub_image_has_size_of_input_image_if_2xradius_covers_the_whole_image(
         self):
     image = Image.blank(5, 6, 3, 0)
     x_center = 2
     y_center = 2
     radius = 7
     sub_image, roi = image.sub_image(Point(x_center, y_center), radius)
     height = sub_image.height
     width = sub_image.width
     self.assertEquals(width, image.width)
     self.assertEquals(height, image.height)
示例#21
0
 def test_sub_image_is_created_if_the_center_is_outside_but_the_radius_ovelaps_with_input_image(
         self):
     image = Image.blank(9, 9, 3, 0)
     x_center = 10
     y_center = 10
     radius = 2
     sub_image, roi = image.sub_image(Point(x_center, y_center), radius)
     height = sub_image.height
     width = sub_image.width
     self.assertEquals(width, 1)
     self.assertEquals(height, 1)
示例#22
0
 def test_sub_image_has_size_0x0_if_center_and_radius_outside_the_input_image(
         self):
     image = Image.blank(5, 6, 3, 0)
     x_center = 10
     y_center = 10
     radius = 2
     sub_image, roi = image.sub_image(Point(x_center, y_center), radius)
     height = sub_image.height
     width = sub_image.width
     self.assertEquals(width, 0)
     self.assertEquals(height, 0)
示例#23
0
 def test_sub_image_is_not_square_if_center_x_is_too_close_to_the_edge(
         self):
     image = Image.blank(10, 10, 3, 0)
     x_center = 9
     y_center = 5
     radius = 2
     sub_image, roi = image.sub_image(Point(x_center, y_center), radius)
     height = sub_image.height
     width = sub_image.width
     self.assertEquals(width, 3)
     self.assertEquals(height, 2 * radius)
     self.assertNotEquals(width, height)
示例#24
0
 def test_draw_circle_thickness_equals_four(self):
     img = Image.blank(40, 40)
     circle = Circle(Point(20, 20), 10)
     img.draw_circle(circle, Color(200, 200, 200), 4)
     self.assertEquals(img.img[6][20][1], 0)
     self.assertEquals(img.img[7][20][1], 0)  #!!
     self.assertEquals(img.img[8][20][1], 200)
     self.assertEquals(img.img[10][20][1], 200)
     self.assertEquals(img.img[9][20][1], 200)
     self.assertEquals(img.img[11][20][1], 200)
     self.assertEquals(img.img[12][20][1], 200)
     self.assertEquals(img.img[13][20][1], 0)  #!!
     self.assertEquals(img.img[14][20][1], 0)
示例#25
0
    def test_sub_image_is_square_with_side_length_2_radius_if_enough_space_to_cut_from(
            self):
        image = Image.blank(10, 10, 3, 0)

        x_center = 5
        y_center = 5
        radius = 2
        sub_image, roi = image.sub_image(Point(
            x_center, y_center), radius)  #sub_image returns a raw cv image

        height = sub_image.height
        width = sub_image.width
        self.assertEquals(width, 2 * radius)
        self.assertEquals(height, 2 * radius)
        self.assertEquals(width, height)
示例#26
0
    def test_draw_circle_centre_is_kept(self):
        img = Image.blank(40, 40)
        circle = Circle(Point(20, 20), 1)
        img.draw_circle(circle, Color(200, 200, 200), 1)
        self.assertEquals(img.img[18][20][1], 0)
        self.assertEquals(img.img[19][20][1], 200)
        self.assertEquals(img.img[20][20][1], 0)
        self.assertEquals(img.img[21][20][1], 200)
        self.assertEquals(img.img[22][20][1], 0)

        self.assertEquals(img.img[20][18][1], 0)
        self.assertEquals(img.img[20][19][1], 200)
        self.assertEquals(img.img[20][20][1], 0)
        self.assertEquals(img.img[20][21][1], 200)
        self.assertEquals(img.img[20][22][1], 0)
def run_scans(img_file, expected_codes):
    filepath = os.path.join(TEST_IMG_DIR, img_file)
    print(img_file)
    cv_image = Image.from_file(filepath)
    gray_image = cv_image.to_grayscale()
    results = GeometryScanner("Unipuck", [14]).scan_next_frame(gray_image, is_single_image=True)
    plate = results.plate()
    if plate != None:
        for expected_code in expected_codes:
            expected_code_text = expected_code[0] #text
            slot_number = expected_code[1] #number
            slot = plate.slot(slot_number)
            read_code_text = slot.barcode_data()
            #print(slot_number, read_code_text, expected_code_text)
            if slot.state() == slot.VALID:
                assert read_code_text == expected_code_text
示例#28
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")
示例#29
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)
def CIRCLES_DEMO():
    """ Draw a set of axes and a random set of circles. Perform a series of
    random transformations on the circles.
    """
    # Create a set of random circles
    points = []
    for i in range(10):
        X = (random.random()) * 200
        Y = (random.random()) * 200
        points.append(Point(X, Y))

    for i in range(10):
        # Create random transformation
        angle = random.random() * 2 * math.pi
        scale = random.random() * 3
        delX = (random.random() - 0.5) * 200
        delY = (random.random() - 0.5) * 200
        translate = Point(delX, delY)
        trs = Transform(translate, angle, scale)

        # Display on image
        image = Image.blank(1000, 800)
        image.draw_offset = IMG_CENTER
        draw_axes(image, 300)

        # Draw the circles and transformed circles on the image
        radius = 10
        for p in points:
            circle = Circle(p, radius)
            trans_circle = Circle(trs.transform(p), radius * trs.zoom)
            image.draw_circle(circle, Color.Red())
            image.draw_circle(trans_circle, Color.Blue())

        # Write the transformation on the image
        image.draw_text(trs.__str__(),
                        Point(-450, 350),
                        Color.White(),
                        centered=False,
                        scale=0.5,
                        thickness=1)

        # Show the image
        image.popup()
示例#31
0
def run_tests():

    # Run all of the test cases
    total = 0
    correct = 0
    found = 0
    start = time.clock()
    for case in TEST_CASES:
        file = case[0]
        expected_codes = case[1]
        total += len(expected_codes)

        filename = TEST_IMG_DIR + file
        cv_image = Image.from_file(filename)
        gray_image = cv_image.to_grayscale()
        results = GeometryScanner("Unipuck",
                                  14).scan_next_frame(gray_image,
                                                      is_single_image=True)
        plate = results.plate()
        store_scan(plate, cv_image)

        pass_count = 0
        slots = [plate.slot(i) for i in range(16)]
        num_found = len([s for s in slots if s.state() == s.VALID])
        for expected_code in expected_codes:
            text = expected_code[0]
            slot = expected_code[1]

            data = plate.slot(slot).barcode_data()
            if data == text:
                pass_count += 1

        result = "pass" if pass_count == len(expected_codes) else "FAIL"
        print("{0} - {1}  -  {2}/{3} matches ({4} found)".format(
            file, result, pass_count, len(expected_codes), num_found))

        correct += pass_count
        found += num_found

    end = time.clock()
    print("Summary | {0} secs | {1} correct | {2} found | {3} total".format(
        end - start, correct, found, total))
示例#32
0
    def test_circle_is_correctly_detected_when_there_is_one_circle_in_the_image(
            self):
        img = Image.blank(40, 40)
        circle = Circle(Point(20, 20), 10)
        img.draw_circle(circle, Color(200, 200, 200), 2)
        grey = img.to_grayscale()
        #parameters of the detector very important - a bit dubious test
        decorator = CircleDetector()
        decorator.set_maximum_radius(20)
        decorator.set_minimum_radius(5)
        decorator.set_accumulator_threshold(20)
        decorator.set_canny_threshold(20)

        list = decorator.find_circles(grey)

        self.assertEqual(list.__len__(), 1)
        # self.assertEqual(list[0].radius(), circle.radius())
        #self.assertEqual(list[0].center().x, circle.center().x + 1)
        #self.assertEqual(list[0].center().y, circle.center().y + 1)
        self.assertEqual(list[0].area(), circle.area())
示例#33
0
    def test_circle_is_correctly_detected_when_there_there_are_two_circles_in_the_image_not_intersecting(
            self):

        img = Image.blank(100, 100)
        circle_a = Circle(Point(20, 20), 10)
        circle_b = Circle(Point(50, 50), 10)
        img.draw_circle(circle_a, Color(10, 50, 100), 2)
        img.draw_circle(circle_b, Color(10, 50, 100), 2)
        grey = img.to_grayscale()

        decorator = CircleDetector()
        decorator.set_maximum_radius(20)
        decorator.set_minimum_radius(5)
        decorator.set_accumulator_threshold(30)
        decorator.set_canny_threshold(30)
        decorator.set_minimum_separation(10)

        list = decorator.find_circles(grey)

        self.assertEqual(list.__len__(), 2)
示例#34
0
def run_tests():

    # Run all of the test cases
    total = 0
    correct = 0
    found = 0
    start = time.clock()
    for case in TEST_CASES:
        file = case[0]
        expected_codes = case[1]
        total += len(expected_codes)

        filename = TEST_IMG_DIR + file
        cv_image = Image.from_file(filename)
        gray_image = cv_image.to_grayscale()
        results = GeometryScanner("Unipuck", 14).scan_next_frame(gray_image, is_single_image=True)
        plate = results.plate()
        store_scan(plate, cv_image)

        pass_count = 0
        slots = [plate.slot(i) for i in range(16)]
        num_found = len([s for s in slots if s.state() == s.VALID])
        for expected_code in expected_codes:
            text = expected_code[0]
            slot = expected_code[1]

            data = plate.slot(slot).barcode_data()
            if data == text:
                pass_count += 1

        result = "pass" if pass_count == len(expected_codes) else "FAIL"
        print("{0} - {1}  -  {2}/{3} matches ({4} found)".format(file, result, pass_count, len(expected_codes), num_found))

        correct += pass_count
        found += num_found

    end = time.clock()
    print("Summary | {0} secs | {1} correct | {2} found | {3} total".format(end-start, correct,found,total))
示例#35
0
def CIRCLES_DEMO():
    """ Draw a set of axes and a random set of circles. Perform a series of
    random transformations on the circles.
    """
    # Create a set of random circles
    points = []
    for i in range(10):
        X = (random.random()) * 200
        Y = (random.random()) * 200
        points.append(Point(X, Y))

    for i in range(10):
        # Create random transformation
        angle = random.random() * 2 * math.pi
        scale = random.random() * 3
        delX = (random.random() - 0.5) * 200
        delY = (random.random() - 0.5) * 200
        translate = Point(delX, delY)
        trs = Transform(translate, angle, scale)

        # Display on image
        image = Image.blank(1000, 800)
        image.draw_offset = IMG_CENTER
        draw_axes(image, 300)

        # Draw the circles and transformed circles on the image
        radius = 10
        for p in points:
            circle = Circle(p, radius)
            trans_circle = Circle(trs.transform(p), radius * trs.zoom)
            image.draw_circle(circle, Color.Red())
            image.draw_circle(trans_circle, Color.Blue())

        # Write the transformation on the image
        image.draw_text(trs.__str__(), Point(-450, 350), Color.White(), centered=False, scale=0.5, thickness=1)

        # Show the image
        image.popup()
示例#36
0
 def image(self):
     image = Image.from_file(self.image_path)
     return image
""" This file gives an illustrated demonstration of process involved in
locating a datamatrix in an image. This isn't to be used as a test as it
re-implements some parts of the locator algorithm

"""
import cv2

from dls_util.image import Image, Color
from dls_util.shape import Point
from dls_barcode.datamatrix.locate.locate_contour import ContourLocator as CL


# Load the image file
folder = "./demo-resources/"
file = folder + "dm.png"
image_original = Image.from_file(file)

# Convert to a grayscale image
image_mono = image_original.to_grayscale()

# Perform adaptive threshold
block_size = 35
C = 16
image_threshold = CL._do_threshold(image_mono, block_size, C)

# Perform morphological close
close_size = 2
image_morphed = CL._do_close_morph(image_threshold, close_size)

# Find a bunch of contours in the image.
contours = CL._get_contours(image_morphed)
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)