コード例 #1
0
    def __init__(self, file):
        Config.__init__(self, file)

        add = self.add

        if IS_BUNDLED:
            default_store = "./store/"
        else:
            default_store = "../store/"

        self.color_ok = add(ColorConfigItem, "Read Color", Color.Green())
        self.color_unreadable = add(ColorConfigItem, "Not Read Color",
                                    Color.Red())
        self.color_empty = add(ColorConfigItem, "Empty Color", Color.Grey())

        self.camera_number = add(IntConfigItem, "Camera Number", default=0)
        self.camera_width = add(IntConfigItem, "Camera Width", default=1920)
        self.camera_height = add(IntConfigItem, "Camera Height", default=1080)

        self.plate_type = add(EnumConfigItem,
                              "Sample Plate Type",
                              default=Geometry.UNIPUCK,
                              extra_arg=Geometry.TYPES)
        self.barcode_size = add(EnumConfigItem,
                                "Datamatrix Size",
                                default=DataMatrix.DEFAULT_SIZE,
                                extra_arg=DatamatrixSizeTable.valid_sizes())

        self.scan_beep = add(BoolConfigItem,
                             "Beep While Scanning",
                             default=True)
        self.scan_clipboard = add(BoolConfigItem,
                                  "Results to Clipboard",
                                  default=True)

        self.image_puck = add(BoolConfigItem, "Draw Puck", default=True)
        self.image_pins = add(BoolConfigItem,
                              "Draw Slot Highlights",
                              default=True)
        self.image_crop = add(BoolConfigItem, "Crop to Puck", default=True)

        self.store_directory = add(DirectoryConfigItem,
                                   "Store Directory",
                                   default=default_store)
        self.store_capacity = add(IntConfigItem,
                                  "Results History Size",
                                  default=50)

        self.console_frame = add(BoolConfigItem,
                                 "Print Frame Summary",
                                 default=False)
        self.slot_images = add(BoolConfigItem,
                               "Save Debug Images",
                               default=False)
        self.slot_image_directory = add(DirectoryConfigItem,
                                        "Debug Directory",
                                        default="../debug-output/")

        self.initialize_from_file()
コード例 #2
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()
コード例 #3
0
def draw_axes(img, length):
    # Draw axes
    x_neg = Point(-length, 0)
    x_pos = Point(length, 0)
    y_neg = Point(0, -length)
    y_pos = Point(0, length)

    img.draw_line(y_neg, y_pos, Color.White(), 5)
    img.draw_line(x_neg, x_pos, Color.White(), 5)
コード例 #4
0
def _draw_finder_pattern(image, transform, fp):
    center = Point(transform.x, transform.y)
    angle = transform.rot
    rotated = image.rotate(transform.rot, center)

    c1 = _rotate_around_point(fp.c1, -angle, center)
    c2 = _rotate_around_point(fp.c2, -angle, center)
    c3 = _rotate_around_point(fp.c3, -angle, center)

    img = rotated.to_alpha()
    img.draw_line(c1, c2, Color.Green(), 1)
    img.draw_line(c1, c3, Color.Green(), 1)

    return img
コード例 #5
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)
コード例 #6
0
    def _DEBUG_SQUARE_LOCATOR(self, slot_img, fp, slot_num):
        if not self.DEBUG:
            return

        color = slot_img.to_alpha()
        fp.draw_to_image(color, Color.Green())
        self._DEBUG_SAVE_IMAGE(color, "SQUARE_FP", slot_num)
コード例 #7
0
ファイル: control.py プロジェクト: krisward/dls_barcode
    def _get_dialog_color(start_color):
        color = start_color

        qt_col = QtGui.QColorDialog.getColor(start_color.to_qt())
        if qt_col.isValid():
            color = Color.from_qt(qt_col)

        return color
コード例 #8
0
    def _get_dialog_color(start_color):
        color = start_color

        qt_col = QColorDialog.getColor(start_color.to_qt())
        if qt_col.isValid():
            color = Color.from_qt(qt_col)

        return color
コード例 #9
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
コード例 #10
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)
コード例 #11
0
    def _DEBUG_MULTI_FP_IMAGE(self, slot_img, fps, slot_num):
        if not self.DEBUG:
            return

        if len(fps) > 1:
            color = slot_img.to_alpha()
            for fp in fps:
                fp.draw_to_image(color, Color.Random())
            self._DEBUG_SAVE_IMAGE(color, "DEEP CONTOUR_ALL FPS", slot_num)
コード例 #12
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()
コード例 #13
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)
コード例 #14
0
def _draw_square_and_writing(image, transform, size):
    marked_img = _draw_square(image, transform, size)

    txt_height = SquareLocator.TXT_HEIGHT * size
    txt_width = SquareLocator.TXT_WIDTH * size

    center = transform.trans
    x1 = center.x - txt_width/2
    x2 = x1 + txt_width
    y_offset = SquareLocator.TXT_OFFSET*size

    y1 = center.y + y_offset - txt_height/2
    y2 = y1 + txt_height
    marked_img.draw_rectangle((x1, y1, x2, y2), Color.Green(), 1)

    y1 = center.y - y_offset - txt_height/2
    y2 = y1 + txt_height
    marked_img.draw_rectangle((x1, y1, x2, y2), Color.Green(), 1)

    return marked_img
