def check_radon_iradon_circle(interpolation, shape, output_size): # Forward and inverse radon on synthetic data image = _random_circle(shape) radius = min(shape) // 2 sinogram_rectangle = radon(image, circle=False) reconstruction_rectangle = iradon(sinogram_rectangle, output_size=output_size, interpolation=interpolation, circle=False) sinogram_circle = radon(image, circle=True) reconstruction_circle = iradon(sinogram_circle, output_size=output_size, interpolation=interpolation, circle=True) # Crop rectangular reconstruction to match circle=True reconstruction width = reconstruction_circle.shape[0] excess = int(np.ceil((reconstruction_rectangle.shape[0] - width) / 2)) s = np.s_[excess:width + excess, excess:width + excess] reconstruction_rectangle = reconstruction_rectangle[s] # Find the reconstruction circle, set reconstruction to zero outside c0, c1 = np.ogrid[0:width, 0:width] r = np.sqrt((c0 - width // 2)**2 + (c1 - width // 2)**2) reconstruction_rectangle[r > radius] = 0. print(reconstruction_circle.shape) print(reconstruction_rectangle.shape) np.allclose(reconstruction_rectangle, reconstruction_circle)
def test_iradon_angles(): """ Test with different number of projections """ size = 100 # Synthetic data image = np.tri(size) + np.tri(size)[::-1] # Large number of projections: a good quality is expected nb_angles = 200 radon_image_200 = radon(image, theta=np.linspace(0, 180, nb_angles, endpoint=False)) reconstructed = iradon(radon_image_200) delta_200 = np.mean(abs(_rescale_intensity(image) - _rescale_intensity(reconstructed))) assert delta_200 < 0.03 # Lower number of projections nb_angles = 80 radon_image_80 = radon(image, theta=np.linspace(0, 180, nb_angles, endpoint=False)) # Test whether the sum of all projections is approximately the same s = radon_image_80.sum(axis=0) assert np.allclose(s, s[0], rtol=0.01) reconstructed = iradon(radon_image_80) delta_80 = np.mean(abs(image / np.max(image) - reconstructed / np.max(reconstructed))) # Loss of quality when the number of projections is reduced assert delta_80 > delta_200
def check_sinogram_circle_to_square(size): from skimage.transform.radon_transform import _sinogram_circle_to_square image = _random_circle((size, size)) theta = np.linspace(0.0, 180.0, size, False) sinogram_circle = radon(image, theta, circle=True) argmax_shape = lambda a: np.unravel_index(np.argmax(a), a.shape) print("\n\targmax of circle:", argmax_shape(sinogram_circle)) sinogram_square = radon(image, theta, circle=False) print("\targmax of square:", argmax_shape(sinogram_square)) sinogram_circle_to_square = _sinogram_circle_to_square(sinogram_circle) print("\targmax of circle to square:", argmax_shape(sinogram_circle_to_square)) error = abs(sinogram_square - sinogram_circle_to_square) print(np.mean(error), np.max(error)) assert argmax_shape(sinogram_square) == argmax_shape(sinogram_circle_to_square)
def wu_hash(fxy): # compute radon hash, use 180 deg w/sampl. intervall 1 fxy_rad = radon(fxy) # divide into 40x10 blocks bl = blocks(fxy_rad,40,10) # compute mean values of the blocks ms = [] for x in xrange(0,len(bl)): els = [] for y in xrange(0,len(bl[x])): els.append(np.mean(bl[x][y])) ms.append(els) # wavelet decomposition with haar wavelet # for each column resulting in (approx, detail) # approx is thrown away, resulting in a # list of 40 lists with each 5 higher order elements dec = [] for x in xrange(0,len(ms)): dec.append(pywt.dwt(ms[x],"haar")[1]) # apply fft to each component and throw imaginary # components away ffts = map(np.fft.fft,dec) reals = [] for x in xrange(0,len(ffts)): reals_of_x = [] for c in ffts[x]: reals_of_x.append(c.real) reals.append(reals_of_x) return reals
def test_iradon_sart(): debug = False image = rescale(PHANTOM, 0.8) theta_ordered = np.linspace(0., 180., image.shape[0], endpoint=False) theta_missing_wedge = np.linspace(0., 150., image.shape[0], endpoint=True) for theta, error_factor in ((theta_ordered, 1.), (theta_missing_wedge, 2.)): sinogram = radon(image, theta, circle=True) reconstructed = iradon_sart(sinogram, theta) if debug: from matplotlib import pyplot as plt plt.figure() plt.subplot(221) plt.imshow(image, interpolation='nearest') plt.subplot(222) plt.imshow(sinogram, interpolation='nearest') plt.subplot(223) plt.imshow(reconstructed, interpolation='nearest') plt.subplot(224) plt.imshow(reconstructed - image, interpolation='nearest') plt.show() delta = np.mean(np.abs(reconstructed - image)) print('delta (1 iteration) =', delta) assert delta < 0.02 * error_factor reconstructed = iradon_sart(sinogram, theta, reconstructed) delta = np.mean(np.abs(reconstructed - image)) print('delta (2 iterations) =', delta) assert delta < 0.014 * error_factor reconstructed = iradon_sart(sinogram, theta, clip=(0, 1)) delta = np.mean(np.abs(reconstructed - image)) print('delta (1 iteration, clip) =', delta) assert delta < 0.018 * error_factor np.random.seed(1239867) shifts = np.random.uniform(-3, 3, sinogram.shape[1]) x = np.arange(sinogram.shape[0]) sinogram_shifted = np.vstack(np.interp(x + shifts[i], x, sinogram[:, i]) for i in range(sinogram.shape[1])).T reconstructed = iradon_sart(sinogram_shifted, theta, projection_shifts=shifts) if debug: from matplotlib import pyplot as plt plt.figure() plt.subplot(221) plt.imshow(image, interpolation='nearest') plt.subplot(222) plt.imshow(sinogram_shifted, interpolation='nearest') plt.subplot(223) plt.imshow(reconstructed, interpolation='nearest') plt.subplot(224) plt.imshow(reconstructed - image, interpolation='nearest') plt.show() delta = np.mean(np.abs(reconstructed - image)) print('delta (1 iteration, shifted sinogram) =', delta) assert delta < 0.022 * error_factor
def extract(self, image): """ Applies the radon transform to the image. """ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) try: sinogram = radon(gray, theta=self.theta, circle=False) except: print(traceback.format_exc()) return sinogram
def _radon_costf(frame, cent, radint, coords): """ Radon cost function used in frame_center_radon(). """ frame_shifted = frame_shift(frame, coords[0], coords[1]) frame_shifted_ann = get_annulus(frame_shifted, radint, cent-radint) theta = np.linspace(start=0., stop=360., num=frame_shifted_ann.shape[0], endpoint=False) sinogram = radon(frame_shifted_ann, theta=theta, circle=True) costf = np.sum(np.abs(sinogram[cent,:])) return costf
def low_L2_objfun(u,sinogram, lambdapen,dkx,dky,bkx,bky,thetas,image_res, Circle_Mask,TV,TVT,TVTTV): u = np.reshape(u,(image_res,image_res)) u[0==Circle_Mask] = 0. dtheta = (thetas[1]-thetas[0])/180. #Assume regular spaced angles dx = 1./image_res #Assume square image J = .5*np.sum((radon(u,thetas,circle=True)-sinogram)**2)*dtheta*dx J += .5*lambdapen*np.sum( (dkx-bkx-u*TV)**2 )*dx*dx J += .5*lambdapen*np.sum( (dky-bky-TVT*u)**2 )*dx*dx return J
def sinogram_radon(self, img, detectors=0, alpha=0, scans=0): self.__setup(img, detectors, alpha, scans) self._original_image = img scale = 1.0*self._detectors/len(img) img = rescale(img, scale=scale) theta = np.linspace(0., float(self._alpha), self._scans, endpoint=False) # print theta self._sinogram = radon(img, theta=theta, circle=True) return self._sinogram
def tiff_sinos_pad(sinogram,flag,thetas): """ Pads Octopus sinograms (after shape has been extracted elsewhere) so that applying radon to other data won't need a mask and will still be the right shape. NOTE: Very Very hacked together. """ from skimage.transform import radon, iradon if flag=='FBP':#apply Radon transform to FBP of sinogram to use as data imres=sinogram.shape[0] sinogram = radon(iradon(sinogram,thetas,output_size=imres,circle=True), thetas,circle=False) elif flag=='pad':#Insert 0's into sinogram on either side imres=sinogram.shape[0] temp = radon(iradon(0.*sinogram,thetas,output_size=imres,circle=True), thetas,circle=False) sizediff = abs(sinogram.shape[0]-temp.shape[0]) if sizediff>0: #padding is needed sinogram = np.concatenate((temp[0:np.ceil(sizediff/2.),:],sinogram, temp[0:np.floor(sizediff/2.),:])) return sinogram
def check_radon_center(shape, circle): # Create a test image with only a single non-zero pixel at the origin image = np.zeros(shape, dtype=np.float) image[(shape[0] // 2, shape[1] // 2)] = 1. # Calculate the sinogram theta = np.linspace(0., 180., max(shape), endpoint=False) sinogram = radon(image, theta=theta, circle=circle) # The sinogram should be a straight, horizontal line sinogram_max = np.argmax(sinogram, axis=0) print(sinogram_max) assert np.std(sinogram_max) < 1e-6
def low_L2_objgrad(u,sinogram, lambdapen,dkx,dky,bkx,bky,thetas,image_res, Circle_Mask,TV,TVT,TVTTV): u = np.reshape(u,(image_res,image_res)) u[0==Circle_Mask] = 0. dtheta = (thetas[1]-thetas[0])/180. dx = 1./image_res grad = (iradon(radon(u,thetas,circle = True)-sinogram,thetas, output_size = image_res, circle = True,filter = None ))*dtheta*dx*(2.*len(thetas))/np.pi grad -= dx*dx*((lambdapen*TVTTV*u+lambdapen*u*TVTTV) +lambdapen*(TVT*(dkx- bkx)+(dky-bky)*TV)) return np.ravel(grad)
def compute_skew(cls, image): image = image - np.mean(image) # Demean; make the brightness extend above and below zero # Do the radon transform and display the result sinogram = radon(image) # Find the RMS value of each row and find "busiest" rotation, # where the transform is lined up perfectly with the alternating dark # text and white lines r = np.array([rms_flat(line) for line in sinogram.transpose()]) rotation = np.argmax(r) return (90 - rotation) / 100
def check_radon_iradon_minimal(shape, slices): debug = False theta = np.arange(180) image = np.zeros(shape, dtype=np.float) image[slices] = 1. sinogram = radon(image, theta) reconstructed = iradon(sinogram, theta) print('\n\tMaximum deviation:', np.max(np.abs(image - reconstructed))) if debug: _debug_plot(image, reconstructed, sinogram) if image.sum() == 1: assert (np.unravel_index(np.argmax(reconstructed), image.shape) == np.unravel_index(np.argmax(image), image.shape))
def _radon_costf2(frame, cent, radint, coords): """ Radon cost function used in frame_center_radon(). """ frame_shifted = frame_shift(frame, coords[0], coords[1]) frame_shifted_ann = get_annulus(frame_shifted, radint, cent-radint) samples = 10 theta = np.hstack((np.linspace(start=40, stop=50, num=samples, endpoint=False), np.linspace(start=130, stop=140, num=samples, endpoint=False), np.linspace(start=220, stop=230, num=samples, endpoint=False), np.linspace(start=310, stop=320, num=samples, endpoint=False))) sinogram = radon(frame_shifted_ann, theta=theta, circle=True) costf = np.sum(np.abs(sinogram[cent,:])) return costf
def ridgelet(img): n1,n2 = np.shape(img) lvl = np.int(np.log2(n1)) rad = ski.radon(img, theta = np.linspace(0,180,n1)) nr,nt = np.shape(rad) rad_ridgelet = np.zeros((lvl,nr,nt)) for i in np.linspace(0,nt-1,nt): rad_ridgelet[:,:,i] = np.reshape(wavelet_1D(rad[:,i],lvl),(lvl,nr)) # ridgelet = np.zeros((lvl,n1,n2)) ##Not right # for l in np.linspace(0,lvl-1,lvl): # ridgelet[l,:,:] = ski.iradon(rad_ridgelet[l,:,:]) ridgelet = rad_ridgelet return ridgelet
def check_radon_iradon_minimal(shape, slices): debug = False theta = np.arange(180) image = np.zeros(shape, dtype=np.float) image[slices] = 1. sinogram = radon(image, theta, circle=False) reconstructed = iradon(sinogram, theta, circle=False) print('\n\tMaximum deviation:', np.max(np.abs(image - reconstructed))) if debug: _debug_plot(image, reconstructed, sinogram) if image.sum() == 1: assert (np.unravel_index(np.argmax(reconstructed), image.shape) == np.unravel_index( np.argmax(image), image.shape))
def calc_hor_slope(mat, ratio=0.3): """ Calculate the slope of horizontal lines against the horizontal axis. Parameters ---------- mat : array_like 2D binary array. ratio : float Used to select the ROI around the middle of an image. Returns ------- float Horizontal slope of the grid. """ coarse_range = 30.0 # Degree radi = np.pi / 180.0 mat = np.int16(clear_border(_select_roi(mat, ratio))) (height, width) = mat.shape list_angle = 90.0 + np.arange(-coarse_range, coarse_range + 1.0) projections = radon(np.float32(mat), theta=list_angle, circle=False) list_max = np.amax(projections, axis=0) best_angle = -(list_angle[np.argmax(list_max)] - 90.0) dist_error = 0.5 * width * (np.tan(radi) / np.cos(best_angle * radi)) mat_label, num_dots = ndi.label(mat) list_index = np.arange(1, num_dots + 1) list_cent = np.asarray( center_of_mass(mat, labels=mat_label, index=list_index)) list_cent = -list_cent # For coordinate consistency mean_x = np.mean(list_cent[:, 1]) mean_y = np.mean(list_cent[:, 0]) index_mid_dot = np.argsort( np.sqrt((mean_x - list_cent[:, 1])**2 + (mean_y - list_cent[:, 0])**2))[0] used_dot = list_cent[index_mid_dot] line_slope = np.tan(best_angle * radi) list_tmp = np.sqrt( np.ones(num_dots, dtype=np.float32) * line_slope**2 + 1.0) list_tmp2 = used_dot[0] * np.ones( num_dots, dtype=np.float32) - line_slope * used_dot[1] list_dist = np.abs(line_slope * list_cent[:, 1] - list_cent[:, 0] + list_tmp2) / list_tmp dots_selected = np.asarray( [dot for i, dot in enumerate(list_cent) if list_dist[i] < dist_error]) if len(dots_selected) > 1: slope = np.polyfit(dots_selected[:, 1], dots_selected[:, 0], 1)[0] else: slope = line_slope return slope
def test_radon_circle(): a = np.ones((10, 10)) assert_raises(ValueError, radon, a, circle=True) # Synthetic data, circular symmetry shape = (61, 79) c0, c1 = np.ogrid[0:shape[0], 0:shape[1]] r = np.sqrt((c0 - shape[0] // 2)**2 + (c1 - shape[1] // 2)**2) radius = min(shape) // 2 image = np.clip(radius - r, 0, np.inf) image = _rescale_intensity(image) angles = np.linspace(0, 180, min(shape), endpoint=False) sinogram = radon(image, theta=angles, circle=True) assert np.all(sinogram.std(axis=1) < 1e-2) # Synthetic data, random image = _random_circle(shape) sinogram = radon(image, theta=angles, circle=True) mass = sinogram.sum(axis=0) average_mass = mass.mean() relative_error = np.abs(mass - average_mass) / average_mass print(relative_error.max(), relative_error.mean()) assert np.all(relative_error < 3.2e-3)
def skimage_radon_forward_projector(volume, geometry, proj_space, out=None): """Calculate forward projection using skimage. Parameters ---------- volume : `DiscreteLpElement` The volume to project. geometry : `Geometry` The projection geometry to use. proj_space : `DiscreteLp` Space in which the projections (sinograms) live. out : ``proj_space`` element, optional Element to which the result should be written. Returns ------- sinogram : ``proj_space`` element Result of the forward projection. If ``out`` was given, the returned object is a reference to it. """ # Lazy import due to significant import time from skimage.transform import radon # Check basic requirements. Fully checking should be in wrapper assert volume.shape[0] == volume.shape[1] theta = np.degrees(geometry.angles) skimage_range = skimage_proj_space(geometry, volume.space, proj_space) # Rotate volume from (x, y) to (rows, cols), then project sino_arr = radon( np.rot90(volume.asarray(), 1), theta=theta, circle=False ) sinogram = skimage_range.element(sino_arr.T) if out is None: out = proj_space.element() with writable_array(out) as out_arr: point_collocation( clamped_interpolation(skimage_range, sinogram), proj_space.grid.meshgrid, out=out_arr, ) scale = volume.space.cell_sides[0] out *= scale return out
def apply_inverse_map(self, transport_map, sig0): """ Appy inverse transport map. Parameters ---------- transport_map : 2d array, shape (t, len(theta)) Forward transport map. Inverse is computed in this function. sig0 : array, shape (height, width) Reference signal. Returns ------- sig1_recon : array, shape (height, width) Reconstructed signal sig1. """ # Check input arrays transport_map = check_array(transport_map, ndim=2, dtype=[np.float64, np.float32]) sig0 = check_array(sig0, ndim=2, dtype=[np.float64, np.float32], force_strictly_positive=True) # Initialize Radon transforms rad0 = radon(sig0, theta=self.theta, circle=False) rad1 = np.zeros_like(rad0) # Check transport map and Radon transforms are the same size assert_equal_shape(transport_map, rad0, ['transport_map', 'Radon transform of sig0']) # Loop over angles cdt = CDT() for i in range(self.theta.size): # Convert projection to PDF j0 = signal_to_pdf(rad0[:, i], epsilon=1e-8, total=1.) # Radon transform of sig1 comprised of inverse CDT of projections rad1[:, i] = cdt.apply_inverse_map(transport_map[:, i], j0) # Inverse Radon transform sig1_recon = iradon(rad1, self.theta, circle=False, filter='ramp') # Crop sig1_recon to match sig0 sig1_recon = match_shape2d(sig0, sig1_recon) return sig1_recon
def data_load(dataflag,Phant_size,TIFF_dir,TIFF_slice,res_freq,theta_freq, theta_count,padflag,FITS_dir,FITS_slice,corruptflag, shift_amount,dp_perc): if dataflag == 1: image = TV_Split_utilities.generateSheppLogan(Phant_size) image_res = image.shape[0] thetas = np.linspace(0.,180.,theta_count, endpoint = False) image = np.expand_dims(image,axis = 2) sinogram = np.empty((image.shape[0],theta_count,image.shape[2])) for i in range(image.shape[2]): sinogram[:,:,i] = radon(image[:,:,i], thetas,circle = True) if corruptflag>0: sinogram[:,:,i] = TV_Split_utilities.add_deadpix( sinogram[:,:,i],dp_perc) if dataflag == 2: sinogram = TV_Split_utilities.FITS_to_sinos(FITS_dir,FITS_slice, theta_freq) sinores = sinogram.shape #Downsample ind = np.linspace(0,sinores[0]-1,num = (sinores[0]-1)/res_freq ).astype('int') sinogram = sinogram[ind,:] ind = np.linspace(0,sinores[1]-1,num = (sinores[1]-1)/theta_freq).astype('int') sinogram = sinogram[:,ind] sinogram = sinogram.astype(float) image_res = sinogram.shape[0] theta_count = sinogram.shape[1] thetas = np.linspace(0.,180.,theta_count, endpoint = False) if dataflag == 4: sinogram = TV_Split_utilities.tiff_sino_to_image_slice(TIFF_dir, TIFF_slice) sinores = sinogram.shape #Downsample ind = np.linspace(0,sinores[0]-1,num = (sinores[0]-1)/res_freq ).astype('int') sinogram = sinogram[ind,:] ind = np.linspace(0,sinores[1]-1,num = (sinores[1]-1)/theta_freq).astype('int') sinogram = sinogram[:,ind] sinogram = sinogram.astype(float) image_res = sinogram.shape[0] theta_count = sinogram.shape[1] thetas = np.linspace(0.,180.,theta_count, endpoint = False) #Normalize for all sinograms sinogram = sinogram/np.max(np.abs(sinogram)) return sinogram,thetas,image_res
def check_radon_center(shape, circle, dtype, preserve_range): # Create a test image with only a single non-zero pixel at the origin image = np.zeros(shape, dtype=dtype) image[(shape[0] // 2, shape[1] // 2)] = 1. # Calculate the sinogram theta = np.linspace(0., 180., max(shape), endpoint=False) sinogram = radon(image, theta=theta, circle=circle, preserve_range=preserve_range) assert sinogram.dtype == _supported_float_type(sinogram.dtype) # The sinogram should be a straight, horizontal line sinogram_max = np.argmax(sinogram, axis=0) print(sinogram_max) assert np.std(sinogram_max) < 1e-6
def _radon_costf(frame, cent, radint, coords): """ Radon cost function used in frame_center_radon(). """ frame_shifted = frame_shift(frame, coords[0], coords[1]) frame_shifted_ann = get_annulus(frame_shifted, radint, cent-radint) # theta = np.linspace(start=0., stop=360., num=frame_shifted_ann.shape[0], # endpoint=False) theta1 = np.linspace(start=35., stop=55., num=frame_shifted_ann.shape[0]/2) theta2 = np.linspace(start=125., stop=145., num=frame_shifted_ann.shape[0]/2) theta=np.concatenate((theta1,theta2)) sinogram = radon(frame_shifted_ann, theta=theta, circle=True) costf = np.sum(np.abs(sinogram[cent,:])) return costf
def test_radon_circle(): a = np.ones((10, 10)) with expected_warnings(['reconstruction circle']): radon(a, circle=True) # Synthetic data, circular symmetry shape = (61, 79) c0, c1 = np.ogrid[0:shape[0], 0:shape[1]] r = np.sqrt((c0 - shape[0] // 2)**2 + (c1 - shape[1] // 2)**2) radius = min(shape) // 2 image = np.clip(radius - r, 0, np.inf) image = _rescale_intensity(image) angles = np.linspace(0, 180, min(shape), endpoint=False) sinogram = radon(image, theta=angles, circle=True) assert np.all(sinogram.std(axis=1) < 1e-2) # Synthetic data, random image = _random_circle(shape) sinogram = radon(image, theta=angles, circle=True) mass = sinogram.sum(axis=0) average_mass = mass.mean() relative_error = np.abs(mass - average_mass) / average_mass print(relative_error.max(), relative_error.mean()) assert np.all(relative_error < 3.2e-3)
def error_at_dtheta(dtheta, ax=None, filter = "ramp"): dtheta = int(dtheta) theta = range(0,180,dtheta) sinogram = st.radon(phantom, theta, circle = False) rc_phantom = st.iradon(sinogram, theta, circle = False, filter = filter) error = rc_phantom - phantom rms = np.sqrt(np.mean(error**2)) if ax: ax.imshow(rc_phantom, cmap = plt.cm.Greys_r) ax.set_xlabel("{}˚".format(dtheta)) ax.set_xticks([]) ax.set_yticks([]) return rms
def mask_radon(im, step=1): ''' mask out values outside the inscribed circle to satisfy assumptions of radon() ''' image = np.copy(im) shape_min = min(image.shape) radius = shape_min // 2 img_shape = np.array(image.shape) coords = np.array( np.ogrid[:image.shape[0], :image.shape[1]], dtype=object) dist = ((coords - img_shape // 2) ** 2).sum(0) outside_reconstruction_circle = dist > radius ** 2 image[outside_reconstruction_circle] = 0 return radon(image, theta=np.arange(0, 180, step))
def test(): with mss.mss() as sct: monitor = {'top': 90, 'left': 0, 'width': 400, 'height': 220} last_time = time.time() img = np.array(sct.grab(monitor)) img = cv2.resize(img, (100, 100)) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) theta = np.linspace(0., 180., max(img.shape), endpoint=False) sinogram = radon(img, theta=theta, circle=False) reconstruction_fbp = iradon(sinogram, theta=theta, circle=False) img = np.array(reconstruction_fbp, dtype=np.int8) return img
def load_sinogram(): ''' Generates the sinogram of the Sheep Logan Phantom first loaded from skimage.data. - Ouput: sinogram - numpy.array that contains the contains the sinogram of the Shepp Logan Phantom. NOTE - the shape is [angle, position] ''' # Load the shepp logan phantom data slp_image = skimage.data.shepp_logan_phantom() # create the sinogram of the sheep logan phantom loaded from skimage sinogram = radon(slp_image) return sinogram
def radtra(file, downR): image = imread(file, as_grey=True) width, height = np.shape(image) imageSqsize = max(width, height) image = resize(image, (imageSqsize, imageSqsize), mode='constant') ###image = rescale(image, scale=0.8, mode='reflect') fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6)) ax1.set_title("Original") ax1.imshow(image, cmap=plt.cm.Greys_r) theta = np.linspace(0., 180., max(image.shape), endpoint=False) sinogram = radon(image, theta=theta, circle=False) sinogram = distortion(sinogram, downR, width) ax2.set_title("Radon transform\n(Sinogram)") ax2.set_xlabel("Projection angle (deg)") ax2.set_ylabel("Projection position (pixels)") ax2.imshow(sinogram, cmap=plt.cm.Greys_r, extent=(0, 360, 0, sinogram.shape[0]), aspect='auto') fig.tight_layout() plt.show() reconstruction_fbp = iradon(sinogram, theta=theta, circle=False) #scipy.misc.imsave(file.replace("images", "images_f_sinogram"), reconstruction_fbp) error = reconstruction_fbp - image error = 2 print('FBP rms reconstruction error: %.3g' % np.sqrt(np.mean(error**2))) imkwargs = dict(vmin=-0.2, vmax=0.2) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6), sharex=True, sharey=True, subplot_kw={'adjustable': 'box-forced'}) ax1.set_title("Reconstruction\nFiltered back projection") ax1.imshow(reconstruction_fbp, cmap=plt.cm.Greys_r) ax2.set_title("Reconstruction error\nFiltered back projection") ax2.imshow(image, cmap=plt.cm.Greys_r, **imkwargs) plt.show()
def check_radon_iradon(interpolation_type, filter_type): debug = False image = PHANTOM reconstructed = iradon(radon(image), filter=filter_type, interpolation=interpolation_type) delta = np.mean(np.abs(image - reconstructed)) print("\n\tmean error:", delta) if debug: _debug_plot(image, reconstructed) if filter_type in ("ramp", "shepp-logan"): if interpolation_type == "nearest": allowed_delta = 0.03 else: allowed_delta = 0.025 else: allowed_delta = 0.05 assert delta < allowed_delta
def run(self): for i in self.data_indices: im = EMData(args[0], i) radon_im = radon(im.numpy(), preserve_range=True) laplacian = blob_log(radon_im, threshold=options.rthreshold, min_sigma=options.rsigma) if len(laplacian) == 0: lines.append(0) else: lines.append(1) print( f"{i} out of {n} images analyzed" + ' ' * 20, end='\b' * (len(str(f"{i} out of {n} images analyzed")) + 20), flush=True)
def findline(img): """ Description: Find lines in an image. Linear Hough transform and Canny edge detection are used. Input: img - The input image. Output: lines - Parameters of the detected line in polar form. """ # Pre-processing #cv2.imshow('line',img) #cv2.waitKey(0) I2, orient = canny(img, 2, 0, 1) I3 = adjgamma(I2, 1.9) I4 = nonmaxsup(I3, orient, 1.5) edgeimage = hysthresh(I4, 0.2, 0.15) # Radon transformation theta = np.arange(180) R = radon(edgeimage, theta, circle=False) sz = R.shape[0] // 2 xp = np.arange(-sz, sz + 1, 1) # Find for the strongest edge maxv = np.max(R) if maxv > 25: i = np.where(R.ravel() == maxv) i = i[0] else: return np.array([]) R_vect = R.ravel() ind = np.argsort(-R_vect[i]) u = i.shape[0] k = i[ind[0:u]] y, x = np.unravel_index(k, R.shape) t = -theta[x] * np.pi / 180 r = xp[y] lines = np.vstack([np.cos(t), np.sin(t), -r]).transpose() cx = img.shape[1] / 2 - 1 cy = img.shape[0] / 2 - 1 lines[:, 2] = lines[:, 2] - lines[:, 0] * cx - lines[:, 1] * cy return lines
def _load_whole_data(current_version, file, dump_folder): hashstr = hashlib.sha256( ("".join(file) + current_version).encode()).hexdigest() dump_file = os.path.join(dump_folder, hashstr + ".h5") print(dump_file) rebuild_data = True if os.path.exists(dump_file): print("dump file existed") with h5py.File(dump_file, "r") as h5file: if "version" in list(h5file.keys()): if h5file["version"].value == current_version: rebuild_data = False print("rebuild_data", rebuild_data) if rebuild_data: data = [] mat_contents = sio.loadmat(file) gt = np.squeeze(mat_contents['data_gt']) sparse = np.zeros_like(gt) full = np.zeros_like(gt) for ind in range(gt.shape[2]): img = np.squeeze(gt[:, :, ind]) theta = np.linspace(0., 180., 1e3, endpoint=False) sinogram = radon(img, theta=theta, circle=False) theta_down = theta[0:1000:20] sparse[:, :, ind] = iradon(sinogram[:, 0:1000:20], theta=theta_down, circle=False) full[:, :, ind] = iradon(sinogram, theta=theta, circle=False) print("iteration : ", ind, "/", gt.shape[2]) norm_val = np.amax(sparse) print("norm_val", norm_val) print("finished rebuild") saveh5( { "label": full / norm_val * 255., "sparse": sparse / norm_val * 255., "version": current_version }, dump_file) f_handle = h5py.File(dump_file, "r") label = np.array(f_handle["label"]) sparse = np.array(f_handle["sparse"]) print("size of label, ", label.shape) print("size of sparse, ", sparse.shape)
def check_radon_iradon(interpolation_type, filter_type): debug = False image = PHANTOM reconstructed = iradon(radon(image, circle=False), filter=filter_type, interpolation=interpolation_type, circle=False) delta = np.mean(np.abs(image - reconstructed)) print('\n\tmean error:', delta) if debug: _debug_plot(image, reconstructed) if filter_type in ('ramp', 'shepp-logan'): if interpolation_type == 'nearest': allowed_delta = 0.03 else: allowed_delta = 0.025 else: allowed_delta = 0.05 assert delta < allowed_delta
def findangle(image, precision): firsttheta = 0 lasttheta = 180 stepangle = (lasttheta - firsttheta) / 25 while stepangle * 20 >= precision: theta = np.linspace(firsttheta, lasttheta, 25, endpoint=False) sinogram = radon(image, theta=theta, circle=True) diff = np.std(sinogram, axis=0) Mx = max(diff) diff = diff.tolist() num = diff.index(Mx) + 1 global angle angle = float(firsttheta) + (num * stepangle - stepangle / 2) firsttheta = angle - 2 * stepangle lasttheta = angle + 2 * stepangle stepangle = (lasttheta - firsttheta) / 25
def sirt_xin(sinogram_np, angles, numIter=10): # SIRT # print("--start sirt_xin---") recon_SIRT = iradon(sinogram_np, theta=angles, filter=None, circle=True) for i in range(0, numIter): reprojs = radon(recon_SIRT, theta=angles, circle=True) ratio = sinogram_np / reprojs ratio[np.isinf(ratio)] = 1e8 ratio[np.isnan(ratio)] = 1 timet = iradon(ratio, theta=angles, filter=None, circle=True) timet[np.isinf(timet)] = 1 timet[np.isnan(timet)] = 1 recon_SIRT = recon_SIRT * timet # print('SIRT %.3g' % i) # plt.imshow(recon_SIRT, cmap=plt.cm.Greys_r) # plt.show() return recon_SIRT
def check_radon_iradon(interpolation_type, filter_type): debug = False image = PHANTOM reconstructed = iradon(radon(image, circle=False), filter=filter_type, interpolation=interpolation_type) delta = np.mean(np.abs(image - reconstructed)) print('\n\tmean error:', delta) if debug: _debug_plot(image, reconstructed) if filter_type in ('ramp', 'shepp-logan'): if interpolation_type == 'nearest': allowed_delta = 0.03 else: allowed_delta = 0.025 else: allowed_delta = 0.05 assert delta < allowed_delta
def radfil(im,radiance,arange=10,mutemet='hann'): (lx,ly)=im.shape minang=max(radiance-arange,0) maxang=min(radiance+arange,180) print "Muting=",minang,"to",maxang,"\nSize of chunk to process",lx,ly #Forward Radon Transform print "\nStarting Radon transform" #The transform is "squared" theta = np.linspace(0., 180., max(im.shape), endpoint=False) radt=radon(im,theta=theta) print "...radon done.\n" #__________________________________________________________________ disptrans(im,radt) #__________________________________________________________________ #Mute in the radon domain print "\nMuting in the radon domain...\n" sf=float(radt.shape[1]/180.0) #scale factor for the angles mina=int(minang*sf) maxa=int(maxang*sf) for angle in range(mina,maxa): for ori in range(0,int(radt.shape[0])-1): #choose amongst 3 different ways to mute if mutemet=='door': radt[ori,angle]=0 elif mutemet=='gauss': radt[ori,angle]=radt[ori,angle]*gauss(angle,mina,maxa) else: radt[ori,angle]=radt[ori,angle]*hann(angle,mina,maxa) #__________________________________________________________________ print "Starting Inverse Radon transform...\n" iradt=iradon(radt,theta=theta) print "...Inverse radon done.\n" #__________________________________________________________________ disptrans(iradt,radt) #__________________________________________________________________ if(lx<ly): pad=int(ly-lx)/2 return iradt[pad:lx+pad,:] else: pad=int(lx-ly)/2 return iradt[:,pad:ly+pad]
def test_iradon_bias_circular_phantom(): """ test that a uniform circular phantom has a small reconstruction bias """ pixels = 128 xy = np.arange(-pixels / 2, pixels / 2) + 0.5 x, y = np.meshgrid(xy, xy) image = x**2 + y**2 <= (pixels/4)**2 theta = np.linspace(0., 180., max(image.shape), endpoint=False) sinogram = radon(image, theta=theta) reconstruction_fbp = iradon(sinogram, theta=theta) error = reconstruction_fbp - image tol = 5e-5 roi_err = np.abs(np.mean(error)) assert( roi_err < tol )
def __init__(self, file_name, target_size=128, n_theta=50, stdev=0.1, relative_location=""): super().__init__(file_name, target_size, stdev, relative_location) self.n_theta = n_theta self.theta = np.linspace(0., 180., self.n_theta, endpoint=False) self.n_r = self.dim self.r = np.linspace(-0.5, 0.5, self.n_r) self.pure_sinogram = cp.asarray( radon(cp.asnumpy(self.target_image), self.theta, circle=True)) self.sinogram = self.pure_sinogram + self.stdev * cp.random.randn( self.pure_sinogram.shape[0], self.pure_sinogram.shape[1]) self.y = self.sinogram.ravel(ORDER) / self.stdev self.num_sample = self.y.size self.v = self.pure_sinogram.ravel(ORDER) / self.stdev
def line_detect(): im = data.text() seg = im < 100 r = transform.radon(seg) rho, theta = np.unravel_index(np.argmax(r), r.shape) rho = rho - r.shape[0] / 2 x = np.int(rho * np.cos((theta + 90) * np.pi / 180) + im.shape[0] / 2) y = np.int(rho * np.sin((theta + 90) * np.pi / 180) + im.shape[1] / 2) dx = np.cos((theta) * np.pi / 180) dy = np.sin((theta) * np.pi / 180) l = 1000 res = im.copy() cv2.line(res, (np.int(y - dy * l), np.int(x - dx * l)), (np.int(y + dy * l), np.int(x + dx * l)), 255, 2) io.imsave('text.png', im) io.imsave('text-line.png', res)
def test_iradon_bias_circular_phantom(): """ test that a uniform circular phantom has a small reconstruction bias """ pixels = 128 xy = np.arange(-pixels / 2, pixels / 2) + 0.5 x, y = np.meshgrid(xy, xy) image = x**2 + y**2 <= (pixels / 4)**2 theta = np.linspace(0., 180., max(image.shape), endpoint=False) sinogram = radon(image, theta=theta) reconstruction_fbp = iradon(sinogram, theta=theta) error = reconstruction_fbp - image tol = 5e-5 roi_err = np.abs(np.mean(error)) assert roi_err < tol
def rotation(image): if len(image.shape) < 3: img = image I = img elif len(image.shape) == 3: img = image I = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) h, w = I.shape if (w > 640): I = cv2.resize(I, (640, int((h / w) * 640))) I = I - np.mean(I) sinogram = radon(I) r = np.array( [np.sqrt(np.mean(np.abs(line)**2)) for line in sinogram.transpose()]) rotation = np.argmax(r) M = cv2.getRotationMatrix2D((w / 2, h / 2), 90 - rotation, 1) angle = 90 - rotation return angle
def get_random_xy(size=20, keep_threshole=0.99, n_project=180): image = np.random.rand(size, size) for x in range(size): for y in range(size): rx = x - size / 2 ry = y - size / 2 r = size / 2 - 1 if (rx * rx + ry * ry) > r * r: image[x][y] = 0. elif image[x][y] > keep_threshole: image[x][y] = 1. else: image[x][y] = 0. theta = np.linspace(0., 180., n_project, endpoint=False) sinogram = radon(image, theta=theta, circle=True) ''' fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5)) ax1.set_title("Original") ax1.imshow(image, cmap=plt.cm.Greys_r) ax2.set_title("Radon transform\n(Sinogram)") ax2.set_xlabel("Projection angle (deg)") ax2.set_ylabel("Projection position (pixels)") ax2.imshow(sinogram, cmap=plt.cm.Greys_r, extent=(0, 180, 0, sinogram.shape[0]), aspect='auto') fig.tight_layout() plt.show() reconstruction_fbp = iradon_sart(sinogram, theta=theta) error = reconstruction_fbp - image print('FBP rms reconstruction error: %.3g' % np.sqrt(np.mean(error**2))) imkwargs = dict(vmin=-0.2, vmax=0.2) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5), sharex=True, sharey=True, subplot_kw={'adjustable': 'box-forced'}) ax1.set_title("Reconstruction\nFiltered back projection") ax1.imshow(reconstruction_fbp, cmap=plt.cm.Greys_r) ax2.set_title("Reconstruction error\nFiltered back projection") ax2.imshow(reconstruction_fbp - image, cmap=plt.cm.Greys_r, **imkwargs) ''' return iradon_sart(sinogram, theta=theta), image
def PD_denoise(sinogram,rec_FBP,thetas,outerloops,innerloops, CGloops,image_res,convtestnorm,lambdapen,slicenum): """ Solves the problem via the following formulation. We minimize F(Ku)+G(u), where K:= (grad,R)^T and F(x):= ||x_1||_1+lambda/2||x_2-g||^2, and G(u):=0. Then, F^*(y) = \delta_p(y_1)+1/(2lambda)||y_2||^2+<g,y_2>. We then perform the primal dual algorithm of Chambolle-Pock '11. We assume it is better to have repeated G evaluations and fewer thing stored. Do not use; needs significant tuning/possible debugging. """ uk = (TV_Split_utilities.generateSheppLogan(Phant_size)) radius = min(uk.shape) // 2 c0, c1 = np.ogrid[0:uk.shape[0], 0:uk.shape[1]] Circle_Mask = ((c0 - uk.shape[0] // 2) ** 2+ (c1 - uk.shape[1] // 2) ** 2) Circle_Mask = Circle_Mask <= 0.95*(radius ** 2) Circle_Mask = np.matrix(Circle_Mask) uk[0==Circle_Mask]=0. y_onek = np.gradient(0.*uk) y_twok = 0.*sinogram sigma = 1.e-2 tau = 1.e-2 theta = 1. ubark = uk Err_diff = np.zeros((int(.5*rec_FBP.size))) for i in range(int(.5*rec_FBP.size)): y_onek[0],y_onek[1], y_twok = resolvent_Fstar(y_onek[0]+sigma* grad_one(ubark),y_onek[1]+sigma*grad_two(ubark), y_twok+sigma*radon(ubark,thetas,circle=True),sigma,lambdapen, sinogram) ubark = (1+theta)*resolvent_G(uk+tau*(-1.*Divu(y_onek)+iradon(y_twok, thetas,output_size=image_res,circle=True,filter = 'ramp' )))-theta*uk ubark[0==Circle_Mask]=0. uk = resolvent_G(uk-tau*(-1.*Divu(y_onek)+iradon(y_twok, thetas,output_size=image_res,circle=True,filter = 'ramp' ))) uk[0==Circle_Mask]=0. Err_diff[i] = np.linalg.norm((ubark-uk)/theta) plt.imshow(uk);plt.pause(.0001) print('Slice %d]' %(slicenum)) print('Outer Iterate = ' ,i) print('Update = ' ,Err_diff[i]) if Err_diff[i]<1.e-5: break return uk,Err_diff
def computeR(image, vis): # === Check if image properties: type & range if image.dtype == "uint8": image = image.astype(float) / np.max(image) # Number of channels: 3channels to 1channel if needed if len(image.shape) > 2: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray = image sinogram = radon(gray, theta=theta) # , circle=True)# # === R_transform R = np.zeros(N) # R_transform for i in xrange(N): a = sinogram[:, i] R[i] = a.sum() Rn = R / np.max(R) # normalized R transform if vis: print "Displaying image and its r and R transforms" import matplotlib.pyplot as plt plt.figure(figsize=(8, 5)) plt.subplot(121) plt.title("Radon(r) transform\n(Sinogram)") plt.xlabel("Projection Angle (theta) [degree]") plt.ylabel("Projection Position (rho) [pixels]") plt.imshow( sinogram, cmap=plt.cm.Greys_r, # hot, extent=(0, 180, 0, sinogram.shape[0]), aspect='auto') plt.subplot(122) plt.title("R-transform\nR(normalized)") plt.xlabel("Projection Angle (theta) [degree]") plt.ylabel("Projection Position (rho) [pixels]") plt.plot(theta, Rn) plt.subplots_adjust(hspace=0.4, wspace=0.5) cv2.imshow("image to R transform", np.uint8(image * 255)) plt.show() cv2.waitKey(10) plt.close() return Rn
def filtered_backprojection(img, filter_name, L_name, L_value, save_dir): theta_values = np.arange(60) * 3 sinogram = radon(img, theta=theta_values, circle=False) sinogram_filtered = my_filter(sinogram, filter_name, L_value) # coeff = 1 if filter_name is None else 0.5 img_recon = 0.5 * iradon( sinogram_filtered, theta=theta_values, filter_name=None, circle=False) plot(img_recon, title='Reconstructed Image. Filter = {}, L = {}'.format( filter_name, L_name), save_path=os.path.join( save_dir, 'recon_filter_{}_L_{}.png'.format(filter_name, L_name))) rrmse = get_rrmse(img, img_recon) return rrmse
def clean(self, cctol=None): """ Apply a tolerance in cor-coeff on projections to kill the worst ones (should work) """ # scalc is "self-consistent", just reverse transform scalc = radon(self.recon, self.angles, circle=True).T # Scor each angle project to see how well it fits scors = np.array([ np.corrcoef(self.sinogram[i], scalc[i])[1, 0] for i in range(len(self.angles)) ]) # apply a correlation coefficient cutoff if cctol is None: pl.subplot(121) pl.plot(self.angles, scors, "o") pl.subplot(122) pl.hist(scors, np.linspace(0, 1, len(scors) / 10)) pl.show() # might change of py3/py2 cctol = float(input("Enter cut off for cctol: ")) io = self.io # i_omega indices of peaks to sinogram msk = np.zeros(len(io), np.bool) for i in range(len(self.angles)): if scors[i] < cctol: # remove msk = msk | (io == i) # filter peak list according to masking self.pkid = self.pkid[msk] self.io = self.io[msk] self.iy = self.iy[msk] self.hkle = self.hkle[msk] recon_mask = scors > cctol # FIXME = remove pkid or add a used / not used mask self.sinogram = self.sinogram[recon_mask] self.angles = self.angles[recon_mask] self.run_iradon()
def process_image(image, with_fragment=False): sinogram = radon(image, circle=False) print_min_max_shape(image, 'image') print_min_max_shape(sinogram, 'sinogram') plot_two_images(image, sinogram, 'image', 'sinogram') recon_image = iradon(sinogram) recon_image_sart = iradon_sart(sinogram) print_min_max_shape(recon_image, 'recon_image') print_min_max_shape(recon_image_sart, 'recon_image_sart') plot_two_images(recon_image, recon_image_sart, 'recon_image', 'recon_image_sart') if with_fragment: plot_two_images(recon_image[23:119, 23:119], recon_image_sart[23:119, 23:119], 'recon_image fragment', 'recon_image_sart fragment') return recon_image, recon_image_sart
def computeR(image, vis): # === Check if image properties: type & range if image.dtype == "uint8": image = image.astype(float)/np.max(image) # Number of channels: 3channels to 1channel if needed if len(image.shape) > 2: gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) else: gray = image # sinogram = radon(gray, theta=theta)#, circle=True)# # === R_transform R = np.zeros(N) # R_transform for i in xrange(N): a = sinogram[:,i] R[i] = a.sum() Rn = R/np.max(R) # normalized R transform # if vis: print "Displaying image and its r and R transforms" import matplotlib.pyplot as plt plt.figure(figsize=(8, 5)) plt.subplot(121) plt.title("Radon(r) transform\n(Sinogram)") plt.xlabel("Projection Angle (theta) [degree]") plt.ylabel("Projection Position (rho) [pixels]") plt.imshow(sinogram, cmap = plt.cm.Greys_r,#hot, extent=(0,180,0,sinogram.shape[0]), aspect='auto') plt.subplot(122) plt.title("R-transform\nR(normalized)") plt.xlabel("Projection Angle (theta) [degree]") plt.ylabel("Projection Position (rho) [pixels]") plt.plot(theta, Rn) plt.subplots_adjust(hspace=0.4, wspace=0.5) cv2.imshow("image to R transform", np.uint8(image*255)) plt.show() cv2.waitKey(10) plt.close() return Rn
def scikit_radon_forward(volume, geometry, range, out=None): """Calculate forward projection using scikit Parameters ---------- volume : `DiscreteLpElement` The volume to project geometry : `Geometry` The projection geometry to use range : `DiscreteLp` range of this projection (sinogram space) out : ``range`` element, optional An element in range that the result should be written to Returns ------- sinogram : ``range`` element Sinogram given by the projection. """ # Check basic requirements. Fully checking should be in wrapper assert volume.shape[0] == volume.shape[1] theta = scikit_theta(geometry) scikit_range = scikit_sinogram_space(geometry, volume.space, range) sinogram = scikit_range.element(radon(volume.asarray(), theta=theta).T) if out is None: out = range.element() out.sampling(clamped_interpolation(scikit_range, sinogram)) scale = volume.space.cell_sides[0] out *= scale return out
import matplotlib.pyplot as plt from skimage.io import imread from skimage import data_dir from skimage.transform import radon, rescale image = imread(data_dir + "/phantom.png", as_grey=True) image = rescale(image, scale=0.4) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5)) ax1.set_title("Original") ax1.imshow(image, cmap=plt.cm.Greys_r) theta = np.linspace(0., 180., max(image.shape), endpoint=False) sinogram = radon(image, theta=theta, circle=True) ax2.set_title("Radon transform\n(Sinogram)") ax2.set_xlabel("Projection angle (deg)") ax2.set_ylabel("Projection position (pixels)") ax2.imshow(sinogram, cmap=plt.cm.Greys_r, extent=(0, 180, 0, sinogram.shape[0]), aspect='auto') fig.subplots_adjust(hspace=0.4, wspace=0.5) plt.show() """ .. image:: PLOT2RST.current_figure Reconstruction with the Filtered Back Projection (FBP) ======================================================
count = args.count niter = args.niter nsub = args.nsub sfwhm = args.filter beta = args.beta median = args.median # shepp-logan phantom image = imread(data_dir + "/phantom.png", as_grey=True) image = rescale(image, 0.4) shape = image.shape # sinogram theta = np.linspace(0., 180., max(image.shape), endpoint=False) sinogram = radon(image, theta=theta, circle=True) # add noise if count > 0: val = sinogram.sum() sinogram = np.random.poisson(sinogram / val * count).astype(np.float) sinogram *= val / count # normalization matrix nview = len(theta) norm = np.ones(shape) wgts = [] for sub in xrange(nsub): views = range(sub, nview, nsub) wgt = iradon(norm[:, views], theta=theta[views], filter=None, circle=True) wgts.append(wgt)
# Setup simulation parameters (partR, simdir, tstart) = simParams(sys) nparts = float(simdir.partition('/')[0]) # Setup directory structures #(root, simdir, datadir, imgdir) = directoryStructureDevel(simdir) (root, simdir, datadir, imgdir) = directoryStructureMarcc(simdir) # Get time and z data (time, tsInd, nt, evalZ, nz) = initData(datadir, tstart) # Print simulation data printSimulationData(partR, root, simdir, datadir) # Find output data -- each column is a different time vFracFile = datadir + "volume-fraction" vFrac = np.genfromtxt(vFracFile).T[:,tsInd:] # Subtract mean vFrac -= nparts*(4./3.)*np.pi*(2.1**3.)/(42.*42.*126.) sinogram = radon(vFrac) ## Save Data to File savefile = datadir + "radon-xform" with open(savefile, 'wb') as outfile: out = csv.writer(outfile, delimiter=' ') out.writerows(sinogram) print "\n ...Done!"
def test_reconstruct_with_wrong_angles(): a = np.zeros((3, 3)) p = radon(a, theta=[0, 1, 2]) iradon(p, theta=[0, 1, 2]) assert_raises(ValueError, iradon, p, theta=[0, 1, 2, 3])
def argmax(x): return parabolic(x, numpy.argmax(x))[0] except ImportError: from numpy import argmax filename = '../../public/images/skew-linedetection.png' # Load file, converting to grayscale I = asarray(Image.open(filename).convert('L')) I = I - mean(I) # Demean; make the brightness extend above and below zero plt.subplot(2, 2, 1) plt.imshow(I) # Do the radon transform and display the result sinogram = radon(I) plt.subplot(2, 2, 2) plt.imshow(sinogram.T, aspect='auto') plt.gray() # Find the RMS value of each row and find "busiest" rotation, # where the transform is lined up perfectly with the alternating dark # text and white lines r = array([rms_flat(line) for line in sinogram.transpose()]) rotation = argmax(r) print('Rotation: {:.2f} degrees'.format(90 - rotation)) plt.axhline(rotation, color='r') # Plot the busy row row = sinogram[:, rotation]
from skimage.transform import radon import pylab as pyl import tomopy_peri.tomopy # SIMULATED TOMO DATA #--------------------- p = 128 n_projections = 200 emission = True iters = 1 simulate_misaligned_projections = False theta = np.linspace(0,180,num=n_projections,endpoint=True) msl = phantom.modified_shepp_logan((p,p,p)) data = np.zeros((1, n_projections, p, p)) for i in range(p): data[0,:,i,:] = np.rollaxis(radon(msl[:,i,:], theta=theta, circle=True),1,0) if simulate_misaligned_projections: for i in range(n_projections): sx, sy = 3*(np.random.random()-0.5), 3*(np.random.random()-0.5) data[0,i,:,:]=spni.shift(data[0,i,:,:], (sx, sy)) d = tomopy.xftomo_dataset(data=data, theta=theta, channel_names=['Modified Shepp-Logan'], log='debug') tomopy.xftomo_writer(d.data, channel=0, output_file='/tmp/projections/projection_{:}_{:}.tif') if simulate_misaligned_projections: d.align_projections(output_gifs=True, output_filename='/tmp/projections.gif') d.align_projections(output_gifs=True, output_filename='/tmp/projections.gif') d.diagnose_center() d.optimize_center()