def get_view_box(self): """Calculate shown portion of image and image units per pixel This method utilizes a precomputed "mesh" of relatively evenly spaced points over the entire image space. This mesh is transformed to the canvas space (-1 to 1 user-viewed space) to figure out which portions of the image are currently being viewed and which portions can actually be projected on the viewed projection. While the result of the chosen method may not always be completely accurate, it should work for all possible viewing cases. """ if self._viewable_mesh_mask is None or self.canvas.size[ 0] == 0 or self.canvas.size[1] == 0: raise ValueError("Image '%s' is not viewable in this projection" % (self.name, )) # Image points transformed to canvas coordinates img_cmesh = self.transforms.get_transform().map(self.calc.image_mesh) # The image mesh projected to canvas coordinates (valid only) img_cmesh = img_cmesh[self._viewable_mesh_mask] # The image mesh of only valid "viewable" projected coordinates img_vbox = self.calc.image_mesh[self._viewable_mesh_mask] ref_idx_1, ref_idx_2 = get_reference_points(img_cmesh, img_vbox) dx, dy = calc_pixel_size(img_cmesh[(self._ref1, self._ref2), :], img_vbox[(self._ref1, self._ref2), :], self.canvas.size) view_extents = self.calc.calc_view_extents(img_cmesh[ref_idx_1], img_vbox[ref_idx_1], self.canvas.size, dx, dy) return ViewBox(*view_extents, dx=dx, dy=dy)
def determine_reference_points(self): # Image points transformed to canvas coordinates img_cmesh = self.transforms.get_transform().map(self.calc.image_mesh) # Mask any points that are really far off screen (can't be transformed) valid_mask = (np.abs(img_cmesh[:, 0]) < CANVAS_EPSILON) & (np.abs( img_cmesh[:, 1]) < CANVAS_EPSILON) # The image mesh projected to canvas coordinates (valid only) img_cmesh = img_cmesh[valid_mask] # The image mesh of only valid "viewable" projected coordinates img_vbox = self.calc.image_mesh[valid_mask] if not img_cmesh[:, 0].size or not img_cmesh[:, 1].size: self._viewable_mesh_mask = None self._ref1, self._ref2 = None, None return x_cmin, x_cmax = img_cmesh[:, 0].min(), img_cmesh[:, 0].max() y_cmin, y_cmax = img_cmesh[:, 1].min(), img_cmesh[:, 1].max() center_x = (x_cmax - x_cmin) / 2. + x_cmin center_y = (y_cmax - y_cmin) / 2. + y_cmin dist = img_cmesh.copy() dist[:, 0] = center_x - img_cmesh[:, 0] dist[:, 1] = center_y - img_cmesh[:, 1] self._viewable_mesh_mask = valid_mask self._ref1, self._ref2 = get_reference_points(dist, img_vbox)
def test_get_reference_points_bad_points(ic, iv): """Test that error is thrown if given invalid mesh points.""" with pytest.raises(ValueError): get_reference_points(np.array(ic), np.array(iv))
def test_get_reference_points(ic, iv, exp): """Test returned image reference point indexes are correct.""" res = get_reference_points(np.array(ic), np.array(iv)) assert res == exp