From 00c4956e97c6971515332e70d1554904b338a2a8 Mon Sep 17 00:00:00 2001 From: Tamino Huxohl <thuxohl@techfak.uni-bielefeld.de> Date: Fri, 18 Nov 2022 14:05:19 +0100 Subject: [PATCH] rename recon module to osem and add postfilter support --- mu_map/recon/{recon.py => osem.py} | 47 ++++++++++++++++++------------ 1 file changed, 28 insertions(+), 19 deletions(-) rename mu_map/recon/{recon.py => osem.py} (89%) diff --git a/mu_map/recon/recon.py b/mu_map/recon/osem.py similarity index 89% rename from mu_map/recon/recon.py rename to mu_map/recon/osem.py index 3614817..d4abd98 100644 --- a/mu_map/recon/recon.py +++ b/mu_map/recon/osem.py @@ -16,6 +16,7 @@ from mu_map.file.interfile import ( KEY_SPACING_2, TEMPLATE_HEADER_IMAGE, ) +from mu_map.recon.filter import GaussianFilter TEMPLATE_RECON_PARAMS = """ @@ -65,21 +66,6 @@ OSMAPOSLParameters := number of subiterations:= {N_SUBITERATIONS} Save estimates at subiteration intervals:= {SAVE_INTERVALS} - ; keywords that specify the filtering that occurs after every subiteration - ; warning: do not normally use together with a prior - inter-iteration filter subiteration interval := 4 - inter-iteration filter type := Separable Gaussian - ;post-filter type := Separable Gaussian - separable gaussian filter parameters := - x-dir filter fwhm (in mm) := 9.6 - y-dir filter fwhm (in mm) := 9.6 - z-dir filter fwhm (in mm) := 9.6 - x-dir maximum kernel size := 128 - y-dir maximum kernel size := 128 - z-dir maximum kernel size := 33 - Normalise filter to 1 := 1 - end separable gaussian filter parameters := - END := """ @@ -112,6 +98,7 @@ def reconstruct( init: Optional[Tuple[Dict[str, str], np.ndarray]] = None, n_subsets: Optional[int] = 4, n_iterations: Optional[int] = 10, + postfilter: Optional[GaussianFilter] = None, **kwargs, ): # sanitize parameters @@ -155,6 +142,9 @@ def reconstruct( write_interfile(filename_init, *init) params = params.replace("{INIT_FILE}", filename_init) + if postfilter: + params = postfilter.insert(params) + filename_params = os.path.join(dir_tmp.name, "OSEM_SPECT.par") with open(filename_params, mode="w") as f: f.write(params.strip()) @@ -162,7 +152,6 @@ def reconstruct( recon = stir.OSMAPOSLReconstruction3DFloat(filename_params) recon.reconstruct() - print(params) return load_interfile(filename_out) @@ -209,6 +198,18 @@ if __name__ == "__main__": default=10, help="the number of iterations for OSEM reconstruction", ) + parser.add_argument( + "--postfilter", + choices=["gaussian", "none"], + default="gaussian", + help="apply a postfilter to the reconstruction", + ) + parser.add_argument( + "--postfilter_width", + type=float, + default=1.0, + help="the filter witdth for the postfilter is based on the spacing in the projection and can be modified with this factor", + ) parser.add_argument( "-v", "--verbosity", type=int, default=0, help="configure the verbosity of STIR" ) @@ -230,11 +231,19 @@ if __name__ == "__main__": else: projection = load_as_interfile(args.projection) + postfilter = None + if args.postfilter == "gaussian": + postfilter = GaussianFilter(projection, args.postfilter_width) + kwargs = vars(args) del kwargs["mu_map"] del kwargs["projection"] - print(kwargs) - header, image = reconstruct(projection, mu_map=mu_map, **kwargs) - image = image[:, :, ::-1] + del kwargs["postfilter"] + header, image = reconstruct( + projection, mu_map=mu_map, postfilter=postfilter, **kwargs + ) + image = image[ + :, :, ::-1 + ] # STIR creates reconstructions flipped on the x-axes, this is reverted here write_interfile(args.out, header, image) -- GitLab