def test_ellipse_trivial(): img = np.zeros((2, 2), "uint8") rr, cc = ellipse(0.5, 0.5, 0.5, 0.5) img[rr, cc] = 1 img_correct = np.array([[0, 0], [0, 0]]) assert_array_equal(img, img_correct) img = np.zeros((2, 2), "uint8") rr, cc = ellipse(0.5, 0.5, 1.1, 1.1) img[rr, cc] = 1 img_correct = np.array([[1, 1], [1, 1]]) assert_array_equal(img, img_correct) img = np.zeros((3, 3), "uint8") rr, cc = ellipse(1, 1, 0.9, 0.9) img[rr, cc] = 1 img_correct = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]) assert_array_equal(img, img_correct) img = np.zeros((3, 3), "uint8") rr, cc = ellipse(1, 1, 1.1, 1.1) img[rr, cc] = 1 img_correct = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) assert_array_equal(img, img_correct) img = np.zeros((3, 3), "uint8") rr, cc = ellipse(1, 1, 1.5, 1.5) img[rr, cc] = 1 img_correct = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) assert_array_equal(img, img_correct)
def test_ellipse_rotation_symmetry(): img1 = np.zeros((150, 150), dtype=np.uint8) img2 = np.zeros((150, 150), dtype=np.uint8) for angle in range(0, 180, 15): img1.fill(0) rr, cc = ellipse(80, 70, 60, 40, rotation=np.deg2rad(angle)) img1[rr, cc] = 1 img2.fill(0) rr, cc = ellipse(80, 70, 60, 40, rotation=np.deg2rad(angle + 180)) img2[rr, cc] = 1 assert_array_equal(img1, img2)
def add_Ellipse(self, scale = 1, thick = 5): """h for vertical, w for horizontal""" h = self.e_h = self.base_e_h * scale w = self.e_w = self.base_e_w * scale # e and lv should not be too close shift = self.e_w/8 center = self.lv_center + self.lv_radius_vec center[1] += shift self.e_center = center self.e_thick = thick self.e_big = d.ellipse(center[0], center[1], h, w) self.e_small= d.ellipse(center[0], center[1], h-thick, w-thick)
def makeFakeVessels(imgsize=(512, 512), background=230): """ create and save a matrix with whitish background and randomly selected vessel sizes and save matrices generated as images of format png """ nVes = 20 mu = 20 sigma = 5 minw = 5 sx, sy = imgsize vasc = np.ones((sx, sy), dtype=np.uint8) * background for i in range(nVes): cx, cy = random.uniform(0, sx), random.uniform(0, sy) r1, r2 = 0, 0 while (r1 < minw) or (r2 < minw): np.random.seed(20) r1 = np.random.normal(mu, sigma) r2 = np.random.normal(mu, sigma) print(r1, r2) rr, cc = ellipse(cy, cx, r1, r2) if np.any(rr >= sy): ix = rr < sy rr, cc = rr[ix], cc[ix] if np.any(cc >= sx): ix = cc < sx rr, cc = rr[ix], cc[ix] vasc[rr, cc] = 1 # make circle blackish return vasc
def test_ellipse(): img = np.zeros((15, 15), 'uint8') rr, cc = ellipse(7, 7, 3, 7) img[rr, cc] = 1 img_ = np.array( [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] ) assert_array_equal(img, img_)
def test_ellipse_with_shape(): img = np.zeros((15, 15), 'uint8') rr, cc = ellipse(7, 7, 3, 10, shape=img.shape) img[rr, cc] = 1 img_ = np.array( [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] ) assert_array_equal(img, img_)
def test_ellipse_negative(): rr, cc = ellipse(-3, -3, 1.7, 1.7) rr_, cc_ = np.nonzero( np.array([[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]]) ) assert_array_equal(rr, rr_ - 5) assert_array_equal(cc, cc_ - 5)
def setup(): image = np.zeros((30, 30, 3), dtype=float) image[draw.ellipse(15, 15, 5, 8)] = 1 state = np.zeros((30, 30, 2)) state[15, 15] = (1, 1) state[0, 0] = (0, 1) return image, state
def get_indices(self): """Returns a set of points that lie inside the picked polygon.""" if not self.center: raise ValueError("Cannot get ellipse indices before the dimensions are defined") x, y = self.center w = self.width h = self.height return ellipse(y, x, h/2., w/2., self.im)
def test_ellipse_rotated(): img = np.zeros((1000, 1200), dtype=np.uint8) for rot in range(0, 180, 10): img.fill(0) angle = np.deg2rad(rot) rr, cc = ellipse(500, 600, 200, 400, rotation=angle) img[rr, cc] = 1 # estimate orientation of ellipse angle_estim = np.round(regionprops(img)[0].orientation, 3) % (np.pi / 2) assert_almost_equal(angle_estim, angle % (np.pi / 2), 2)
def test_rotate_largest_region(self): test_img = np.zeros((1000,1000), dtype=np.uint8) rr, cc = circle(100,100,50) test_img[rr,cc] = 1 rr, cc = ellipse(500,500,300,100) test_img[rr, cc] = 1 rotated = gzapi.rotate_largest_region(test_img) largest_region = gzapi.get_largest_region(rotated) self.assertAlmostEqual(largest_region.orientation, 0) self.assertIsNone(gzapi.rotate_largest_region(None))
def sim_wire(angle, gaussian_sigma=1, noise_level=0, L=100): "Draw a wire with blur and optional noise." # Noise level should be from 0 to 1. 0.02 is reasonable. shape = (L, L) a = np.zeros(shape, dtype=np.uint8) a[draw.ellipse(L//2, L//2, L//24, L//4)] = 100 # horizontal ellipse a = filter.gaussian_filter(a, gaussian_sigma) b = transform.rotate(a, angle) b += noise_level*np.random.randn(*shape) return b
def _measure_fluorescence(self, time_period, time_index, image_slice, channel_annotation): mask = np.zeros((image_slice.height * 2, image_slice.width)) old_pole, new_pole = channel_annotation.get_cell_bounds(time_period, time_index) ellipse_minor_radius = int(0.80 * image_slice.height) ellipse_major_radius = int((new_pole - old_pole) / 2.0) * 0.8 centroid_y = int(image_slice.height) centroid_x = int((new_pole + old_pole) / 2.0) rr, cc = draw.ellipse(centroid_y, centroid_x, ellipse_minor_radius, ellipse_major_radius) mask[rr, cc] = 1 mean, stddev, median, area, centroid = self._calculate_cell_intensity_statistics(mask.astype("int"), image_slice.image_data) return mean, stddev, median, area, centroid
def test_growcut_basic(): image = np.zeros((30, 30, 3), dtype=float) image[draw.ellipse(15, 15, 5, 8)] = 1 state = np.zeros((30, 30, 2)) state[15, 15] = (1, 1) state[0, 0] = (0, 1) npt.assert_array_equal(image[..., 0], growcut(image, state, window_size=3, max_iter=20)) npt.assert_array_equal(image[..., 0], growcut_fast(image, state, window_size=3, max_iter=20))
def ellipse(width, height, dtype=np.uint8): """Generates a flat, ellipse-shaped structuring element. Every pixel along the perimeter of ellipse satisfies the equation ``(x/width+1)**2 + (y/height+1)**2 = 1``. Parameters ---------- width : int The width of the ellipse-shaped structuring element. height : int The height of the ellipse-shaped structuring element. Other Parameters ---------------- dtype : data-type The data type of the structuring element. Returns ------- selem : ndarray The structuring element where elements of the neighborhood are 1 and 0 otherwise. Examples -------- >>> from skimage.morphology import selem >>> selem.ellipse(5, 3) array([[0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]], dtype=uint8) """ selem = np.zeros((2 * height + 1, 2 * width + 1), dtype=dtype) rows, cols = draw.ellipse(height, width, height + 1, width + 1) selem[rows, cols] = 1 return selem
def ellipseMask(maskImg, ellipse_yradius, ellipse_xradius): boxsize = maskImg.get_xsize() maskArray = EMNumPy.em2numpy(maskImg) if (boxsize <= ellipse_yradius * 2 or boxsize <= ellipse_xradius * 2): print "ERROR: ellipse_xradius or ellipse_yradius is larger than the boxsize of particles." sys.exit() #from skimage.draw import ellipse #Generate coordinates of pixels within ellipse. #################################### ''' ellipse_xradius=random.randint(ellipse_xradius-10,ellipse_xradius+10) print ellipse_xradius ellipse_yradius=random.randint(ellipse_yradius-10,ellipse_yradius+10) print ellipse_yradius ''' size = max([ellipse_xradius, ellipse_yradius]) * 2 + 4 cx = size/2 cy = size/2 ellipseArray = np.zeros((size, size), dtype=np.uint8) rr, cc = ellipse(cy, cx, ellipse_yradius, ellipse_xradius) ellipseArray[rr, cc] = 1 m, n = ellipseArray.shape assert m==n if (m%2 == 0): pad_before = (boxsize - m)/2 pad_after = (boxsize - m)/2 else: pad_before = (boxsize - m)/2 pad_after = (boxsize - m)/2+1 ellipseArrayPad = np.pad(ellipseArray, (pad_before, pad_after), mode='constant') ellipseImg = EMNumPy.numpy2em(ellipseArrayPad) return ellipseImg
import matplotlib.pyplot as plt import numpy as np from skimage import measure from skimage.draw import ellipse from skimage.transform import rotate image = np.zeros((600, 600)) rr, cc = ellipse(300, 350, 100, 220) image[rr, cc] = 1 image = rotate(image, angle=15, order=0) label_img = measure.label(input=image) print(label_img.shape, label_img.max(), label_img.min(), np.unique(label_img)) print(np.sum(image - label_img)) # regions = measure.regionprops(label_image=label_img) print(regions) fig, ax = plt.subplots() ax.imshow(image, cmap=plt.cm.gray) # pylint: disable=E1101
def read_roi(roi_obj): """Parses an individual ImageJ ROI _getX lines with no assignment are bytes within the imageJ roi file format that contain additional information that can be extracted if needed. In line comments label what they are. This is based on: http://rsbweb.nih.gov/ij/developer/source/ij/io/RoiDecoder.java.html http://rsbweb.nih.gov/ij/developer/source/ij/io/RoiEncoder.java.html Parameters ---------- roi_obj : file object File object containing a single ImageJ ROI Returns ------- ROI Returns a parsed ROI object (dictionary) Raises ------ IOError If there is an error reading the roi file object ValueError If unable to parse ROI """ sub_pixel_resolution = 128 # Other options that are not currently used # SPLINE_FIT = 1 # DOUBLE_HEADED = 2 # OUTLINE = 4 # OVERLAY_LABELS = 8 # OVERLAY_NAMES = 16 # OVERLAY_BACKGROUNDS = 32 # OVERLAY_BOLD = 64 # DRAW_OFFSET = 256 pos = [4] def _get8(): """Read 1 byte from the roi file object""" pos[0] += 1 s = roi_obj.read(1) if not s: raise IOError('read_imagej_roi: Unexpected EOF') return ord(s) def _get16(): """Read 2 bytes from the roi file object""" b0 = _get8() b1 = _get8() return (b0 << 8) | b1 def _get16signed(): """Read a signed 16 bit integer from 2 bytes from roi file object""" b0 = _get8() b1 = _get8() out = (b0 << 8) | b1 # This is a signed integer, so need to check if the value is # positive or negative. if b0 > 127: out = out - 65536 return out def _get32(): """Read 4 bytes from the roi file object""" s0 = _get16() s1 = _get16() return (s0 << 16) | s1 def _getfloat(): """Read a float from the roi file object""" v = np.int32(_get32()) return v.view(np.float32) def _getcoords(z=0): """Get the next coordinate of an roi polygon""" if options & sub_pixel_resolution: getc = _getfloat points = np.empty((n_coordinates, 3), dtype=np.float32) else: getc = _get16 points = np.empty((n_coordinates, 3), dtype=np.int16) points[:, 0] = [getc() for _ in range(n_coordinates)] points[:, 1] = [getc() for _ in range(n_coordinates)] points[:, 0] += left points[:, 1] += top points[:, 2] = z return points magic = roi_obj.read(4) if magic != b'Iout': raise IOError('read_imagej_roi: Magic number not found') _get16() # version roi_type = _get8() # Discard extra second Byte: _get8() if not (0 <= roi_type < 11): raise ValueError('read_imagej_roi: \ ROI type {} not supported'.format(roi_type)) top = _get16signed() left = _get16signed() bottom = _get16signed() right = _get16signed() n_coordinates = _get16() x1 = _getfloat() # x1 y1 = _getfloat() # y1 x2 = _getfloat() # x2 y2 = _getfloat() # y2 _get16() # stroke width _get32() # shape roi size _get32() # stroke color _get32() # fill color subtype = _get16() if subtype != 0 and subtype != 3: raise ValueError('read_imagej_roi: \ ROI subtype {} not supported (!= 0)'.format(subtype)) options = _get16() if subtype == 3 and roi_type == 7: # ellipse aspect ratio aspect_ratio = _getfloat() else: _get8() # arrow style _get8() # arrow head size _get16() # rectangle arc size z = _get32() # position if z > 0: z -= 1 # Multi-plane images start indexing at 1 instead of 0 _get32() # header 2 offset if roi_type == 0: # Polygon coords = _getcoords(z) coords = coords.astype('float') return {'polygons': coords} elif roi_type == 1: # Rectangle coords = [[left, top, z], [right, top, z], [right, bottom, z], [left, bottom, z]] coords = np.array(coords).astype('float') return {'polygons': coords} elif roi_type == 2: # Oval width = right - left height = bottom - top # 0.5 moves the mid point to the center of the pixel x_mid = (right + left) / 2.0 - 0.5 y_mid = (top + bottom) / 2.0 - 0.5 mask = np.zeros((z + 1, right, bottom), dtype=bool) for y, x in product(np.arange(top, bottom), np.arange(left, right)): mask[z, x, y] = ((x - x_mid) ** 2 / (width / 2.0) ** 2 + (y - y_mid) ** 2 / (height / 2.0) ** 2 <= 1) return {'mask': mask} elif roi_type == 7: if subtype == 3: # ellipse mask = np.zeros((1, right+10, bottom+10), dtype=bool) r_radius = np.sqrt((x2-x1)**2+(y2-y1)**2)/2.0 c_radius = r_radius*aspect_ratio r = (x1+x2)/2-0.5 c = (y1+y2)/2-0.5 shpe = mask.shape orientation = np.arctan2(y2-y1, x2-x1) X, Y = ellipse(r, c, r_radius, c_radius, shpe[1:], orientation) mask[0, X, Y] = True return {'mask': mask} else: # Freehand coords = _getcoords(z) coords = coords.astype('float') return {'polygons': coords} else: try: coords = _getcoords(z) coords = coords.astype('float') return {'polygons': coords} except BaseException: raise ValueError( 'read_imagej_roi: ROI type {} not supported'.format(roi_type))
def bp_removal_2d(obj_tmp, cy, cx, fwhm, sig, protect_psf, verbose): n_x = obj_tmp.shape[1] n_y = obj_tmp.shape[0] # Squash the frame if twice less resolved vertically than horizontally if half_res_y: if n_y % 2 != 0: msg = 'The input frames do not have of an even number of rows. ' msg2 = 'Hence, you should not use option half_res_y = True' raise ValueError(msg + msg2) n_y = int(n_y / 2) cy = int(cy / 2) frame = obj_tmp.copy() obj_tmp = np.zeros([n_y, n_x]) for yy in range(n_y): obj_tmp[yy] = frame[2 * yy] #1/ Stddev of background _, _, stddev = sigma_clipped_stats(obj_tmp, sigma=2.5) #2/ Define each annulus, its median and stddev ymax = max(cy, n_y - cy) xmax = max(cx, n_x - cx) if half_res_y: ymax *= 2 rmax = np.sqrt(ymax**2 + xmax**2) # the annuli definition is optimized for Airy rings ann_width = max(1.5, 0.61 * fwhm) nrad = int(rmax / ann_width) + 1 d_bord_max = max(n_y - cy, cy, n_x - cx, cx) if half_res_y: d_bord_max = max(2 * (n_y - cy), 2 * cy, n_x - cx, cx) big_ell_frame = np.zeros_like(obj_tmp) sma_ell_frame = np.zeros_like(obj_tmp) ann_frame_cumul = np.zeros_like(obj_tmp) n_neig = np.zeros(nrad) med_neig = np.zeros(nrad) std_neig = np.zeros(nrad) neighbours = np.zeros([nrad, n_y * n_x]) for rr in range(nrad): if rr > int(d_bord_max / ann_width): # just to merge farthest annuli with very few elements rr_big = nrad rr_sma = int(d_bord_max / ann_width) else: rr_big = rr rr_sma = rr if half_res_y: big_ell_idx = ellipse(cy=cy, cx=cx, yradius=((rr_big + 1) * ann_width) / 2, xradius=(rr_big + 1) * ann_width, shape=(n_y, n_x)) if rr != 0: small_ell_idx = ellipse(cy=cy, cx=cx, yradius=(rr_sma * ann_width) / 2, xradius=rr_sma * ann_width, shape=(n_y, n_x)) else: big_ell_idx = circle(cy, cx, radius=(rr_big + 1) * ann_width, shape=(n_y, n_x)) if rr != 0: small_ell_idx = circle(cy, cx, radius=rr_sma * ann_width, shape=(n_y, n_x)) big_ell_frame[big_ell_idx] = 1 if rr != 0: sma_ell_frame[small_ell_idx] = 1 ann_frame = big_ell_frame - sma_ell_frame n_neig[rr] = ann_frame[np.where(ann_frame)].shape[0] neighbours[rr, :n_neig[rr]] = obj_tmp[np.where(ann_frame)] ann_frame_cumul[np.where(ann_frame)] = rr # We delete iteratively max and min outliers in each annulus, # so that the annuli median and stddev are not corrupted by bpixs neigh = neighbours[rr, :n_neig[rr]] n_removal = 0 n_pix_init = neigh.shape[0] while neigh.shape[0] > 10 and n_removal < n_pix_init / 10: min_neigh = np.amin(neigh) if reject_outliers(neigh, min_neigh, m=5, stddev=stddev, min_thr=min_thr * stddev, mid_thr=mid_thr * stddev): min_idx = np.argmin(neigh) neigh = np.delete(neigh, min_idx) n_removal += 1 else: max_neigh = np.amax(neigh) if reject_outliers(neigh, max_neigh, m=5, stddev=stddev, min_thr=min_thr * stddev, mid_thr=mid_thr * stddev): max_idx = np.argmax(neigh) neigh = np.delete(neigh, max_idx) n_removal += 1 else: break n_neig[rr] = neigh.shape[0] neighbours[rr, :n_neig[rr]] = neigh neighbours[rr, n_neig[rr]:] = 0 med_neig[rr] = np.median(neigh) std_neig[rr] = np.std(neigh) #3/ Create a tuple-array with coordinates of a circle of radius 1.8*fwhm # centered on the provided coordinates of the star if protect_psf: if half_res_y: circl_new = ellipse(cy, cx, yradius=0.9 * fwhm, xradius=1.8 * fwhm, shape=(n_y, n_x)) else: circl_new = circle(cy, cx, radius=1.8 * fwhm, shape=(n_y, n_x)) else: circl_new = [] #4/ Loop on all pixels to check bpix bpix_map = np.zeros_like(obj_tmp) obj_tmp_corr = obj_tmp.copy() for yy in range(n_y): for xx in range(n_x): if half_res_y: rad = np.sqrt((2 * (cy - yy))**2 + (cx - xx)**2) else: rad = dist(cy, cx, yy, xx) rr = int(rad / ann_width) neigh = neighbours[rr, :n_neig[rr]] dev = max(stddev, min(std_neig[rr], med_neig[rr])) # check min_thr if obj_tmp[yy, xx] < min_thr * stddev: bpix_map[yy, xx] = 1 # Gaussian noise #obj_tmp_corr[yy,xx] = med_neig[rr] +dev*np.random.randn() # Poisson noise rand_fac = 2 * (np.random.rand() - 0.5) obj_tmp_corr[yy,xx] = med_neig[rr] + \ np.sqrt(np.abs(med_neig[rr]))*rand_fac # check median +- sig*stddev elif (obj_tmp[yy, xx] < med_neig[rr] - sig * dev or obj_tmp[yy, xx] > med_neig[rr] + sig * dev): bpix_map[yy, xx] = 1 # Gaussian noise #obj_tmp_corr[yy,xx] = med_neig[rr] +dev*np.random.randn() # Poisson noise rand_fac = 2 * (np.random.rand() - 0.5) obj_tmp_corr[yy,xx] = med_neig[rr] + \ np.sqrt(np.abs(med_neig[rr]))*rand_fac # check mid_thr and neighbours else: min_el = max(2, 0.05 * n_neig[rr]) if (obj_tmp[yy, xx] < mid_thr * stddev and neigh[neigh < (mid_thr + 5) * stddev].shape[0] < min_el): bpix_map[yy, xx] = 1 # Gaussian noise #obj_tmp_corr[yy,xx] = med_neig[rr] + \ # dev*np.random.randn() # Poisson noise rand_fac = 2 * (np.random.rand() - 0.5) obj_tmp_corr[yy,xx] = med_neig[rr] + \ np.sqrt(np.abs(med_neig[rr]))*rand_fac #5/ Count bpix and uncorrect if within the circle nbpix_tot = np.sum(bpix_map) nbpix_tbc = nbpix_tot - np.sum(bpix_map[circl_new]) bpix_map[circl_new] = 0 obj_tmp_corr[circl_new] = obj_tmp[circl_new] if verbose: print(nbpix_tot, ' bpix in total, and ', nbpix_tbc, ' corrected.') # Unsquash all the frames if half_res_y: frame = obj_tmp_corr.copy() frame_bpix = bpix_map.copy() n_y = 2 * n_y obj_tmp_corr = np.zeros([n_y, n_x]) bpix_map = np.zeros([n_y, n_x]) ann_frame = ann_frame_cumul.copy() ann_frame_cumul = np.zeros([n_y, n_x]) for yy in range(n_y): obj_tmp_corr[yy] = frame[int(yy / 2)] bpix_map[yy] = frame_bpix[int(yy / 2)] ann_frame_cumul[yy] = ann_frame[int(yy / 2)] return obj_tmp_corr, bpix_map, ann_frame_cumul
def add_ellipse(self, xy_c, wx, wy, idx=1): rr, cc = ellipse(*xy_c, wx, wy, shape=self.mask.shape) self.mask[rr, cc] = idx
def bp_removal_2d(obj_tmp, cy, cx, fwhm, sig, protect_psf, verbose): n_x = obj_tmp.shape[1] n_y = obj_tmp.shape[0] # Squash the frame if twice less resolved vertically than horizontally if half_res_y: if n_y % 2 != 0: msg = 'The input frames do not have of an even number of rows. ' msg2 = 'Hence, you should not use option half_res_y = True' raise ValueError(msg+msg2) n_y = int(n_y/2) cy = int(cy/2) frame = obj_tmp.copy() obj_tmp = np.zeros([n_y,n_x]) for yy in range(n_y): obj_tmp[yy] = frame[2*yy] #1/ Stddev of background _, _, stddev = sigma_clipped_stats(obj_tmp, sigma=2.5) #2/ Define each annulus, its median and stddev ymax = max(cy, n_y-cy) xmax = max(cx, n_x-cx) if half_res_y: ymax *= 2 rmax = np.sqrt(ymax**2+xmax**2) # the annuli definition is optimized for Airy rings ann_width = max(1.5, 0.61*fwhm) nrad = int(rmax/ann_width)+1 d_bord_max = max(n_y-cy, cy, n_x-cx, cx) if half_res_y: d_bord_max = max(2*(n_y-cy), 2*cy, n_x-cx, cx) big_ell_frame = np.zeros_like(obj_tmp) sma_ell_frame = np.zeros_like(obj_tmp) ann_frame_cumul = np.zeros_like(obj_tmp) n_neig = np.zeros(nrad) med_neig = np.zeros(nrad) std_neig = np.zeros(nrad) neighbours = np.zeros([nrad,n_y*n_x]) for rr in range(nrad): if rr > int(d_bord_max/ann_width): # just to merge farthest annuli with very few elements rr_big = nrad rr_sma = int(d_bord_max/ann_width) else: rr_big = rr rr_sma= rr if half_res_y: big_ell_idx = ellipse(cy=cy, cx=cx, yradius=((rr_big+1)*ann_width)/2, xradius=(rr_big+1)*ann_width, shape=(n_y,n_x)) if rr != 0: small_ell_idx = ellipse(cy=cy, cx=cx, yradius=(rr_sma*ann_width)/2, xradius=rr_sma*ann_width, shape=(n_y,n_x)) else: big_ell_idx = circle(cy, cx, radius=(rr_big+1)*ann_width, shape=(n_y,n_x)) if rr != 0: small_ell_idx = circle(cy, cx, radius=rr_sma*ann_width, shape=(n_y,n_x)) big_ell_frame[big_ell_idx] = 1 if rr!=0: sma_ell_frame[small_ell_idx] = 1 ann_frame = big_ell_frame - sma_ell_frame n_neig[rr] = ann_frame[np.where(ann_frame)].shape[0] neighbours[rr,:n_neig[rr]] = obj_tmp[np.where(ann_frame)] ann_frame_cumul[np.where(ann_frame)] = rr # We delete iteratively max and min outliers in each annulus, # so that the annuli median and stddev are not corrupted by bpixs neigh = neighbours[rr,:n_neig[rr]] n_removal = 0 n_pix_init = neigh.shape[0] while neigh.shape[0] > 10 and n_removal < n_pix_init/10: min_neigh = np.amin(neigh) if reject_outliers(neigh, min_neigh, m=5, stddev=stddev, min_thr=min_thr*stddev, mid_thr=mid_thr*stddev): min_idx = np.argmin(neigh) neigh = np.delete(neigh,min_idx) n_removal += 1 else: max_neigh = np.amax(neigh) if reject_outliers(neigh, max_neigh, m=5, stddev=stddev, min_thr=min_thr*stddev, mid_thr=mid_thr*stddev): max_idx = np.argmax(neigh) neigh = np.delete(neigh,max_idx) n_removal += 1 else: break n_neig[rr] = neigh.shape[0] neighbours[rr,:n_neig[rr]] = neigh neighbours[rr,n_neig[rr]:] = 0 med_neig[rr] = np.median(neigh) std_neig[rr] = np.std(neigh) #3/ Create a tuple-array with coordinates of a circle of radius 1.8*fwhm # centered on the provided coordinates of the star if protect_psf: if half_res_y: circl_new = ellipse(cy, cx, yradius=0.9*fwhm, xradius=1.8*fwhm, shape=(n_y,n_x)) else: circl_new = circle(cy, cx, radius=1.8*fwhm, shape=(n_y, n_x)) else: circl_new = [] #4/ Loop on all pixels to check bpix bpix_map = np.zeros_like(obj_tmp) obj_tmp_corr = obj_tmp.copy() for yy in range(n_y): for xx in range(n_x): if half_res_y: rad = np.sqrt((2*(cy-yy))**2+(cx-xx)**2) else: rad = dist(cy, cx, yy, xx) rr = int(rad/ann_width) neigh = neighbours[rr,:n_neig[rr]] dev = max(stddev,min(std_neig[rr],med_neig[rr])) # check min_thr if obj_tmp[yy,xx] < min_thr*stddev: bpix_map[yy,xx] = 1 # Gaussian noise #obj_tmp_corr[yy,xx] = med_neig[rr] +dev*np.random.randn() # Poisson noise rand_fac= 2*(np.random.rand()-0.5) obj_tmp_corr[yy,xx] = med_neig[rr] + \ np.sqrt(np.abs(med_neig[rr]))*rand_fac # check median +- sig*stddev elif (obj_tmp[yy,xx] < med_neig[rr]-sig*dev or obj_tmp[yy,xx] > med_neig[rr]+sig*dev): bpix_map[yy,xx] = 1 # Gaussian noise #obj_tmp_corr[yy,xx] = med_neig[rr] +dev*np.random.randn() # Poisson noise rand_fac= 2*(np.random.rand()-0.5) obj_tmp_corr[yy,xx] = med_neig[rr] + \ np.sqrt(np.abs(med_neig[rr]))*rand_fac # check mid_thr and neighbours else: min_el = max(2, 0.05*n_neig[rr]) if (obj_tmp[yy,xx] < mid_thr*stddev and neigh[neigh<(mid_thr+5)*stddev].shape[0] < min_el): bpix_map[yy,xx] = 1 # Gaussian noise #obj_tmp_corr[yy,xx] = med_neig[rr] + \ # dev*np.random.randn() # Poisson noise rand_fac = 2*(np.random.rand()-0.5) obj_tmp_corr[yy,xx] = med_neig[rr] + \ np.sqrt(np.abs(med_neig[rr]))*rand_fac #5/ Count bpix and uncorrect if within the circle nbpix_tot = np.sum(bpix_map) nbpix_tbc = nbpix_tot - np.sum(bpix_map[circl_new]) bpix_map[circl_new] = 0 obj_tmp_corr[circl_new] = obj_tmp[circl_new] if verbose: print(nbpix_tot, ' bpix in total, and ', nbpix_tbc, ' corrected.') # Unsquash all the frames if half_res_y: frame = obj_tmp_corr.copy() frame_bpix = bpix_map.copy() n_y = 2*n_y obj_tmp_corr = np.zeros([n_y,n_x]) bpix_map = np.zeros([n_y,n_x]) ann_frame = ann_frame_cumul.copy() ann_frame_cumul = np.zeros([n_y,n_x]) for yy in range(n_y): obj_tmp_corr[yy] = frame[int(yy/2)] bpix_map[yy] = frame_bpix[int(yy/2)] ann_frame_cumul[yy] = ann_frame[int(yy/2)] return obj_tmp_corr, bpix_map, ann_frame_cumul
def bp_removal_2d(obj_tmp, cy, cx, fwhm, sig, protect_psf, verbose): n_x = obj_tmp.shape[1] n_y = obj_tmp.shape[0] if half_res_y: if n_y%2 != 0: msg = 'The input frames do not have of an even number of rows. ' msg2 = 'Hence, you should not use option half_res_y = True' raise ValueError(msg+msg2) n_y = int(n_y/2) frame = obj_tmp.copy() obj_tmp = np.zeros([n_y,n_x]) for yy in range(n_y): obj_tmp[yy] = frame[2*yy] fwhm_round = int(round(fwhm)) # This should reduce the chance to accidently correct a bright planet: if fwhm_round % 2 == 0: neighbor_box = max(3, fwhm_round+1) else: neighbor_box = max(3, fwhm_round) nneig = sum(np.arange(3, neighbor_box+2, 2)) #1/ Create a tuple-array with coordinates of a circle of radius 1.8*fwhm # centered on the approximate coordinates of the star if protect_psf: if half_res_y: circl_new = ellipse(int(cy/2), cx, yradius=0.9*fwhm, xradius=1.8*fwhm, shape=(n_y, n_x)) else: circl_new = circle(cy, cx, radius=1.8*fwhm, shape=(n_y, n_x)) else: circl_new = [] #2/ Compute stddev of background # empirically 2.5 is best to find stddev of background noise _, _, stddev = sigma_clipped_stats(obj_tmp, sigma=2.5) #3/ Create a bad pixel map, by detecting them with find_outliers bpix_map = find_outliers(obj_tmp, sig_dist=sig, stddev=stddev, neighbor_box=neighbor_box,min_thr=min_thr, mid_thr=mid_thr) nbpix_tot = np.sum(bpix_map) nbpix_tbc = nbpix_tot - np.sum(bpix_map[circl_new]) bpix_map[circl_new] = 0 bpix_map_cumul = np.zeros_like(bpix_map) bpix_map_cumul[:] = bpix_map[:] nit = 0 #4/ Loop over the bpix correction with sigma_filter, until 0 bpix left while nbpix_tbc > 0 and nit < max_nit: nit = nit+1 if verbose: print("Iteration {}: {} bpix in total, {} to be " "corrected".format(nit, nbpix_tot, nbpix_tbc)) obj_tmp = sigma_filter(obj_tmp, bpix_map, neighbor_box=neighbor_box, min_neighbors=nneig, verbose=verbose) bpix_map = find_outliers(obj_tmp, sig_dist=sig, in_bpix=bpix_map, stddev=stddev, neighbor_box=neighbor_box, min_thr=min_thr,mid_thr=mid_thr) nbpix_tot = np.sum(bpix_map) nbpix_tbc = nbpix_tot - np.sum(bpix_map[circl_new]) bpix_map[circl_new] = 0 bpix_map_cumul = bpix_map_cumul+bpix_map if verbose: print('All bad pixels are corrected.') if half_res_y: frame = obj_tmp.copy() frame_bpix = bpix_map_cumul.copy() n_y = 2*n_y obj_tmp = np.zeros([n_y,n_x]) bpix_map_cumul = np.zeros([n_y,n_x]) for yy in range(n_y): obj_tmp[yy] = frame[int(yy/2)] bpix_map_cumul[yy] = frame_bpix[int(yy/2)] return obj_tmp, bpix_map_cumul
This example shows how to measure properties of labelled image regions. """ import math import matplotlib.pyplot as plt import numpy as np from skimage.draw import ellipse from skimage.measure import label, regionprops from skimage.transform import rotate image = np.zeros((600, 600)) rr, cc = ellipse(300, 350, 100, 220) image[rr, cc] = 1 image = rotate(image, angle=15, order=0) label_img = label(image) regions = regionprops(label_img) fig, ax = plt.subplots() ax.imshow(image, cmap=plt.cm.gray) for props in regions: y0, x0 = props.centroid orientation = props.orientation x1 = x0 + math.cos(orientation) * 0.5 * props.major_axis_length y1 = y0 - math.sin(orientation) * 0.5 * props.major_axis_length
def draw_mask(img, percentage_x=100, percentage_y=100, offset_x=0, offset_y=0, rotation=0, rectangle=True): """ Convenience wrapper for `skimage.draw.ellipse` and `skimage.draw.polygon`. Draws an ellipse at (center + ``offset``) of ``img`` with major and minor axes as a percentage of ``img.shape``. Alternatively, draws a rectangle centered at the offset that covers the given percentage of the height and width of the image. Parameters ---------- img : array Image array that you want to draw a mask on percentage_x : float What percentage of the x-dimension of ``img`` do you want the x-axis to cover? Can be greater than zero percentage_y : float offset_x : float From the middle, what percentage of the width of the picture do you want the center of the ellipse to be? Positive is left. offset_y : float Positive is up. rotation : float In [-pi, pi]. See ``skimage.draw.ellipse'' rectangel : bool Make a rectangular mask instead of an elliptical mask? Returns ------- A binary array with pixels in an ellipse. References ---------- See source and examples for `skimage.draw.ellipse` and `skimage.draw.polygon`. """ ydim, xdim = img.shape mask = np.zeros((ydim, xdim)) # Convert percentages to fractions offset_x = (xdim * offset_x/100) offset_y = (ydim * offset_y/100) percentage_x = percentage_x/100 percentage_y = percentage_y/100 if rectangle is False: x_rad = np.floor((img.shape[1]/2) * percentage_x) y_rad = np.floor((img.shape[0]/2) * percentage_y) x_center = img.shape[1]//2 + offset_x y_center = img.shape[0]//2 - offset_y [x, y] = draw.ellipse(y_center, x_center, y_rad, x_rad, shape = img.shape, rotation=rotation) else: ysub = ydim * (1 - percentage_y) y1 = max(ysub/2 - offset_y, 0) y2 = min(ydim - ysub/2 - offset_y, ydim) r_coords = np.array([y1, y1, y2, y2, y1]) xsub = xdim * (1 - percentage_x) x1 = max(xsub/2 + offset_x,0) x2 = min(xdim - xsub/2 + offset_x, xdim) c_coords = np.array([x1, x2, x2, x1, x1]) x, y = draw.polygon(r_coords, c_coords) mask[x, y] = 1 return(mask)
.. [1] http://en.wikipedia.org/wiki/Corner_detection .. [2] http://en.wikipedia.org/wiki/Interest_point_detection """ from matplotlib import pyplot as plt from skimage import data from skimage.feature import corner_harris, corner_subpix, corner_peaks from skimage.transform import warp, AffineTransform from skimage.draw import ellipse tform = AffineTransform(scale=(1.3, 1.1), rotation=1, shear=0.7, translation=(210, 50)) image = warp(data.checkerboard(), tform.inverse, output_shape=(350, 350)) rr, cc = ellipse(310, 175, 10, 100) image[rr, cc] = 1 image[180:230, 10:60] = 1 image[230:280, 60:110] = 1 coords = corner_peaks(corner_harris(image), min_distance=5) coords_subpix = corner_subpix(image, coords, window_size=13) fig, ax = plt.subplots() ax.imshow(image, interpolation='nearest', cmap=plt.cm.gray) ax.plot(coords[:, 1], coords[:, 0], '.b', markersize=3) ax.plot(coords_subpix[:, 1], coords_subpix[:, 0], '+r', markersize=15) ax.axis((0, 350, 350, 0)) plt.show()
ax3.set_axis_off() ax3.set_title('Masked pixels') plt.show() ################################################## # Solid masks are another illustrating example. In this case, we have a # limited view of an image and an offset image. The masks for these images # need not be the same. The `masked_register_translation` function will correctly identify # which part of the images should be compared. image = data.camera() shift = (-22, 13) rr1, cc1 = draw.ellipse(259, 248, r_radius = 125, c_radius = 100, shape = image.shape) rr2, cc2 = draw.ellipse(300, 200, r_radius = 110, c_radius = 180, shape = image.shape) mask1 = np.zeros_like(image, dtype = np.bool) mask2 = np.zeros_like(image, dtype = np.bool) mask1[rr1, cc1] = True mask2[rr2, cc2] = True offset_image = ndi.shift(image, shift) image *= mask1 offset_image *= mask2
def draw_ellipse(img, center, axis): rr, cc = draw.ellipse(center[0], center[1], axis[0], axis[1], shape=img.shape) img[rr, cc] = 1 return img
def axis_likelyhood_surface(data, kernel_width = 5, center_margin = 8, num_peaks = 10, num_circles = 20, upscale = 1.5, minradius = 15, maxradius = 65, radstep = 2): ximagesize=data[0]['data'].shape[1] yimagesize=data[0]['data'].shape[2] maxradius = max(int(maxradius / np.max(data[0]['metadata']['PixelSpacing'])),1) minradius = max(int(minradius / np.max(data[0]['metadata']['PixelSpacing'])),1) radstep = max(int(radstep / np.max(data[0]['metadata']['PixelSpacing'])),1) xsurface=np.tile(range(ximagesize),(yimagesize,1)).T ysurface=np.tile(range(yimagesize),(ximagesize,1)) lsurface=np.zeros((ximagesize,yimagesize)) allcenters = [] allaccums = [] allradii = [] for ddi in data: outdata=ddi['data'].copy() ff1 = fftn(outdata) fh = np.absolute(ifftn(ff1[1, :, :])) fh[fh < 0.1* np.max(fh)] =0.0 image=img_as_ubyte(fh/np.max(fh)) #image = fh/np.max(fh) # find hough circles edges = canny(image, sigma=3, low_threshold=10, high_threshold=50) #edges = canny(image) # Detect two radii hough_radii = np.arange(minradius, maxradius, radstep) hough_res = hough_circle(edges, hough_radii) if hough_res.any(): centers = [] accums = [] radii = [] for radius, h in zip(hough_radii, hough_res): # For each radius, extract num_peaks circles peaks = peak_local_max(h, num_peaks=num_peaks) centers.extend(peaks) accums.extend(h[peaks[:, 0], peaks[:, 1]]) radii.extend([radius] * num_peaks) # Keep the most prominent num_circles circles sorted=np.argsort(accums)[::-1][:num_circles] for idx in sorted: center_x, center_y = centers[idx] allcenters.append(centers[idx]) allradii.append(radii[idx]) allaccums.append(accums[idx]) brightness=accums[idx] lsurface = lsurface + brightness* np.exp(-((xsurface-center_x)**2 + (ysurface-center_y)**2)/kernel_width**2) lsurface=lsurface/lsurface.max() # select most likely ROI center x_axis, y_axis = np.unravel_index(lsurface.argmax(), lsurface.shape) # determine ROI radius x_radius = 0 y_radius = 0 for idx in range(len(allcenters)): xshift=np.abs(allcenters[idx][0]-x_axis) yshift=np.abs(allcenters[idx][1]-y_axis) if (xshift <= center_margin) & (yshift <= center_margin): x_radius = np.max((x_radius,allradii[idx]+xshift)) y_radius = np.max((y_radius,allradii[idx]+yshift)) x_radius = upscale * x_radius y_radius = upscale * y_radius #x_radius = 1.5*maxradius #y_radius = 1.5*maxradius ROImask = np.zeros_like(lsurface) [rr,cc] = ellipse(x_axis, y_axis, x_radius, y_radius) dum=(rr < ximagesize) & (rr>=0) & (cc < yimagesize) & (cc>=0) rr=rr[dum] cc=cc[dum] ROImask[rr,cc]=1. return lsurface, ROImask, (x_axis, y_axis), (x_radius, y_radius)
def bp_removal_2d(obj_tmp, cy, cx, fwhm, sig, protect_psf, verbose): n_x = obj_tmp.shape[1] n_y = obj_tmp.shape[0] if half_res_y: if n_y % 2 != 0: msg = 'The input frames do not have of an even number of rows. ' msg2 = 'Hence, you should not use option half_res_y = True' raise ValueError(msg + msg2) n_y = int(n_y / 2) frame = obj_tmp.copy() obj_tmp = np.zeros([n_y, n_x]) for yy in range(n_y): obj_tmp[yy] = frame[2 * yy] fwhm_round = int(round(fwhm)) # This should reduce the chance to accidently correct a bright planet: if fwhm_round % 2 == 0: neighbor_box = max(3, fwhm_round + 1) else: neighbor_box = max(3, fwhm_round) nneig = sum(np.arange(3, neighbor_box + 2, 2)) #1/ Create a tuple-array with coordinates of a circle of radius 1.8*fwhm # centered on the approximate coordinates of the star if protect_psf: if half_res_y: circl_new = ellipse(int(cy / 2), cx, yradius=0.9 * fwhm, xradius=1.8 * fwhm, shape=(n_y, n_x)) else: circl_new = circle(cy, cx, radius=1.8 * fwhm, shape=(n_y, n_x)) else: circl_new = [] #2/ Compute stddev of background # empirically 2.5 is best to find stddev of background noise _, _, stddev = sigma_clipped_stats(obj_tmp, sigma=2.5) #3/ Create a bad pixel map, by detecting them with find_outliers bpix_map = find_outliers(obj_tmp, sig_dist=sig, stddev=stddev, neighbor_box=neighbor_box, min_thr=min_thr, mid_thr=mid_thr) nbpix_tot = np.sum(bpix_map) nbpix_tbc = nbpix_tot - np.sum(bpix_map[circl_new]) bpix_map[circl_new] = 0 bpix_map_cumul = np.zeros_like(bpix_map) bpix_map_cumul[:] = bpix_map[:] nit = 0 #4/ Loop over the bpix correction with sigma_filter, until 0 bpix left while nbpix_tbc > 0 and nit < max_nit: nit = nit + 1 if verbose: print("Iteration {}: {} bpix in total, {} to be " "corrected".format(nit, nbpix_tot, nbpix_tbc)) obj_tmp = sigma_filter(obj_tmp, bpix_map, neighbor_box=neighbor_box, min_neighbors=nneig, verbose=verbose) bpix_map = find_outliers(obj_tmp, sig_dist=sig, in_bpix=bpix_map, stddev=stddev, neighbor_box=neighbor_box, min_thr=min_thr, mid_thr=mid_thr) nbpix_tot = np.sum(bpix_map) nbpix_tbc = nbpix_tot - np.sum(bpix_map[circl_new]) bpix_map[circl_new] = 0 bpix_map_cumul = bpix_map_cumul + bpix_map if verbose: print('All bad pixels are corrected.') if half_res_y: frame = obj_tmp.copy() frame_bpix = bpix_map_cumul.copy() n_y = 2 * n_y obj_tmp = np.zeros([n_y, n_x]) bpix_map_cumul = np.zeros([n_y, n_x]) for yy in range(n_y): obj_tmp[yy] = frame[int(yy / 2)] bpix_map_cumul[yy] = frame_bpix[int(yy / 2)] return obj_tmp, bpix_map_cumul
def test_ellipse_generic(): img = np.zeros((4, 4), 'uint8') rr, cc = ellipse(1.5, 1.5, 1.1, 1.7) img[rr, cc] = 1 img_ = np.array([ [0, 0, 0, 0], [1, 1, 1, 1], [1, 1, 1, 1], [0, 0, 0, 0], ]) assert_array_equal(img, img_) img = np.zeros((5, 5), 'uint8') rr, cc = ellipse(2, 2, 1.7, 1.7) img[rr, cc] = 1 img_ = np.array([ [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0], ]) assert_array_equal(img, img_) img = np.zeros((10, 10), 'uint8') rr, cc = ellipse(5, 5, 3, 4) img[rr, cc] = 1 img_ = np.array([ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ]) assert_array_equal(img, img_) img = np.zeros((10, 10), 'uint8') rr, cc = ellipse(4.5, 5, 3.5, 4) img[rr, cc] = 1 img_ = np.array([ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ]) assert_array_equal(img, img_) img = np.zeros((15, 15), 'uint8') rr, cc = ellipse(7, 7, 3, 7) img[rr, cc] = 1 img_ = np.array([ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ]) assert_array_equal(img, img_)
poly = np.array(( (300, 300), (480, 320), (380, 430), (220, 590), (300, 300), )) rr, cc = polygon(poly[:,0], poly[:,1], img.shape) img[rr,cc,1] = 255 # fill circle rr, cc = circle(200, 200, 100, img.shape) img[rr,cc,:] = (255, 255, 0) # fill ellipse rr, cc = ellipse(300, 300, 100, 200, img.shape) img[rr,cc,2] = 255 # circle rr, cc = circle_perimeter(120, 400, 15) img[rr, cc, :] = (255, 0, 0) # ellipses rr, cc = ellipse_perimeter(120, 400, 60, 20, orientation=math.pi / 4.) img[rr, cc, :] = (255, 0, 255) rr, cc = ellipse_perimeter(120, 400, 60, 20, orientation=-math.pi / 4.) img[rr, cc, :] = (0, 0, 255) rr, cc = ellipse_perimeter(120, 400, 60, 20, orientation=math.pi / 2.) img[rr, cc, :] = (255, 255, 255) plt.imshow(img)
# approximate subdivided polygon with Douglas-Peucker algorithm appr_hand = approximate_polygon(new_hand, tolerance=0.02) print("Number of coordinates:", len(hand), len(new_hand), len(appr_hand)) fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(9, 4)) ax1.plot(hand[:, 0], hand[:, 1]) ax1.plot(new_hand[:, 0], new_hand[:, 1]) ax1.plot(appr_hand[:, 0], appr_hand[:, 1]) # create two ellipses in image img = np.zeros((800, 800), 'int32') rr, cc = ellipse(250, 250, 180, 230, img.shape) img[rr, cc] = 1 rr, cc = ellipse(600, 600, 150, 90, img.shape) img[rr, cc] = 1 plt.gray() ax2.imshow(img) # approximate / simplify coordinates of the two ellipses for contour in find_contours(img, 0): coords = approximate_polygon(contour, tolerance=2.5) ax2.plot(coords[:, 1], coords[:, 0], '-r', linewidth=2) coords2 = approximate_polygon(contour, tolerance=39.5) ax2.plot(coords2[:, 1], coords2[:, 0], '-g', linewidth=2) print("Number of coordinates:", len(contour), len(coords), len(coords2))
def process_one(kdata, kdata_ref, acs_out, debug_path='debug_fig_sq'): # Transpose to get the channel index in position 0, and rotate the image (if necessary) #img_coils = np.rot90(np.transpose(img_coils, (2,0,1)),k=-1,axes=(1,2)) #print (img_coils.shape) # Crop the image (if necessary) #img_coils = img_coils[:,:,:] # Get the dimensions kspace_fully_sampled = kdata [num_chan, N1, N2, Nt] = kspace_fully_sampled.shape #mosaic(kspace_fully_sampled[:,:,:], 4, 8, 1, [0,2e-5], fig_title='kspace_fully_sampled', fig_size=(15,15), num_rot=0) # Get the rssq image ''' kspace_fully_sampled = np.fft.fftshift(np.fft.ifft(np.fft.ifftshift(kspace_fully_sampled, axes=3), axis=3), axes=3) img_coils = np.fft.fftshift(np.fft.ifft2(np.fft.ifftshift(kspace_fully_sampled, axes=(1,2)), axes=(1,2)), axes=(1,2)) image_original0 = np.sqrt(np.sum(np.square(np.abs(img_coils)),axis=0)) for i in range(75,90): image_original = image_original0[:,:,i] mosaic(image_original, 1, 1, 1, [0,150], fig_title=f'image_original_{i}', fig_base_path=debug_path, fig_size=(10,10), num_rot=0) raise ''' #num_acs = (24, 24, 256) num_acs = (22, 22, 256) #num_acs = (N1, 30, 40) Rx = 4 Ry = 2 acs_x, acs_y, acs_t = num_acs acs_start_index_x = N1 // 2 - num_acs[0] // 2 # inclusive acs_start_index_y = N2 // 2 - num_acs[1] // 2 # inclusive acs_end_index_x = np.int(np.ceil(N1 / 2)) + num_acs[0] // 2 # exclusive acs_end_index_y = np.int(np.ceil(N2 / 2)) + num_acs[1] // 2 # exclusive acs_start_index_t = Nt // 2 - num_acs[2] // 2 # inclusive acs_end_index_t = np.int(np.ceil(Nt / 2)) + num_acs[2] // 2 # exclusive #print (acs_start_index_x, acs_end_index_x) #print (acs_start_index_y, acs_end_index_y) #print (acs_start_index_t, acs_end_index_t) #kspace_undersampled_zero_filled = np.zeros(kspace_fully_sampled.shape, dtype=kspace_fully_sampled.dtype) #kspace_undersampled_zero_filled[:,0:N1:Ry,0:N2:Rx,:] = kspace_fully_sampled[:,0:N1:Ry,0:N2:Rx,:] #print (kspace_undersampled_zero_filled.shape) print(kspace_fully_sampled.shape) c, w, h, z = kspace_fully_sampled.shape mask_ellip = np.zeros((w, h), dtype=np.uint8) rr, cc = ellipse(w // 2, h // 2, w // 2, h // 2) mask_ellip[rr, cc] = 1 print(mask_ellip.shape) mask_ellip = np.expand_dims(mask_ellip, axis=0) mask_ellip = np.repeat(mask_ellip, c, axis=0) mask_ellip = np.expand_dims(mask_ellip, axis=-1) mask_ellip = np.repeat(mask_ellip, z, axis=-1) print(mask_ellip.shape) mask = np.zeros(kspace_fully_sampled.shape) mask[0:32, 0:N1:7, 0:N2:7, :] = 1 mask[0:32, 1:N1:7, 3:N2:7, :] = 1 mask[0:32, 2:N1:7, 6:N2:7, :] = 1 mask[0:32, 3:N1:7, 2:N2:7, :] = 1 mask[0:32, 4:N1:7, 5:N2:7, :] = 1 mask[0:32, 5:N1:7, 1:N2:7, :] = 1 mask[0:32, 6:N1:7, 4:N2:7, :] = 1 mask[32:64, 1:N1:7, 1:N2:7, :] = 1 mask[32:64, 2:N1:7, 4:N2:7, :] = 1 mask[32:64, 3:N1:7, 0:N2:7, :] = 1 mask[32:64, 4:N1:7, 3:N2:7, :] = 1 mask[32:64, 5:N1:7, 6:N2:7, :] = 1 mask[32:64, 6:N1:7, 2:N2:7, :] = 1 mask[32:64, 0:N1:7, 5:N2:7, :] = 1 mask[64:96, 2:N1:7, 2:N2:7, :] = 1 mask[64:96, 3:N1:7, 5:N2:7, :] = 1 mask[64:96, 4:N1:7, 1:N2:7, :] = 1 mask[64:96, 5:N1:7, 4:N2:7, :] = 1 mask[64:96, 6:N1:7, 0:N2:7, :] = 1 mask[64:96, 0:N1:7, 3:N2:7, :] = 1 mask[64:96, 1:N1:7, 6:N2:7, :] = 1 ''' mask[:, 0:N1:7, 0:N2:7, :] = 1 mask[:, 1:N1:7, 3:N2:7, :] = 1 mask[:, 2:N1:7, 6:N2:7, :] = 1 mask[:, 3:N1:7, 2:N2:7, :] = 1 mask[:, 4:N1:7, 5:N2:7, :] = 1 mask[:, 5:N1:7, 1:N2:7, :] = 1 mask[:, 6:N1:7, 4:N2:7, :] = 1 #print (mask[10,0:16,0:16,10]) #raise ''' ''' mask[0:16, 0:N1:7, 0:N2:7, :] = 1 mask[0:16, 1:N1:7, 3:N2:7, :] = 1 mask[0:16, 2:N1:7, 6:N2:7, :] = 1 mask[0:16, 3:N1:7, 2:N2:7, :] = 1 mask[0:16, 4:N1:7, 5:N2:7, :] = 1 mask[0:16, 5:N1:7, 1:N2:7, :] = 1 mask[0:16, 6:N1:7, 4:N2:7, :] = 1 mask[16:32, 1:N1:7, 1:N2:7, :] = 1 mask[16:32, 2:N1:7, 4:N2:7, :] = 1 mask[16:32, 3:N1:7, 0:N2:7, :] = 1 mask[16:32, 4:N1:7, 3:N2:7, :] = 1 mask[16:32, 5:N1:7, 6:N2:7, :] = 1 mask[16:32, 6:N1:7, 2:N2:7, :] = 1 mask[16:32, 0:N1:7, 5:N2:7, :] = 1 mask[32:48, 2:N1:7, 2:N2:7, :] = 1 mask[32:48, 3:N1:7, 5:N2:7, :] = 1 mask[32:48, 4:N1:7, 1:N2:7, :] = 1 mask[32:48, 5:N1:7, 4:N2:7, :] = 1 mask[32:48, 6:N1:7, 0:N2:7, :] = 1 mask[32:48, 0:N1:7, 3:N2:7, :] = 1 mask[32:48, 1:N1:7, 6:N2:7, :] = 1 ''' #print (mask.shape) #raise kspace_undersampled_zero_filled0 = kspace_fully_sampled * mask * mask_ellip #kspace_undersampled_zero_filled = kspace_undersampled_zero_filled0[0:16,...] + kspace_undersampled_zero_filled0[16:32,...] + kspace_undersampled_zero_filled0[32:48,...] kspace_undersampled_zero_filled = kspace_undersampled_zero_filled0[ 0:32, ...] + kspace_undersampled_zero_filled0[32:64, ...] kspace_acs_zero_filled = np.zeros(kspace_fully_sampled.shape, dtype=kspace_fully_sampled.dtype) kspace_acs_zero_filled[:, acs_start_index_x:acs_end_index_x, acs_start_index_y:acs_end_index_y, acs_start_index_t: acs_end_index_t] = kspace_fully_sampled[:, acs_start_index_x: acs_end_index_x, acs_start_index_y: acs_end_index_y, acs_start_index_t: acs_end_index_t] print(kspace_acs_zero_filled.shape) kspace_acs_cropped = np.zeros( [num_chan, num_acs[0], num_acs[1], num_acs[2]], dtype=kspace_fully_sampled.dtype) kspace_acs_cropped[:, :, :, :] = kspace_fully_sampled[:, acs_start_index_x: acs_end_index_x, acs_start_index_y: acs_end_index_y, acs_start_index_t: acs_end_index_t] #tmp = kdata_ref[acs_start_index_x:acs_end_index_x,acs_start_index_y:acs_end_index_y, acs_start_index_t:acs_end_index_t] #print (tmp.shape) #print (acs_out.shape) #print (tmp[:,12,100]) #print (acs_out[0,:,12,100]) #raise #kspace_coils_acs_out = acs_out kspace_coils_acs_out = acs_out[:, 1:-1, 1:-1, :] #kspace_coils_acs_out = acs_out[:,acs_start_index_x:acs_end_index_x,acs_start_index_y:acs_end_index_y, acs_start_index_t:acs_end_index_t] #kspace_coils_acs_out = kspace_acs_cropped #kspace_coils_acs_out = np.expand_dims(kdata_ref[acs_start_index_x:acs_end_index_x,acs_start_index_y:acs_end_index_y, acs_start_index_t:acs_end_index_t], axis=0) ''' tmp = np.expand_dims(kdata_ref[acs_start_index_x:acs_end_index_x,acs_start_index_y:acs_end_index_y, acs_start_index_t:acs_end_index_t], axis=0) print (kspace_coils_acs_out.shape) print (tmp.shape) print (kspace_coils_acs_out[0,10:12,10:12,5]) print (tmp[0,10:12,10:12,5]) raise ''' #print (kspace_coils_acs_out.shape) #img_test = np.fft.fftshift(np.fft.ifft2(np.fft.ifftshift(kspace_coils_acs_out[0,:,:,0], axes=(0,1)), axes=(0,1)), axes=(0,1)) #mosaic(img_test, 1, 1, 1, [0,2e-5], fig_title='img_test', fig_base_path='debug_test', fig_size=(15,15), num_rot=0) #kdata_ref[acs_start_index_x:acs_end_index_x,acs_start_index_y:acs_end_index_y, acs_start_index_t:acs_end_index_t] = acs_out[0,...] #put acs back to ref img_coils_ref = np.fft.fftshift(np.fft.ifftn(np.fft.ifftshift(kdata_ref, axes=(0, 1, 2)), axes=(0, 1, 2)), axes=(0, 1, 2)) #img_coils_ref = np.fft.fftshift(np.fft.ifft2(np.fft.ifftshift(kdata_ref, axes=(0,1)), axes=(0,1)), axes=(0,1)) image_original_ref = np.abs(img_coils_ref) #image_original_ref = np.sqrt(np.sum(np.square(np.abs(img_coils_ref)),axis=0)) print('image_original_ref shape: ', image_original_ref.shape) start_t = time.time() name_image = f'{debug_path}/recon.mat' name_weight = f'{debug_path}/weight.mat' raki(num_chan, N1, N2, Nt, acs_start_index_x, acs_end_index_x, acs_start_index_y, acs_end_index_y, acs_start_index_t, acs_end_index_t, kspace_undersampled_zero_filled, kspace_acs_zero_filled, kspace_coils_acs_out, kspace_acs_cropped, Rx, Ry, debug_path, name_image, name_weight, train_flag=True) print(time.time() - start_t) #show_raki_results(image_original_ref, debug_path, name_image) show_raki_results_3d(image_original_ref, debug_path, name_image)