def test1(): ## Pick up a random number in [0,256] and make sure it is even n = np.int(np.random.rand(1) * 1024) if n == 0: n = 20 if n % 2 != 0: n += 1 print("Number of pixels: ", n) ## Construct an array of random angles in rad a = np.random.random(n).astype(myfloat) ## Construct a random object y1 = np.random.random((n, n)).astype(myfloat) ## Construct a random sinogram x2 = np.random.random((n, n)).astype(myfloat) ## Load gridding projectors tp = cpj.projectors(n, a, ctr=0.0) ## Create A^{T}y x1 = tp.At(y1) ## Create Ax y2 = tp.A(x2) ## Compute inner product < A^{T}y , x > inn_prod = np.sum(np.conjugate(x2) * x1) ## Compute inner product < y , Ax > inn_prod = np.sum(np.conjugate(y2) * y1) print("< b , Tt( a ) > = ", inn_prod) print("< T( b ) , a > = ", inn_prod)
def multi_thread(pathin, pathout, filein, args, ii): sino = io.readImage(pathin + filein).astype(myfloat) nang, npix = sino.shape angles = utils.create_projection_angles(nang) tp = cpj.projectors(npix, angles, args=args) reco = tp.fbp(sino) if args.edge_pad: i1 = ii[0] i2 = ii[2] reco = reco[i1:i2, i1:i2] save_reconstruction(pathout, filein, args, reco)
def test4(sino): ## Get sinogram size nang, n = sino.shape ## Create array of 200 angularly equispaced angles in [0,180) (degrees) a = np.arange(nang) * 180.0 / nang ## Compute non-filtered backprojection tp = cpj.projectors(n, a, ctr=0.0, filt="hann") reco = tp.fbp(sino) return reco
def test2(): ## Read Shepp-Logan image in folder "../data/" image = io.readImage("../data/shepp_logan_pix0256.DMP") n = image.shape[0] ## Create array of 200 angularly equispaced angles in [0,180) (degrees) nang = 402 a = np.arange(nang) * 180.0 / nang ## Compute forward projection tp = cpj.projectors(n, a, ctr=0.0) sino = tp.A(image) return sino
def main(): ## Initial print print('\n') print('########################################################') print('############# REGRIDDING BACKPROJECTION #############') print('########################################################') print('\n') ## Get the startimg time of the reconstruction time1 = time.time() ## Get input arguments args = getArgs() ## Get input/output directory pathin, pathout = utils.get_io_path(args) print('\nInput path:\n', pathin) print('\nOutput path:\n', pathout) ## Get input files file_list, file1, nimg, ext = utils.get_input(args, pathin) print('\nNumber of input files: ', nimg) print('Extension of the files: ', ext) ## Read first sinogram sino = io.readImage(pathin + file1).astype(myfloat) nang, npix = sino.shape print('\nSinogram to reconstruct:\n', file1) print('Number of projection angles: ', nang) print('Number of pixels: ', npix) if args.plot is True: dis.plot(sino, 'Input sinogram') ## Getting projection geometry if args.geometry == '0': print( '\nDealing with equiangular projections distributed between 0 and' + ' 180 degrees ---> [0,180)') angles = utils.create_projection_angles(nang) else: print('\nReading list of projection angles:\n', pathin + args.geometry) angles = utils.create_projection_angles(textfile=pathin + args.geometry) ## Set center of rotation axis if args.ctr == None: ctr = 0.0 print('Center of rotation axis placed at pixel: ', npix * 0.5) else: if args.ctr == -1: ctr = proc.search_rot_ctr(sino, None, 'a') print('Center of rotation axis placed at pixel: ', ctr) else: ctr = args.ctr print('Center of rotation axis placed at pixel: ', ctr) if args.dbp is True: sino[:, :] = proc.sino_correct_rot_axis(sino, ctr) print('Center of rotation corrected') ctr = 0.0 ## Enable edge padding if args.edge_pad is True: sino = proc.sino_edge_padding(sino, 0.5).astype(myfloat) i1 = int((sino.shape[1] - npix) * 0.5) i2 = i1 + npix npix = sino.shape[1] if ctr != 0.0: ctr += i1 if args.plot is True: dis.plot(sino, 'Edge padded sinogram') else: i1 = 0 i2 = npix ## External sinogram filtering if args.filt == 'ramp-ext' or args.filt == 'conv-ext': if filt == 'ramp-ext': sino = fil.filter_fft(sino, 'ramp') elif filt == 'conv-ext': sino = fil.filter_convolve(sino) sino *= 4.0 / myfloat(npix) args.filt = 0 ## Differential sinogram fo DBP if args.dbp is True: print('\nDifferential backprojection enabled') print( 'Computing differential sinogram by means of Savitzky-Golay method' ) print('Savizky-Golay window length: ', args.sg) sino[:, :] = proc.diff_sino_savitzky_golay(sino, window_size=args.sg) if args.plot is True: dis.plot(sino, 'Differential sinogram') ## Initialize projectior class tp = cpj.projectors(npix, angles, ctr=ctr, args=args) ## Apply forward projection operator time_rec1 = time.time() reco = tp.fbp(sino) time_rec2 = time.time() ## Crop reconstruction if args.edge_pad: reco = reco[i1:i2, i1:i2] ## Display reconstruction if args.plot is True: dis.plot(reco, 'Reconstruction') ## Save reconstruction save_reconstruction(pathout, file1, args, reco) ## Reconstruct sinograms from all the other images in the stack if args.filein is None: pool = mproc.Pool() for i in range(1, nimg): pool.apply_async( multi_thread, (pathin, pathout, file_list[0][i], args, [i1, i2])) pool.close() pool.join() time2 = time.time() print('\nTime elapsed to run the 1st backward gridrec: ', time_rec2 - time_rec1) print('Total time elapsed for the run of the program: ', time2 - time1) print('\n') print('##############################################') print('#### REGRIDDING BACKPROJECTION DONE ! ####') print('##############################################') print('\n')
def admm(b, a, param): ## Get number of pixels and angles m, n, nz = param.nang, param.npix_op, param.nz b = np.array(b).astype(myfloat) rd = param.radon_degree ## Init forward and back-projector if param.projector == 'grid-pswf': tp = cpj1.projectors(n, a, kernel='pswf', oversampl=2.0, radon_degree=rd) elif param.projector == 'grid-kb': tp = cpj1.projectors(n, a, kernel='kb', oversampl=1.5, W=6.6, errs=6.0e-6, interp='lin', radon_degree=rd) elif param.projector == 'bspline': tp = cpj2.projectors(n, a, param, bspline_degree=3, proj_support_y=4, radon_degree=rd) elif param.projector == 'radon': tp = cpj2.projectors(n, a, param, bspline_degree=1, proj_support_y=2, radon_degree=rd) elif param.projector == 'pix-driv': tp = cpj3.projectors(n, a, oper='pd') elif param.projector == 'ray-driv': tp = cpj3.projectors(n, a, oper='rd') elif param.projector == 'dist-driv': tp = cpj3.projectors(n, a, oper='dd') elif param.projector == 'slant': tp = cpj3.projectors(n, a, oper='ss') ## Initialize x x = np.ones((nz, n, n), dtype=myfloat) if param.init_object is True: i1 = param.index_start i2 = param.index_end x_new = [] b_new = [] for i in range(nz): x[i, :, :] = tp.fbp(b[i, :, :]) if param.plot is True: dis.plot(x[i, :, :], 'Initialization') ## Reconstruction with CG if param.reg == 'cg': x[:], info = conj_grad(x, b, tp, param) ## Reconstruction with Lasso-L1 elif param.reg == 'lasso': x[:], info = lasso_l1(x, b, tp, param) ## Reconstruction with Lasso-TV elif param.reg == 'lasso-tv': x[:], info = lasso_tv(x, b, tp, param) ## Reconstruction with Plug-and-Play else: x[:], info = plug_and_play(x, b, tp, param) ## Conversion for bspline reconstruction and rotate if param.projector == 'bspline': for i in range(nz): x[i, :, :] = bfun.convert_from_bspline_to_pixel_basis( x[i, :, :], 3) x[:, :, :] = x[:, ::-1, ::-1] return x, info
def sir(b, a, param): ## Get number of pixels and angles m, n, nz = param.nang, param.npix_op, param.nz b = np.array(b).astype(myfloat) ## Init forward and back-projector if param.projector == 'grid-pswf': tp = cpj1.projectors(n, a, kernel='pswf', oversampl=2.0) elif param.projector == 'grid-kb': tp = cpj1.projectors(n, a, kernel='kb', oversampl=1.5, W=6.6, errs=6.0e-6, interp='lin') elif param.projector == 'bspline': tp = cpj2.projectors(n, a, param, bspline_degree=3, proj_support_y=4) elif param.projector == 'radon': tp = cpj2.projectors(n, a, param, bspline_degree=1, proj_support_y=2) elif param.projector == 'pix-driv': tp = cpj3.projectors(n, a, oper='pd') elif param.projector == 'ray-driv': tp = cpj3.projectors(n, a, oper='rd') elif param.projector == 'dist-driv': tp = cpj3.projectors(n, a, oper='dd') elif param.projector == 'slant': tp = cpj3.projectors(n, a, oper='ss') ## Initialize x x = np.ones((nz, n, n), dtype=myfloat) if param.init_object is True: i1 = param.index_start i2 = param.index_end x_new = [] b_new = [] for i in range(nz): x[i, :, :] = tp.fbp(b[i, :, :]) if param.plot is True: dis.plot(x[i, :, :], 'Initialization') ## Reconstruction with CG if param.algorithm == 'em': print('\n\nUsing Maximum-Likelihood Expectation-Maximization') x[:], info = em(x, b, tp, param) ## Reconstruction with Lasso-L1 elif param.algorithm == 'sps': print('\n\nUsing Separable Paraboloidal Surrogate') x[:], info = sps(x, b, tp, param) ## Conversion for bspline reconstruction and rotate if param.projector == 'bspline': for i in range(nz): x[i, :, :] = bfun.convert_from_bspline_to_pixel_basis( x[i, :, :], 3) x[:, :, :] = x[:, ::-1, ::-1] return x, info
def main(): ## Initial print print('\n') print('###########################################################') print('############# FORWARD REGRIDDING PROJECTOR #############') print('###########################################################') print('\n') ## Get the startimg time of the reconstruction time1 = time.time() ## Get input arguments args = getArgs() ## Get input/output directory pathin, pathout = utils.get_io_path(args) print('\nInput path:\n', pathin) print('\nOutput path:\n', pathout) ## Get input files file_list, file1, nimg, ext = utils.get_input(args, pathin) print('\nNumber of input files: ', nimg) print('Extension of the files: ', ext) ## Read first image image = io.readImage(pathin + file1).astype(myfloat) npix = image.shape[0] print('\nFirst image to forward project: ', file1) print('Number of pixels: ', npix) if args.plot is True: dis.plot(image, 'Input image') ## Get projection angles if args.geometry == '0' or args.geometry == '1': nang = args.nang angle_type = myint(args.geometry) if args.angle_range.find(':') == -1 or args.geometry == -1: angle_start = myfloat(args.angle_range) angle_end = angle_start + 180.0 else: angle_aux = args.angle_range.find(':') angle_start = myfloat(angle_aux[0]) angle_end = myfloat(angle_aux[1]) angles = utils.create_projection_angles(nang, angle_start, angle_end) else: angles = utils.create_projection_angles(pathin + args.geometry) nang = len(angles) print('\nNumber of views: ', nang) print('Selected angle range: [ ', angle_start, ' , ', angle_end, ' )') print('Angles:\n', angles) ## Initialize projectior class tp = cpj.projectors(npix, angles, args=args) ## Apply forward projection operator time_rec1 = time.time() sino = tp.A(image) time_rec2 = time.time() ## Display sinogram if args.plot is True: dis.plot(sino, 'Sinogram') ## Save sinogram save_sinogram(pathout, file1, angles, args, sino) ## Create sinograms from all the other images in the stack if args.filein is None: pool = mproc.Pool() for i in range(1, nimg): pool.apply_async(multi_thread, (pathin, pathout, file_list[0][i], angles, args)) pool.close() pool.join() time2 = time.time() print('\nTime elapsed to run the 1st forward gridrec: ', time_rec2 - time_rec1) print('Total time elapsed for the run of the program: ', time2 - time1) print('\n') print('#######################################') print('#### FORWARD PROJECTION DONE ! ####') print('#######################################') print('\n')
def multi_thread(pathin, pathout, filein, angles, args): image = io.readImage(pathin + filein).astype(myfloat) npix = image.shape[0] tp = cpj.projectors(npix, angles, args=args) sino = tp.A(image) save_sinogram(pathout, filein, angles, args, sino)
def main(): ## Initial print print('\n') print('########################################################') print('#### CREATE VIRTUAL SINOGRAM ####') print('########################################################') print('\n') ## Get arguments args = getArgs() ## Get input/output directory pathin , pathout = utils.get_io_path( args ) print('\nInput path:\n', pathin) print('\nOutput path:\n', pathout) ## Get input files file_list , file1 , nimg , ext = utils.get_input( args , pathin ) print('\nNumber of input files: ' , nimg) print('Extension of the files: ', ext) ## Read first sinogram sino = io.readImage( pathin + file1 ).astype( myfloat ) nang , npix = sino.shape print('\nSinogram to reconstruct:\n', file1) print('Number of projection angles: ', nang) print('Number of pixels: ', npix) if args.plot is True: dis.plot( sino , 'Input sinogram' ) ## Set center of rotation axis if args.ctr == None: ctr = 0.0 print('Center of rotation axis placed at pixel: ', npix * 0.5) else: ctr = args.ctr print('Center of rotation axis placed at pixel: ', ctr) ## Enable edge-padding if args.edge_pad is True: sino = proc.sino_edge_padding( sino , 0.5 ).astype( myfloat ) i1 = int( ( sino.shape[1] - npix ) * 0.5 ) i2 = i1 + npix npix = sino.shape[1] if ctr != 0.0: ctr += i1 if args.plot is True: dis.plot( sino , 'Edge padded sinogram' ) else: i1 = 0 i2 = npix ## Prepare projectors ang = np.arange( nang ) * 180.0 / myfloat( nang ) tp = cpj.projectors( npix , ang , kernel='kb' , oversampl=2.32 , W=6.6 , errs=6.0e-6 , interp='lin' , radon_degree=0 , filt=args.filt , ctr=ctr ) ## Reconstruct reco = tp.fbp( sino ) if args.plot is True: dis.plot( reco , 'Reconstruction' ) #reco = reco[i1:i2,i1:i2] ## Zero-out pixels outside resolution circle reco_new = reco.copy(); reco_new[:] = 0.0 io.writeImage( 'reco.DMP' , reco[i1:i2,i1:i2] ) reco_new[i1:i2,i1:i2] = utils.resol_circle_constr( reco[i1:i2,i1:i2] ) reco[:] = reco_new[:] if args.plot is True: dis.plot( reco , 'Constrained reconstruction' ) io.writeImage( 'reco_circle.DMP' , reco ) ## Background equalization reco[:] = background_equalization( reco ) if args.plot is True: dis.plot( reco , 'Equalized reconstruction' ) io.writeImage( 'reco_equaliz.DMP' , reco ) ## Forward projection nang_new = np.int( npix * np.pi / 2.0 ) ang_new = np.arange( nang_new ) * 180.0 / np.float32( nang_new ) tp = cpj.projectors( npix , ang_new , kernel='kb' , oversampl=2.32 , W=6.6 , errs=6.0e-6 , interp='lin' , radon_degree=0 ) sino = tp.A( reco ) #sino = sino[:,i1:i2] if args.plot is True: dis.plot( sino , 'Forward projection' ) io.writeImage( 'sino_circle.DMP' , sino ) ## Save output file if args.fileout is None: filein = args.filein extension = filein[len(filein)-4:] fileout = filein[:len(filein)-4] + '_virt.tif' else: fileout = args.fileout io.writeImage( pathout + fileout , sino ) print( '\nWritten output file:\n' , pathout + fileout )
def main(): ## Initial print print('\n') print('##################################################################') print('############# TOMOGRAPHIC GRIDDING RECONSTRUCTION #############') print('##################################################################') print('\n') ## Get the startimg time of the reconstruction time1 = time.time() ## Get input arguments args = getArgs() ## Get input/output directory pathin, pathout = utils.get_io_path(args) print('\nInput path:\n', pathin) print('\nOutput path:\n', pathout) ## Get input files file_list, file1, nimg, ext = utils.get_input(args, pathin) print('\nNumber of input files: ', nimg) print('Extension of the files: ', ext) ## Read first sinogram sino = io.readImage(pathin + file1).astype(myfloat) nang, npix = sino.shape print('\nSinogram to reconstruct:\n', file1) print('Number of projection angles: ', nang) print('Number of pixels: ', npix) if args.plot is True: dis.plot(sino, 'Input sinogram') ## Enable edge padding if args.edge_pad is True: sino = proc.sino_edge_padding(sino, 0.5).astype(myfloat) i1 = int((sino.shape[1] - npix) * 0.5) i2 = i1 + npix npix = sino.shape[1] ctr = args.ctr if ctr != 0.0: ctr += i1 if args.plot is True: dis.plot(sino, 'Edge padded sinogram') else: i1 = 0 i2 = npix ctr = args.ctr ## Getting projection geometry if args.geometry == '0': print( '\nDealing with equiangular projections distributed between 0 and' + ' 180 degrees ---> [0,180)') angles = utils.create_projection_angles(nang) else: print('\nReading list of projection angles:\n', pathin + args.geometry) angles = utils.create_projection_angles(textfile=pathin + args.geometry) if args.plot is True: print('\nProjection angles:') pp.printArray(angles) ## Enable object support calculation if args.object_support is True: print('\nObject support calculation enabled') mask = ob.object_support(sino) if args.plot is True: dis.plot(mask, 'Object support mask') ## Differential sinogram fo DBP if args.dbp is True: print('\nDifferential backprojection enabled') print( 'Computing differential sinogram by means of Savitzky-Golay method' ) sino[:, :] = proc.diff_sino_savitzky_golay(sino, window_size=11) if args.plot is True: dis.plot(sino, 'Differential sinogram') ## Initialize projectior class tp = cpj.projectors(npix, angles, ctr=ctr, args=args) ## Apply forward projection operator time_rec1 = time.time() reco = tp.fbp(sino) time_rec2 = time.time() ## Crop reconstruction if args.edge_pad: reco = reco[i1:i2, i1:i2] ## Apply object support mask if args.object_support is True: reco[mask == 0] = 0.0 ## Display reconstruction if args.plot is True: dis.plot(reco, 'Reconstruction') ## Save reconstruction save_reconstruction(pathout, file1, args, reco) ## Reconstruct sinograms from all the other images in the stack if args.filein is None: pool = mproc.Pool() for i in range(1, nimg): pool.apply_async( multi_thread, (pathin, pathout, file_list[0][i], args, [i1, i2])) pool.close() pool.join() time2 = time.time() print('\nTime elapsed to run the 1st backward gridrec: ', time_rec2 - time_rec1) print('Total time elapsed for the run of the program: ', time2 - time1) print('\n') print('##############################################') print('#### GRIDDING RECONSTRUCTION DONE ! ####') print('##############################################') print('\n')