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()
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()
def _minimise_integer_grid(self, binary_image, center, side_length): """ Attempt to locate the square area (of the specified size, centered on the specified center point) in the binary image which has the minimum brightness. The datamatrix is a relatively dark area on a relative light background, so the area corresponding to the datamatrix should have the lowest brightness. """ done = False initial_transform = Transform(center.intify(), 0, 1) best_val = 1000000000000000 best_trs = initial_transform if self.DEBUG: img = binary_image.to_alpha() img = _draw_square(img, initial_transform, side_length) img.rescale(4).popup() count = 0 done_previous = False while not done: count += 1 transforms = self._make_minimisation_transforms(initial_transform, iteration=count) for trs in transforms: val = self._calculate_square_metric(binary_image, trs, side_length) if val < best_val: best_val = val best_trs = trs # if transform doesn't move for 2 iterations (one angle, one space), it # has reached a minimum if best_trs == initial_transform: if done_previous: done = True done_previous = True else: done_previous = False initial_transform = best_trs if self.DEBUG: img = binary_image.to_alpha() img = _draw_square(img, initial_transform, side_length) img.rescale(4).popup() return best_trs
def _determine_old_to_new_transformation(self, plate, valid_barcodes): # Get the positions of the two common barcodes in the current frame and the previous one barcode_a = valid_barcodes[0] barcode_b = valid_barcodes[1] pos_a_new = barcode_a.center() pos_b_new = barcode_b.center() pos_a_old = None pos_b_old = None for slot in plate._slots: if slot.barcode_data() == barcode_a.data(): pos_a_old = slot.barcode_position() elif slot.barcode_data() == barcode_b.data(): pos_b_old = slot.barcode_position() # Determine the transformation that maps the old points to the new line_transform = Transform.line_mapping(pos_a_old, pos_b_old, pos_a_new, pos_b_new) return line_transform