def _get_center(center: Optional[Tuple[int, int]]) -> Tuple[np.ndarray, Tuple[int, int]]: center_frame = self.m_center_in_port[0, ] if center_shape[0] > 1: warnings.warn('Multiple center images found. Using the first image of the stack.') if center is None: center = center_pixel(center_frame) else: center = (int(np.floor(center[0])), int(np.floor(center[1]))) return center_frame, center
def run(self) -> None: """ Run method of the module. Calculates the minimum, maximum, sum, mean, median, and standard deviation of the pixel values of each image separately. NaNs are ignored for each calculation. The values are calculated for either the full images or a circular subsection of the images. Returns ------- NoneType None """ pixscale = self.m_image_in_port.get_attribute('PIXSCALE') nimages = self.m_image_in_port.get_shape()[0] im_shape = self.m_image_in_port.get_shape()[1:] if self.m_position is None: indices = None else: if self.m_position[0] is None and self.m_position[1] is None: center = center_pixel(self.m_image_in_port[0, ]) self.m_position = ( center[0], # y position center[1], # x position self.m_position[2] / pixscale) # radius (pix) else: self.m_position = ( int(self.m_position[1]), # y position int(self.m_position[0]), # x position self.m_position[2] / pixscale) # radius (pix) rr_grid, _, _ = pixel_distance(im_shape, position=self.m_position[0:2]) rr_reshape = np.reshape(rr_grid, (rr_grid.shape[0] * rr_grid.shape[1])) indices = np.where(rr_reshape <= self.m_position[2])[0] self.apply_function_to_images(image_stat, self.m_image_in_port, self.m_stat_out_port, 'Calculating image statistics', func_args=(indices, )) history = f'number of images = {nimages}' self.m_stat_out_port.copy_attributes(self.m_image_in_port) self.m_stat_out_port.add_history('ImageStatisticsModule', history) self.m_stat_out_port.close_port()
def _get_center(center): center_frame = self.m_center_in_port[0, ] if center_shape[0] > 1: warnings.warn( 'Multiple center images found. Using the first image of the stack.' ) if center is None: center = center_pixel(center_frame) else: center = (np.floor(center[0]), np.floor(center[1])) return center_frame, center
def locate_star(image: np.ndarray, center: Union[tuple, None], width: Union[int, None], fwhm: Union[int, None]) -> np.ndarray: """ Function to locate the star by finding the brightest pixel. Parameters ---------- image : numpy.ndarray Input image (2D). center : tuple(int, int), None Pixel center (y, x) of the subframe. The full image is used if set to None. width : int, None The width (pix) of the subframe. The full image is used if set to None. fwhm : int, None Full width at half maximum (pix) of the Gaussian kernel. Not used if set to None. Returns ------- numpy.ndarray Position (y, x) of the brightest pixel. """ if width is not None: if center is None: center = center_pixel(image) image = crop_image(image, center, width) if fwhm is None: smooth = np.copy(image) else: sigma = fwhm / math.sqrt(8. * math.log(2.)) kernel = (fwhm * 2 + 1, fwhm * 2 + 1) smooth = cv2.GaussianBlur(image, kernel, sigma) # argmax[0] is the y position and argmax[1] is the y position argmax = np.asarray(np.unravel_index(smooth.argmax(), smooth.shape)) if center is not None and width is not None: argmax[0] += center[0] - (image.shape[0] - 1) // 2 # y argmax[1] += center[1] - (image.shape[1] - 1) // 2 # x return argmax
def _crop_around_star(image: np.ndarray, position: Optional[Union[Tuple[int, int, float], Tuple[None, None, float]]], im_size: int, fwhm: int) -> np.ndarray: if position is None: center = None width = None else: if position[0] is None and position[1] is None: center = None else: center = (position[1], position[0]) # (y, x) width = int(math.ceil(position[2]/pixscale)) starpos = locate_star(image, center, width, fwhm) try: im_crop = crop_image(image, tuple(starpos), im_size) except ValueError: if cpu == 1: warnings.warn(f'Chosen image size is too large to crop the image around the ' f'brightest pixel (image index = {self.m_count}, pixel [x, y] ' f'= [{starpos[0]}, {starpos[1]}]). Using the center of the ' f'image instead.') index.append(self.m_count) else: warnings.warn('Chosen image size is too large to crop the image around the ' 'brightest pixel. Using the center of the image instead.') starpos = center_pixel(image) im_crop = crop_image(image, tuple(starpos), im_size) if cpu == 1: star.append((starpos[1], starpos[0])) self.m_count += 1 return im_crop
def crop_around_star(image: np.ndarray, im_index: int, position: Optional[Union[Tuple[int, int, float], Tuple[None, None, float]]], im_size: int, fwhm: int, pixscale: float, index_out_port: Optional[OutputPort], image_out_port: OutputPort) -> np.ndarray: if position is None: center = None width = None else: if position[0] is None and position[1] is None: center = None else: center = (position[1], position[0]) # (y, x) width = int(math.ceil(position[2]/pixscale)) starpos = locate_star(image, center, width, fwhm) try: im_crop = crop_image(image, tuple(starpos), im_size) except ValueError: warnings.warn(f'Chosen image size is too large to crop the image around the ' f'brightest pixel (image index = {im_index}, pixel [x, y] ' f'= [{starpos[0]}, {starpos[1]}]). Using the center of the ' f'image instead.') if index_out_port is not None: index_out_port.append([im_index], data_dim=1) starpos = center_pixel(image) im_crop = crop_image(image, tuple(starpos), im_size) return im_crop
def run(self) -> None: """ Run method of the module. Calculates the minimum, maximum, sum, mean, median, and standard deviation of the pixel values of each image separately. NaNs are ignored for each calculation. The values are calculated for either the full images or a circular subsection of the images. Returns ------- NoneType None """ pixscale = self.m_image_in_port.get_attribute('PIXSCALE') nimages = self.m_image_in_port.get_shape()[0] im_shape = self.m_image_in_port.get_shape()[1:] if self.m_position is None: indices = None else: if self.m_position[0] is None and self.m_position[1] is None: center = center_pixel(self.m_image_in_port[0, ]) self.m_position = (center[0], # y position center[1], # x position self.m_position[2]/pixscale) # radius (pix) else: self.m_position = (int(self.m_position[1]), # y position int(self.m_position[0]), # x position self.m_position[2]/pixscale) # radius (pix) rr_grid = pixel_distance(im_shape, self.m_position[0:2]) rr_reshape = np.reshape(rr_grid, (rr_grid.shape[0]*rr_grid.shape[1])) indices = np.where(rr_reshape <= self.m_position[2])[0] @typechecked def _image_stat(image_in: np.ndarray, indices: Optional[np.ndarray]) -> np.ndarray: if indices is None: image_select = np.copy(image_in) else: image_reshape = np.reshape(image_in, (image_in.shape[0]*image_in.shape[1])) image_select = image_reshape[indices] nmin = np.nanmin(image_select) nmax = np.nanmax(image_select) nsum = np.nansum(image_select) mean = np.nanmean(image_select) median = np.nanmedian(image_select) std = np.nanstd(image_select) return np.asarray([nmin, nmax, nsum, mean, median, std]) self.apply_function_to_images(_image_stat, self.m_image_in_port, self.m_stat_out_port, 'Calculating image statistics', func_args=(indices, )) history = f'number of images = {nimages}' self.m_stat_out_port.copy_attributes(self.m_image_in_port) self.m_stat_out_port.add_history('ImageStatisticsModule', history) self.m_stat_out_port.close_port()