def __init__(self, center, radius, image_array, start_angle=0, ccw=True, sampling_ratio=1.0): """ Parameters ---------- image_array : ndarray The 2D image array. start_angle : int, float Starting position of the profile in radians; 0 is right (0 on unit circle). ccw : bool If True (default), the profile will proceed counter-clockwise (the direction on the unit circle). If False, will proceed clockwise. sampling_ratio : float The ratio of pixel sampling to real pixels. E.g. if 1.0, the profile will have approximately the same number of elements as was encountered in the profile. A value of 2.0 will sample the profile at 2x the number of elements. See Also -------- `~pylinac.core.geometry.Circle` : Further parameter info. """ Circle.__init__(self, center, radius) self._ensure_array_size(image_array, self.radius + self.center.x, self.radius + self.center.y) self.image_array = image_array self.start_angle = start_angle self.ccw = ccw self.sampling_ratio = sampling_ratio self._x_locations = None self._y_locations = None MultiProfile.__init__(self, self._profile)
def __init__(self, name, slice_array, angle, radius=None, dist_from_center=None): """ Parameters ---------- angle : int, float The angle of the ROI in degrees from the phantom center. .. warning:: Be sure the enter the angle in degrees rather than radians! radius : int, float The radius of the ROI from the center of the phantom. dist_from_center : int, float The distance of the ROI from the phantom center. """ ROI.__init__(self, name, slice_array) Circle.__init__(self, radius=radius) self.angle = angle self.dist_from_center = dist_from_center
def _create_phantom_outline_object(self): """Construct the phantom outline object which will be plotted on the image for visual inspection.""" outline_type = list(self.phantom_outline_object)[0] outline_settings = list(self.phantom_outline_object.values())[0] settings = {} if outline_type == 'Rectangle': side_a = self.phantom_radius*outline_settings['width ratio'] side_b = self.phantom_radius*outline_settings['height ratio'] half_hyp = np.sqrt(side_a**2 + side_b**2)/2 internal_angle = ia = np.rad2deg(np.arctan(side_b/side_a)) new_x = self.phantom_center.x + half_hyp*(geometry.cos(ia)-geometry.cos(ia+self.phantom_angle)) new_y = self.phantom_center.y + half_hyp*(geometry.sin(ia)-geometry.sin(ia+self.phantom_angle)) obj = Rectangle(width=self.phantom_radius*outline_settings['width ratio'], height=self.phantom_radius*outline_settings['height ratio'], center=Point(new_x, new_y)) settings['angle'] = self.phantom_angle elif outline_type == 'Circle': obj = Circle(center_point=self.phantom_center, radius=self.phantom_radius*outline_settings['radius ratio']) else: raise ValueError("An outline object was passed but was not a Circle or Rectangle.") return obj, settings
def plot_analyzed_image(self, image=True, low_contrast=True, high_contrast=True, show=True): """Plot the analyzed image, which includes the original image with ROIs marked, low-contrast plots and high-contrast plots. Parameters ---------- image : bool Show the image. low_contrast : bool Show the low contrast values plot. high_contrast : bool Show the high contrast values plot. show : bool Whether to actually show the image when called. """ num_plots = sum((image, low_contrast, high_contrast)) if num_plots < 1: return fig, axes = plt.subplots(1, num_plots) fig.subplots_adjust(wspace=0.4) if num_plots < 2: axes = (axes, ) axes = iter(axes) if image: img_ax = next(axes) self.image.plot(ax=img_ax, show=False) img_ax.axis('off') img_ax.set_title('Leeds TOR Phantom Analysis') # plot the phantom location circle; helps users identify if the phantom location was identified correctly Circle(center_point=self.phantom_center, radius=self.phantom_radius).plot2axes(img_ax, edgecolor='blue') # plot the low contrast ROIs for roi in self.lc_rois: roi.plot2axes(img_ax, edgecolor=roi.plot_color_constant) for roi in self.lc_ref_rois: roi.plot2axes(img_ax, edgecolor='g') # plot the high-contrast ROIs for roi in self.hc_rois: roi.plot2axes(img_ax, edgecolor=roi.plot_color) for roi in self.hc_ref_rois: roi.plot2axes(img_ax, edgecolor='g') # plot the low contrast values if low_contrast: lowcon_ax = next(axes) self._plot_lowcontrast(lowcon_ax, self.lc_rois, self.low_contrast_threshold) # plot the high contrast MTF if high_contrast: hicon_ax = next(axes) hc_rois = [roi.mtf for roi in self.hc_rois] hc_rois.insert(0, 1) self._plot_highcontrast(hicon_ax, hc_rois, self.hi_contrast_threshold) if show: plt.show()
def __init__(self, center=None, radius=None): Circle.__init__(self, center, radius) Profile.__init__(self) self.x_locs = np.ndarray # x-values of the circle profile's location self.y_locs = np.ndarray # y-values of the circle profile's location
def distance(p, things): """Calculate the maximum distance to any line from the given point.""" other_thing = Point(p[0], p[1], p[2]) if axis == COUCH: other_thing = Circle(other_thing, radius=p[3]) return max(thing.distance_to(other_thing) for thing in things)