def mask_obj(image, apertures, if_plot=True): """ Automaticlly generate a list of masked based on the input apertures. """ from regions import PixCoord, EllipsePixelRegion from astropy.coordinates import Angle masks = [] # In the script, the objects are 1, emptys are 0. for i in range(len(apertures)): aperture = apertures[i] if isinstance(apertures[0].positions[0], np.ndarray): x, y = aperture.positions[0] elif isinstance(apertures[0].positions[0], float): x, y = aperture.positions center = PixCoord(x=x, y=y) theta = Angle(aperture.theta / np.pi * 180., 'deg') reg = EllipsePixelRegion(center=center, width=aperture.a * 2, height=aperture.b * 2, angle=theta) patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2) mask_set = reg.to_mask(mode='center') mask = mask_set.to_image((len(image), len(image))) mask = 1 - mask if if_plot: print("plot mask for object {0}:".format(i)) fig, axi = plt.subplots(1, 1, figsize=None) axi.add_patch(patch) axi.imshow(mask, origin='lower') plt.show() masks.append(mask) return masks
def ellipse_mask(a, b, x0, y0, theta, image): """Returns elliptical mask of radii (a,b) with rotation theta (in degrees) and offset (xo,yo) from the geometric center of 'I' (X0,Y0), which must be passed via **kws and must have an odd number of pixels in each dimension. The mask has the same shape as 'I' and is assigned 1 (0) for pixels outside (inside) the ellipse, and assigned fractional areas for pixels intercepted by the ellipse. To install astropy and regions, run the following commands from terminal: conda install astropy pip install regions """ from regions import EllipsePixelRegion, PixCoord from astropy.units import deg from numpy import array I = image height, width = I.shape # Calculate ellipse center (h,k) h = x0 k = y0 ellipse = EllipsePixelRegion(PixCoord(h, k), 2 * a, 2 * b, -theta * deg) mask = ellipse.to_mask(mode='exact') mask = mask.to_image(I.shape) return array(mask, dtype='bool')
def fitEllipse(cc,axesLength,angle): x0, y0 = cc[0],cc[1] a, b = axesLength[0],axesLength[1] theta = Angle(angle, 'deg') e = Ellipse2D(amplitude=100., x_0=x0, y_0=y0, a=a, b=b, theta=theta.radian) y, x = np.mgrid[0:1000, 0:1000] center = PixCoord(x=x0, y=y0) reg = EllipsePixelRegion(center=center, width=2*a, height=2*b, angle=theta) patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2) return reg
def fp_show(img, a, b, center_row, center_col, angle): ''' show the ellipse scope in the image img: 2-d numpy.array; a,b: the length corresponding to the semimajor axis and semiminor axis respectively. center_row, center_col: the center location of the image ''' if len(img.shape) == 3: img_row, img_col, _ = img.shape else: img_row, img_col = img.shape angle = 180 - angle # from botton-left (origin) coordinate to up-left(image col-row) coordinate theta = Angle(angle, 'deg') imgShow(img) center = PixCoord(x=center_col, y=center_row) reg = EllipsePixelRegion(center=center, width=2 * a, height=2 * b, angle=theta) patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2) ax = plt.gca() ax.add_patch(patch) plt.plot(center_col, center_row, 'ro')
def mask_obj(img, snr=3.0, exp_sz= 1.2, plt_show = True): threshold = detect_threshold(img, snr=snr) center_img = len(img)/2 sigma = 3.0 * gaussian_fwhm_to_sigma# FWHM = 3. kernel = Gaussian2DKernel(sigma, x_size=5, y_size=5) kernel.normalize() segm = detect_sources(img, threshold, npixels=10, filter_kernel=kernel) npixels = 20 segm_deblend = deblend_sources(img, segm, npixels=npixels, filter_kernel=kernel, nlevels=15, contrast=0.001) #Number of objects segm_deblend.data.max() fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12.5, 10)) import copy, matplotlib my_cmap = copy.copy(matplotlib.cm.get_cmap('gist_heat')) # copy the default cmap my_cmap.set_bad('black') vmin = 1.e-3 vmax = 2.1 ax1.imshow(img, origin='lower', cmap=my_cmap, norm=LogNorm(), vmin=vmin, vmax=vmax) ax1.set_title('Data') ax2.imshow(segm_deblend, origin='lower', cmap=segm_deblend.cmap(random_state=12345)) ax2.set_title('Segmentation Image') plt.close() columns = ['id', 'xcentroid', 'ycentroid', 'source_sum', 'area'] cat = source_properties(img, segm_deblend) tbl = cat.to_table(columns=columns) tbl['xcentroid'].info.format = '.2f' # optional format tbl['ycentroid'].info.format = '.2f' print(tbl) from photutils import EllipticalAperture cat = source_properties(img, segm_deblend) segm_deblend_size = segm_deblend.areas apertures = [] for obj in cat: size = segm_deblend_size[obj.id] print 'obj.id', obj.id position = (obj.xcentroid.value, obj.ycentroid.value) a_o = obj.semimajor_axis_sigma.value b_o = obj.semiminor_axis_sigma.value size_o = np.pi * a_o * b_o r = np.sqrt(size/size_o)*exp_sz a, b = a_o*r, b_o*r theta = obj.orientation.value apertures.append(EllipticalAperture(position, a, b, theta=theta)) dis_sq = [np.sqrt((apertures[i].positions[0][0]-center_img)**2+(apertures[i].positions[0][1]-center_img)**2) for i in range(len(apertures))] dis_sq = np.asarray(dis_sq) c_index= np.where(dis_sq == dis_sq.min())[0][0] #from astropy.visualization.mpl_normalize import ImageNormalize #norm = ImageNormalize(stretch=SqrtStretch()) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12.5, 10)) ax1.imshow(img, origin='lower', cmap=my_cmap, norm=LogNorm(), vmin=vmin, vmax=vmax) ax1.set_title('Data') ax2.imshow(segm_deblend, origin='lower', cmap=segm_deblend.cmap(random_state=12345)) ax2.set_title('Segmentation Image') for i in range(len(apertures)): aperture = apertures[i] aperture.plot(color='white', lw=1.5, ax=ax1) aperture.plot(color='white', lw=1.5, ax=ax2) if plt_show == True: plt.show() else: plt.close() from regions import PixCoord, EllipsePixelRegion from astropy.coordinates import Angle obj_masks = [] # In the script, the objects are 1, emptys are 0. for i in range(len(apertures)): aperture = apertures[i] x, y = aperture.positions[0] center = PixCoord(x=x, y=y) theta = Angle(aperture.theta/np.pi*180.,'deg') reg = EllipsePixelRegion(center=center, width=aperture.a*2, height=aperture.b*2, angle=theta) patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2) fig, axi = plt.subplots(1, 1, figsize=(10, 12.5)) axi.add_patch(patch) mask_set = reg.to_mask(mode='center') mask = mask_set.to_image((len(img),len(img))) axi.imshow(mask, origin='lower') plt.close() obj_masks.append(mask) return obj_masks
def to_object(self, subset): """ Convert a glue Subset object to a astropy regions Region object. Parameters ---------- subset : `glue.core.subset.Subset` The subset to convert to a Region object """ data = subset.data if data.pixel_component_ids[0].axis == 0: x_pix_att = data.pixel_component_ids[1] y_pix_att = data.pixel_component_ids[0] else: x_pix_att = data.pixel_component_ids[0] y_pix_att = data.pixel_component_ids[1] subset_state = subset.subset_state if isinstance(subset_state, RoiSubsetState): roi = subset_state.roi if isinstance(roi, RectangularROI): xcen = 0.5 * (roi.xmin + roi.xmax) ycen = 0.5 * (roi.ymin + roi.ymax) width = roi.xmax - roi.xmin height = roi.ymax - roi.ymin return RectanglePixelRegion(PixCoord(xcen, ycen), width, height) elif isinstance(roi, PolygonalROI): return PolygonPixelRegion(PixCoord(roi.vx, roi.vy)) elif isinstance(roi, CircularROI): return CirclePixelRegion(PixCoord(*roi.get_center()), roi.get_radius()) elif isinstance(roi, EllipticalROI): return EllipsePixelRegion(PixCoord(roi.xc, roi.yc), roi.radius_x, roi.radius_y) elif isinstance(roi, PointROI): return PointPixelRegion(PixCoord(*roi.center())) elif isinstance(roi, RangeROI): return range_to_rect(data, roi.ori, roi.min, roi.max) elif isinstance(roi, AbstractMplRoi): temp_sub = Subset(data) temp_sub.subset_state = RoiSubsetState(x_pix_att, y_pix_att, roi.roi()) try: return self.to_object(temp_sub) except NotImplementedError: raise NotImplementedError( "ROIs of type {0} are not yet supported".format( roi.__class__.__name__)) else: raise NotImplementedError( "ROIs of type {0} are not yet supported".format( roi.__class__.__name__)) elif isinstance(subset_state, RangeSubsetState): if subset_state.att == x_pix_att: return range_to_rect(data, 'x', subset_state.lo, subset_state.hi) elif subset_state.att == y_pix_att: return range_to_rect(data, 'y', subset_state.lo, subset_state.hi) else: raise ValueError( 'Range subset state att should be either x or y pixel coordinate' ) elif isinstance(subset_state, MultiRangeSubsetState): if subset_state.att == x_pix_att: ori = 'x' elif subset_state.att == y_pix_att: ori = 'y' else: message = 'Multirange subset state att should be either x or y pixel coordinate' raise ValueError(message) if len(subset_state.pairs) == 0: message = 'Multirange subset state should contain at least one range' raise ValueError(message) region = range_to_rect(data, ori, subset_state.pairs[0][0], subset_state.pairs[0][1]) for pair in subset_state.pairs[1:]: region = region | range_to_rect(data, ori, pair[0], pair[1]) return region elif isinstance(subset_state, PixelSubsetState): return PointPixelRegion(PixCoord(*subset_state.get_xy(data, 1, 0))) elif isinstance(subset_state, AndState): temp_sub1 = Subset(data=data) temp_sub1.subset_state = subset_state.state1 temp_sub2 = Subset(data=data) temp_sub2.subset_state = subset_state.state2 return self.to_object(temp_sub1) & self.to_object(temp_sub2) elif isinstance(subset_state, OrState): temp_sub1 = Subset(data=data) temp_sub1.subset_state = subset_state.state1 temp_sub2 = Subset(data=data) temp_sub2.subset_state = subset_state.state2 return self.to_object(temp_sub1) | self.to_object(temp_sub2) elif isinstance(subset_state, XorState): temp_sub1 = Subset(data=data) temp_sub1.subset_state = subset_state.state1 temp_sub2 = Subset(data=data) temp_sub2.subset_state = subset_state.state2 return self.to_object(temp_sub1) ^ self.to_object(temp_sub2) elif isinstance(subset_state, MultiOrState): temp_sub = Subset(data=data) temp_sub.subset_state = subset_state.states[0] region = self.to_object(temp_sub) for state in subset_state.states[1:]: temp_sub.subset_state = state region = region | self.to_object(temp_sub) return region else: raise NotImplementedError( "Subset states of type {0} are not supported".format( subset_state.__class__.__name__))