def test_get_patch(self): uut = InteractiveSquare() expected = uut._patch actual = uut.get_patch() self.assertEqual(expected, actual)
def test_get_transform_matrix_no_data(self): uut = InteractiveSquare() expected = [] actual = uut._get_transform_matrix() self.assertEqual(expected, actual.tolist())
def test_register_transform_coalesce_with_nothing(self): uut = InteractiveSquare() matrix = np.array([[1, 0.25], [0.5, 1]]) with self.assertRaises(ValueError): uut.register_transform(matrix, coalescer=np.dot)
def test_get_transform_matrix_component_no_data(self): uut = InteractiveSquare() uut._matrices[0] = (None, {}) expected = [] actual = uut._get_transform_matrix_component(0) self.assertEqual(expected, actual.tolist())
def test_get_transform_matrix_one_order_only_indices(self): uut = InteractiveSquare() uut._matrices[1] = (None, {(0, 1): 0.25}, None) expected = [[1, 0.25], [0, 1]] actual = uut._get_transform_matrix() self.assertEqual(expected, actual.tolist())
def test_get_transform_matrix_component_with_only_matrix(self): expected = np.array([[1, 0.25], [0.5, 1]]) uut = InteractiveSquare() uut._matrices[0] = [expected, {}, None] actual = uut._get_transform_matrix_component(0) self.assertEqual(expected.tolist(), actual.tolist())
def test_get_transform_matrix_two_order_only_indices(self): uut = InteractiveSquare() uut._matrices[1] = (None, {(0, 1): 0.25}, np.dot) uut._matrices[2] = (None, {(1, 0): 0.5}, np.dot) expected = [[1, 0.25], [0.5, 1.125]] actual = uut._get_transform_matrix() self.assertEqual(expected, actual.tolist())
def test_get_transform_matrix_one_order_only_matrix(self): uut = InteractiveSquare() expected = np.array([[1, 0.25], [0.5, 1]]) uut.register_transform(expected) actual = uut._get_transform_matrix() self.assertEqual(expected.tolist(), actual.tolist())
def test_get_matrix_updater_mutator(self): uut = InteractiveSquare() func = uut._get_matrix_updater(0, (0, 1), lambda v: v + 1) func(1) expected = [[1, 2], [0, 1]] actual = uut._get_transform_matrix_component(0) self.assertEqual(expected, actual.tolist())
def test_get_transform_matrix_component_vertical_rectangular_matrix(self): matrix = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 2, 3]]) uut = InteractiveSquare() uut._matrices[0] = [matrix, {}, None] expected = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 2, 3, 1]] actual = uut._get_transform_matrix_component(0) self.assertEqual(expected, actual.tolist())
def test_get_matrix_updater(self): uut = InteractiveSquare() func = uut._get_matrix_updater(0, (0, 1)) func(0.25) expected = [[1, 0.25], [0, 1]] actual = uut._get_transform_matrix_component(0) self.assertEqual(expected, actual.tolist())
def test_register_transform(self): uut = InteractiveSquare() matrix = np.array([[1, 0.25], [0.5, 1]]) uut.register_transform(matrix) expected = {0: [matrix, {}, None]} actual = uut._matrices self.assertEqual(expected, actual)
def test_get_transform_matrix_component_both_matrix_and_indices(self): matrix = np.array([[1, 0.25], [0, 1]]) uut = InteractiveSquare() uut._matrices[0] = [matrix, {}, None] uut._matrices[0][1][(1, 0)] = 0.5 expected = np.array([[1, 0.25], [0.5, 1]]) actual = uut._get_transform_matrix_component(0) self.assertEqual(expected.tolist(), actual.tolist())
def test_get_transform_matrix_two_order_both_matrix_and_indices(self): matrix_1 = np.array([[1, 0.25], [0, 1]]) matrix_2 = np.array([[1, 0.75], [0, 1]]) uut = InteractiveSquare() uut._matrices[1] = (matrix_1, {(1, 0): 0.5}, np.dot) uut._matrices[2] = (matrix_2, {(1, 0): 1.25}, np.dot) expected = [[1.375, 1], [1.75, 1.3125]] actual = uut._get_transform_matrix() self.assertEqual(expected, actual.tolist())
def test_get_transform_matrix_two_order_only_matrix(self): matrix_1 = np.array([[1, 0.25], [0, 1]]) matrix_2 = np.array([[1, 0], [0.5, 1]]) uut = InteractiveSquare() uut._matrices[1] = (matrix_1, {}, np.dot) uut._matrices[2] = (matrix_2, {}, np.dot) expected = [[1, 0.25], [0.5, 1.125]] actual = uut._get_transform_matrix() self.assertEqual(expected, actual.tolist())
def test_register_transform_with_coalescer(self): uut = InteractiveSquare() matrix_1 = np.array([[1, 0.25], [0.5, 1]]) matrix_2 = np.array([[1, 0], [0, 1]]) uut.register_transform(matrix_1) uut.register_transform(matrix_2) expected = {0: [matrix_1, {}, None], 1: [matrix_2, {}, np.dot]} actual = uut._matrices self.assertEqual(expected, actual)
def test_instance_origin_scale(self): uut = InteractiveSquare(origin=(1, 1), scale=1) expected = [[0.5, 0.5], [0.5, 1.5], [1.5, 0.5], [1.5, 1.5]] actual = uut._square self.assertCountEqual(expected, actual.tolist())
def test_get_transform_matrix_component_with_only_indices(self): uut = InteractiveSquare() uut._matrices[0] = [None, {}] uut._matrices[0][1][(0, 1)] = 0.25 uut._matrices[0][1][(1, 0)] = 0.5 expected = np.array([[1, 0.25], [0.5, 1]]) actual = uut._get_transform_matrix_component(0) self.assertEqual(expected.tolist(), actual.tolist())
def test_get_transform_matrix_three_order_sorted(self): matrix_1 = np.array([[0.25, 0.5], [0.75, 1]]) matrix_2 = np.array([[1.25, 1.5], [1.75, 2]]) matrix_3 = np.array([[2.25, 2.5], [2.75, 3]]) uut = InteractiveSquare() uut._matrices[1] = (matrix_1, {}, np.dot) uut._matrices[7] = (matrix_3, {}, np.dot) uut._matrices[3] = (matrix_2, {}, np.dot) expected = [[8.078125, 11.96875], [9.765625, 14.46875]] actual = uut._get_transform_matrix() self.assertEqual(expected, actual.tolist())
def experiment(): # TODO: When is M^-1 =/= M^T? # TODO: Calculate distance from the camera at every pixel, and tint pixel to be lighter the farther it is from the camera. viewport_ratio = 4 # 3/4 rows for viewport, 1/4 rows for sliders num_sliders = 6 figure: pyplot.Figure = pyplot.figure() grid: pyplot.GridSpec = gridspec.GridSpec(viewport_ratio, 1, figure=figure) axes: pyplot.Axes = pyplot.subplot(grid[:viewport_ratio - 1, :]) sliders = gridspec.GridSpecFromSubplotSpec(num_sliders, 2, grid[-1, :], wspace=0.4) # Configure style axes.axis("equal") axes.grid(alpha=0.15, linestyle="--") axes.margins(2, 2) axes.xaxis.set_major_locator(ticker.MultipleLocator(0.5)) axes.yaxis.set_major_locator(ticker.MultipleLocator(0.5)) axes.xaxis.set_minor_locator(ticker.AutoMinorLocator(4)) axes.yaxis.set_minor_locator(ticker.AutoMinorLocator(4)) # Set up gray (baseline) patch origin = (0, 0) InteractiveSquare(axes, origin, style=style.gray) # Set up green (interactive) patch K = np.array( [ # Intrinsic parameter matrix [1, 0, 0, 0], # [αₓ γ μ₀ 0] [0, 1, 0, 0], # [0 αᵧ ν₀ 0] [0, 0, 1, 0] # [0 0 1 0] ], dtype=float) Rx = np.identity(3, dtype=float) # Extrinsic parameter matrix Ry = np.identity(3, dtype=float) # [R,3x3 T,3x1] Rz = np.identity(3, dtype=float) # [0,1x3 1] T = np.array([[0, 0, 0]], dtype=float) B = np.array([[0, 0, 0, 1]], dtype=float) green = InteractiveSquare(axes, (0, 0), 1, (0, 1), style=style.green, convert_2d=utility.from_homogenous, label_vertices=True) green.register_transform(K, label="K") # Rx, Ry, Rz, T, B must be resolved before K can dot it. RT = Sequence() RT.register_node(MutableMatrix("Rz", Rz), None) RT.register_node(MutableMatrix("Ry", Ry), np.dot) RT.register_node(MutableMatrix("Rx", Rx), np.dot) RT.register_node(MutableMatrix("T", T), lambda a, b: np.concatenate( (a, b.T), axis=1)) RT.register_node(MutableMatrix("B", B), lambda a, b: np.concatenate( (a, b), axis=0)) green.register_transform(RT) # TODO: Do not register sliders to x, y, z angles. Register them to yaw (α), pitch (β), and roll (γ). # Would need to register matrices/sliders with functions to calculate world rotations so that # yaw, pitch, roll are valid--need to convert from intrinsic to extrinsic angles. # Yaw (α) slider_1 = widgets.Slider(pyplot.subplot(sliders[0, 0]), "Rotate: α", 0, 360, 0, **style.darkgreen) green.register_slider((1, 0), (0, 0), slider_1, lambda v: math.cos(math.radians(v))) green.register_slider((1, 0), (0, 1), slider_1, lambda v: (-1 * math.sin(math.radians(v)))) green.register_slider((1, 0), (1, 0), slider_1, lambda v: math.sin(math.radians(v))) green.register_slider((1, 0), (1, 1), slider_1, lambda v: math.cos(math.radians(v))) # Pitch (β) slider_2 = widgets.Slider(pyplot.subplot(sliders[1, 0]), "Rotate: β", 0, 360, 0, **style.darkgreen) green.register_slider((1, 1), (0, 0), slider_2, lambda v: math.cos(math.radians(v))) green.register_slider((1, 1), (0, 2), slider_2, lambda v: math.sin(math.radians(v))) green.register_slider((1, 1), (2, 0), slider_2, lambda v: (-1 * math.sin(math.radians(v)))) green.register_slider((1, 1), (2, 2), slider_2, lambda v: math.cos(math.radians(v))) # Roll (γ) slider_3 = widgets.Slider(pyplot.subplot(sliders[2, 0]), "Rotate: γ", 0, 360, 0, **style.darkgreen) green.register_slider((1, 2), (1, 1), slider_3, lambda v: math.cos(math.radians(v))) green.register_slider((1, 2), (1, 2), slider_3, lambda v: (-1 * math.sin(math.radians(v)))) green.register_slider((1, 2), (2, 1), slider_3, lambda v: math.sin(math.radians(v))) green.register_slider((1, 2), (2, 2), slider_3, lambda v: math.cos(math.radians(v))) # Focal length slider_4 = widgets.Slider(pyplot.subplot(sliders[3, 0]), "Focal:", 0, 2, 0, **style.darkgreen) green.register_slider(0, (1, 0), slider_4) green.register_slider(0, (0, 1), slider_4) # Princible point x component slider_5 = widgets.Slider(pyplot.subplot(sliders[4, 0]), "PPx:", -5, 5, 0, **style.darkgreen) green.register_slider(0, (0, 2), slider_5) # Principle point y component slider_6 = widgets.Slider(pyplot.subplot(sliders[5, 0]), "PPy:", -5, 5, 0, **style.darkgreen) green.register_slider(0, (1, 2), slider_6) # World origin x component slider_7 = widgets.Slider(pyplot.subplot(sliders[0, 1]), "Tx", -5, 5, 0, **style.darkgreen) green.register_slider((1, 3), (0, 0), slider_7) # World origin y component slider_8 = widgets.Slider(pyplot.subplot(sliders[1, 1]), "Ty", -5, 5, 0, **style.darkgreen) green.register_slider((1, 3), (0, 1), slider_8) # World origin z component slider_9 = widgets.Slider(pyplot.subplot(sliders[2, 1]), "Tz", -5, 5, 1, **style.darkgreen) green.register_slider((1, 3), (0, 2), slider_9) logging.info(green.get_label()) axes.relim() axes.autoscale_view() pyplot.tight_layout() pyplot.show()
def test_instance(self): uut = InteractiveSquare() self.assertIsNotNone(uut)