Esempio n. 1
0
def scan_and_reconstruct(photons, material, phantom, scale, angles, mas=10000, alpha=0.001, correct=True):

	""" Simulation of the CT scanning process
		reconstruction = scan_and_reconstruct(photons, material, phantom, scale, angles, mas, alpha)
		takes the phantom data in phantom (samples x samples), scans it using the
		source photons and material information given, as well as the scale (in cm),
		number of angles, time-current product in mas, and raised-cosine power
		alpha for filtering. The output reconstruction is the same size as phantom."""


	# convert source (photons per (mas, cm^2)) to photons

	# create sinogram from phantom data, with received detector values
	sinogram = ct_scan(photons, material, phantom, scale, angles, mas)

	# convert detector values into calibrated attenuation values
	sinogram = ct_calibrate(photons, material, sinogram, scale, correct)

	# Ram-Lak
	sinogram = ramp_filter(sinogram, scale, alpha)

	# Back-projection
	reconstruction = back_project(sinogram)

	# convert to Hounsfield Units
	reconstruction = hu(photons, material, reconstruction, scale)

	return reconstruction
def scan_and_backproject(photon_source,
                         material_data,
                         phantom,
                         scale,
                         angles,
                         mas=10000,
                         alpha=0.001):
    """
    Scan and backproject without convolving with a RamLak filter. Use for report and demonstration only.
    """
    # create sinogram from phantom data, with received detector values
    sinogram = ct_scan(photon_source,
                       material_data,
                       phantom,
                       scale,
                       angles,
                       interpolation_order=1)

    # convert detector values into calibrated attenuation values
    total_attenuation = ct_calibrate(photon_source, material_data, sinogram,
                                     scale)

    # Back-projection
    backprojection = back_project(total_attenuation)

    return backprojection
Esempio n. 3
0
    def reconstruct_all(self, file, method=None, alpha=None):
        """ reconstruct_all( FILENAME, ALPHA ) creates a series of DICOM
        files for the Xtreme RSQ data. FILENAME is the base file name for
        the data, and ALPHA is the power of the raised cosine function
        used to filter the data.
        
        reconstruct_all( FILENAME, ALPHA, METHOD ) can be used to
        specify how the data is reconstructed. Possible options are:
        'parallel' - reconstruct each slice separately using a fan to parallel
                           conversion
        'fdk' - approximate FDK algorithm for better reconstruction"""

        if alpha is None:
            alpha = 0.001

        if method is None:
            method = 'parallel'

        # set frame number and DICOM UIDs for saving to multiple frames
        z = 1
        seriesuid = pydicom.uid.generate_uid()
        studyuid = pydicom.uid.generate_uid()
        frameuid = pydicom.uid.generate_uid()
        time = datetime.datetime.now()

        # main loop over each z-fan
        for fan in range(0, self.scans, self.fan_scans):
            if method == 'fdk':

                # correct reconstruction using FDK method, self.fan_scans scans at a time
                pass

            else:

                # default method should reconstruct each slice separately
                sys.stdout.write('\n\n\n\n\n')
                for scan in range(fan + self.skip_scans,
                                  fan + self.fan_scans - self.skip_scans):
                    if (scan < self.scans):

                        sys.stdout.write(
                            '\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[1A'
                            + "Fan:  " + str(fan // self.fan_scans + 1) + '\n')
                        sys.stdout.write("Scan: " + str(
                            (scan - self.skip_scans) % self.fan_scans + 1) +
                                         '\n')

                        # get scan detector values, noise floor and reference
                        sinogram, noise, ref = self.get_rsq_slice(scan)

                        # convert detector values into calibrated attenuation values
                        sinogram = -np.log((sinogram - noise) / (ref - noise))

                        # convert scan from fan to parallel
                        sinogram = self.fan_to_parallel(sinogram)

                        # apply Ram-Lak filter
                        sinogram = ramp_filter(sinogram, self.scale, alpha)

                        # back project
                        reconstruction = back_project(sinogram)

                        # convert to Hounsfield units
                        reconstruction = 1000 * (reconstruction -
                                                 23.835e-3) / 23.835e-3
                        reconstruction = reconstruction.clip(min=-1024,
                                                             max=3071)

                        # save as dicom file
                        create_dicom(reconstruction, file, self.scale,
                                     self.scale, z, studyuid, seriesuid,
                                     frameuid, time)

                        z = z + 1

        return
Esempio n. 4
0
    def reconstruct_all(self, file, method='parallel', alpha=0.001):
        """ reconstruct_all( FILENAME, ALPHA ) creates a series of DICOM
        files for the Xtreme RSQ data. FILENAME is the base file name for
        the data, and ALPHA is the power of the raised cosine function
        used to filter the data."""

        # set frame number and DICOM UIDs for saving to multiple frames
        z = 1
        seriesuid = pydicom.uid.generate_uid()
        studyuid = pydicom.uid.generate_uid()
        frameuid = pydicom.uid.generate_uid()
        time = datetime.datetime.now()

        # main loop over each z-fan
        for fan in range(0, self.scans, self.fan_scans):
            # reconstruct each slice separately
            for scan in range(fan + self.skip_scans,
                              fan + self.fan_scans - self.skip_scans):
                if (scan < self.scans):
                    # obtain slice data
                    f, fmin, fmax = self.get_rsq_slice(scan)

                    # remove noise
                    f = f - fmin
                    fmax = fmax - fmin

                    # calibrate
                    f = -np.log(f / fmax)

                    # convert to a parallel sinogram
                    p = self.fan_to_parallel(f)

                    # filter sinogram (FBP)
                    scale = self.scale / 10
                    filtered = ramp_filter(p, scale)

                    # reconstruct
                    reconstruction = back_project(filtered)

                    # convert to Hu
                    reconstruction = (reconstruction - 0.2192) * 1000 / 0.2192
                    reconstruction = np.where(reconstruction < -1024, -1024,
                                              reconstruction)
                    reconstruction = np.where(reconstruction > 3072, 3072,
                                              reconstruction)
                    plt.close()
                    draw(reconstruction)

                    # save as dicom file
                    """create_dicom(x, filename, sp, sz, f) creates a new DICOM file with a
                    name formed from the given filename and the frame number f, and
                    containing data from x. The pixel scale is given by sp, and the frame
                    spacing is given by sz, both of which are in mm."""

                    create_dicom(reconstruction,
                                 file,
                                 sp=scale,
                                 sz=scale,
                                 f=z,
                                 storage_directory='results',
                                 study_uid=studyuid,
                                 series_uid=seriesuid,
                                 time=time)
                    z = z + 1

        return