コード例 #15
0
def _draw_square(image, transform, size):
    radius = size/2
    center = Point(transform.x, transform.y)
    rotated = image.rotate(transform.rot, center)

    x1, y1 = center.x-radius, center.y-radius
    x2, y2 = x1 + size, y1 + size

    roi = (x1, y1, x2, y2)
    marked_img = rotated.to_alpha()
    marked_img.draw_rectangle(roi, Color.Green(), 1)

    return marked_img
コード例 #16
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)
コード例 #17
0
    def get_marked_image(self, options):
        image = self.get_image()
        geo = self.geometry

        if options.image_puck.value():
            geo.draw_plate(image, Color.Blue())

        if options.image_pins.value():
            self._draw_pins(image, geo, options)

        if options.image_crop.value():
            geo.crop_image(image)

        return image
コード例 #18
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)
コード例 #19
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)
コード例 #20
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())
コード例 #21
0
    def __init__(self, file, file_manager):
        Config.__init__(self, file, file_manager)

        add = self.add

        if IS_BUNDLED:
            default_store = "./store/"
        else:
            default_store = "../store/"

        self.color_ok = add(ColorConfigItem, "Pin/Puck Read", Color.Green())
        self.color_accept = add(ColorConfigItem, "Puck Partially Read",
                                Color.Yellow())
        self.color_unreadable = add(ColorConfigItem, "Pin/Puck Not Read",
                                    Color.Red())
        self.color_empty = add(ColorConfigItem, "Pin Empty", Color.Grey())

        self.plate_type = add(EnumConfigItem,
                              "Sample Plate Type",
                              default=Geometry.UNIPUCK,
                              extra_arg=Geometry.TYPES)
        self.top_barcode_size = add(
            EnumConfigItem,
            "Datamatrix Size",
            default=DataMatrix.DEFAULT_SIZE,
            extra_arg=DatamatrixSizeTable.valid_sizes())
        self.top_camera_timeout = add(IntConfigItem,
                                      "Scan Timeout",
                                      default=15,
                                      extra_arg="s")

        self.scan_beep = add(BoolConfigItem,
                             "Beep While Scanning",
                             default=True)
        self.scan_clipboard = add(BoolConfigItem,
                                  "Results to Clipboard",
                                  default=True)

        self.image_puck = add(BoolConfigItem, "Puck Highlight", default=True)
        self.image_pins = add(BoolConfigItem, "Slots Highlight", default=True)
        self.image_crop = add(BoolConfigItem, "Crop to Puck", default=True)

        self.store_directory = add(DirectoryConfigItem,
                                   "Store Directory",
                                   default=default_store)
        self.store_capacity = add(IntConfigItem,
                                  "Results History Size",
                                  default=50)

        self.console_frame = add(BoolConfigItem,
                                 "Print Frame Summary",
                                 default=False)
        self.slot_images = add(BoolConfigItem,
                               "Save Debug Images",
                               default=False)
        self.slot_image_directory = add(DirectoryConfigItem,
                                        "Debug Directory",
                                        default="../debug-output/")

        self.top_camera_number = add(IntConfigItem,
                                     "Top Camera Number",
                                     default=1)
        self.top_camera_width = add(IntConfigItem,
                                    "Top Camera Width",
                                    default=1600)
        self.top_camera_height = add(IntConfigItem,
                                     "Top Camera Height",
                                     default=1200)

        self.side_camera_number = add(IntConfigItem,
                                      "Side Camera Number",
                                      default=2)
        self.side_camera_width = add(IntConfigItem,
                                     "Side Camera Width",
                                     default=1600)
        self.side_camera_height = add(IntConfigItem,
                                      "Side Camera Height",
                                      default=1200)

        self.initialize_from_file()
コード例 #22
0
 def test_to_hex_10_50_100_returns_0a3264(self):
     self.assertEquals(Color.to_hex(self.firstColor), '#0a3264')
コード例 #23
0
 def test_Black_is_000000(self):
     self.assertEqual(Color.Black().to_hex(), "#000000")
コード例 #24
0
 def test_Blue_is_0000ff(self):
     self.assertEqual(Color.Blue().to_hex(), "#0000ff")
コード例 #25
0
 def test_Grey_is_808080(self):
     self.assertEqual(Color.Grey().to_hex(), "#808080")
コード例 #26
0
 def test_from_string_returns_Color_with_given_rbg_and_alpha255_with_csv_three_valued_string(self):
     col = Color.from_string("25, 100, 243")
     self.assertEqual(col.bgra(), (243, 100, 25, 255))
コード例 #27
0
 def test_from_string_returns_Color_with_given_rbga_with_csv_four_valued_string(self):
     col = Color.from_string("251, 63, 1, 128")
     self.assertEqual(col.bgra(), (1, 63, 251, 128))
コード例 #28
0
 def setUp(self):
     self.firstColor = Color(10, 50, 100)
コード例 #29
0
 def test_from_string_returns_Color_with_given_rbga_with_custom_seperator_four_valued_string(self):
     col = Color.from_string("251;63;1;128", ";")
     self.assertEqual(col.bgra(), (1, 63, 251, 128))
コード例 #30
0
ファイル: camera_scanner.py プロジェクト: jpp08/dls_barcode
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()))
コード例 #31
0
    def test_from_qt_returns_QColour_of_rgba_as_zero255(self):

        qtcolor = Color.to_qt(self.firstColor)
        actual = Color.from_qt(qtcolor)

        self.assertEqual(Color.bgra(actual),  (100, 50, 10, 255))