示例#1
0
 def initialize_registration(self, landmark_path: Path, output_dir: Path):
     """Use landmark to initialise the registration"""
     if not output_dir.joinpath("landmarks.dof.gz").exists() or self.overwrite:
         mirtk.register(
             str(landmark_path),
             str(self.template.landmark),
             model="Rigid",
             dofout=str(output_dir.joinpath("landmarks.dof.gz")),
         )
     return output_dir.joinpath("landmarks.dof.gz")
示例#2
0
 def nonrigid_registration(self, mesh: PhaseMesh, lv_label_transformed: Path, rv_label_transformed: Path,
                           lv_affine_transform: Path, rv_affine_transform: Path, fr: Phase, output_dir: Path):
     temp_dir = output_dir.joinpath("temp")
     temp_dir.mkdir(exist_ok=True, parents=True)
     rv_transform = temp_dir.joinpath("rv_{}_nreg.dof.gz".format(fr))
     lv_transform = temp_dir.joinpath("lv_{}_nreg.dof.gz".format(fr))
     # if not rv_transform.exists() or self.overwrite:
     #     mirtk.register(
     #         str(self.template.vtk_rv(fr)),
     #         str(rv_label_transformed),
     #         model="FFD",
     #         dofin=str(rv_affine_transform),
     #         dofout=str(rv_transform),
     #         parin=str(self.segreg_path),
     #     )
     if not rv_transform.exists() or self.overwrite:
         mirtk.register(
             str(self.template.rv(fr)),
             str(mesh.rv.rv),
             # "-symmetric",
             "-par", "Point set distance correspondence", "CP",
             ds=8,
             model="FFD",
             dofin=str(rv_affine_transform),
             dofout=str(rv_transform),
         )
     # if not lv_transform.exists() or self.overwrite:
     #     mirtk.register(
     #         str(self.template.vtk_lv(fr)),
     #         str(lv_label_transformed),
     #         model="FFD",
     #         dofin=str(lv_affine_transform),
     #         dofout=str(lv_transform),
     #         parin=str(self.segreg_path),
     #     )
     if not lv_transform.exists() or self.overwrite:
         mirtk.register(
             str(self.template.lv_endo(fr)),
             str(mesh.lv.endocardium),
             str(self.template.lv_epi(fr)),
             str(mesh.lv.epicardium),
             # "-symmetric",
             "-par", "Energy function", "PCD(T o P(1:2:end), P(2:2:end))",
             model="FFD",
             dofin=str(lv_affine_transform),
             dofout=str(lv_transform),
             ds=4,
         )
     return lv_transform, rv_transform
示例#3
0
 def affine_registration(self, lv_label_transformed: Path, rv_label_transformed: Path, fr: Phase, output_dir: Path, mesh):
     temp_dir = output_dir.joinpath("temp")
     temp_dir.mkdir(exist_ok=True, parents=True)
     if not temp_dir.joinpath("smoothed_template_vtk_RV_{}.nii.gz".format(fr)).exists() or self.overwrite:
         mirtk.smooth_image(
             str(self.template.vtk_rv(fr)),
             str(temp_dir.joinpath("smoothed_template_vtk_RV_{}.nii.gz".format(fr))),
             1,
             "-float"
         )
     if not temp_dir.joinpath("rv_{}_areg.dof.gz".format(fr)).exists() or self.overwrite:
         mirtk.register(
             str(self.template.rv(fr)),
             str(mesh.rv.rv),
             "-par", "Point set distance correspondence", "CP",
             model="Affine",
             dofout=str(temp_dir.joinpath("rv_{}_areg.dof.gz".format(fr))),
             parin=str(self.segareg_path),
         )
         # mirtk.register(
         #     str(temp_dir.joinpath("smoothed_template_vtk_RV_{}.nii.gz".format(fr))),
         #     str(rv_label_transformed),
         #     model="Affine",
         #     dofout=str(temp_dir.joinpath("rv_{}_areg.dof.gz".format(fr))),
         #     parin=str(self.segareg_path),
         # )
     if not temp_dir.joinpath("lv_{}_areg.dof.gz".format(fr)).exists() or self.overwrite:
         mirtk.register(
             str(self.template.lv_epi(fr)),
             str(mesh.lv.epicardium),
             "-par", "Point set distance correspondence", "CP",
             model="Affine",
             dofout=str(temp_dir.joinpath("lv_{}_areg.dof.gz".format(fr))),
             parin=str(self.segareg_path),
         )
         # mirtk.register(
         #     str(self.template.vtk_lv(fr)),
         #     str(lv_label_transformed),
         #     model="Affine",
         #     dofout=str(temp_dir.joinpath("lv_{}_areg.dof.gz".format(fr))),
         #     parin=str(self.segareg_path),
         # )
     return temp_dir.joinpath("lv_{}_areg.dof.gz".format(fr)), temp_dir.joinpath("rv_{}_areg.dof.gz".format(fr))
示例#4
0
    def select_altases(self, subject_seg: Path, subject_landmarks: Path,
                       output_dir: Path, n_top: int, force: bool):
        """Select top similar atlases, according to subject segmentation and landmark"""
        nmi = []

        top_similar_atlases = []

        n_atlases = len(self.atlases)

        # if force:
        #     for f in output_dir.glob("shapenmi*.txt"):
        #         f.unlink()
        output_dofs = []
        top_atlas_dofs = []
        for i in range(n_atlases):
            try:
                if not output_dir.joinpath(
                        f"shapelandmarks_{i}.dof.gz").exists() or force:
                    mirtk.register(
                        str(subject_landmarks),
                        str(self.landmarks[i]),
                        model="Affine",
                        dofout=str(
                            output_dir.joinpath(f"shapelandmarks_{i}.dof.gz")),
                    )
                if not output_dir.joinpath(
                        f"shapenmi_{i}.txt").exists() or force:
                    mirtk.evaluate_similarity(
                        str(subject_seg),
                        str(self.atlases[i]),
                        Tbins=64,
                        Sbins=64,
                        dofin=str(
                            output_dir.joinpath(f"shapelandmarks_{i}.dof.gz")),
                        table=str(output_dir.joinpath(f"shapenmi_{i}.txt")),
                    )
                output_dofs.append(
                    output_dir.joinpath(f"shapelandmarks_{i}.dof.gz"))

                if output_dir.joinpath(f"shapenmi_{i}.txt").exists():
                    similarities = np.genfromtxt('{0}/shapenmi_{1}.txt'.format(
                        str(output_dir), i),
                                                 delimiter=",")
                    nmi += [similarities[1, 5]]
                else:
                    nmi += [0]
            except KeyboardInterrupt:
                raise
            except Exception:
                continue

        if n_top < n_atlases:
            sortedIndexes = np.array(nmi).argsort()[::-1]
            for i in range(n_top):
                top_similar_atlases += [self.atlases[sortedIndexes[i]]]
                top_atlas_dofs += [output_dofs[sortedIndexes[i]]]
        else:
            top_similar_atlases = self.atlases
            top_atlas_dofs = output_dofs

        return top_similar_atlases, top_atlas_dofs
示例#5
0
    def run(self, subject_image: PhaseImage, subject_seg: Segmentation,
            subject_landmarks: Path, output_dir: Path, n_top: int,
            force: bool) -> Segmentation:
        output_path = output_dir.joinpath(subject_seg.path.stem +
                                          "_refined.nii.gz")

        if force or not Segmentation(path=output_path,
                                     phase=subject_seg.phase).exists():
            tmp_dir = output_dir.joinpath("tmp", str(subject_seg.phase))
            tmp_dir.mkdir(exist_ok=True, parents=True)

            top_atlases, top_dofs = self.select_altases(
                subject_seg=subject_seg.path,
                subject_landmarks=subject_landmarks,
                output_dir=tmp_dir,
                n_top=n_top,
                force=force,
            )
            atlas_labels = []
            phase = str(subject_seg.phase)
            for i, (atlas, dof) in enumerate(zip(top_atlases, top_dofs)):
                if not tmp_dir.joinpath(
                        f"shapeffd_{i}_{str(phase)}.dof.gz").exists() or force:
                    mirtk.register(str(subject_seg),
                                   str(atlas),
                                   parin=str(self.param_path),
                                   dofin=str(dof),
                                   dofout=tmp_dir.joinpath(
                                       f"shapeffd_{i}_{phase}.dof.gz"))

                label_path = tmp_dir.joinpath(f"seg_affine_{i}_{phase}.nii.gz")
                if not label_path.exists() or force:
                    mirtk.transform_image(
                        str(atlas),
                        str(label_path),
                        dofin=str(dof),
                        target=str(subject_image),
                        interp="NN",
                    )

                label_path = tmp_dir.joinpath(f"seg_{i}_{phase}.nii.gz")
                if not label_path.exists() or force:
                    mirtk.transform_image(
                        str(atlas),
                        str(label_path),
                        dofin=str(
                            tmp_dir.joinpath(f"shapeffd_{i}_{phase}.dof.gz")),
                        target=str(subject_image),
                        interp="NN",
                    )
                nim = nib.load(str(label_path))
                label = nim.get_data()
                label[label == 4] = 3
                nim2 = nib.Nifti1Image(label, nim.affine)
                nim2.header['pixdim'] = nim.header['pixdim']
                nib.save(nim2, str(label_path))
                atlas_labels.append(label_path)

            # apply label fusion
            labels = sitk.VectorOfImage()

            for label_path in atlas_labels:
                label = sitk.ReadImage(str(label_path),
                                       imageIO="NiftiImageIO",
                                       outputPixelType=sitk.sitkUInt8)
                labels.push_back(label)
            voter = sitk.LabelVotingImageFilter()
            voter.SetLabelForUndecidedPixels(0)
            fused_label = voter.Execute(labels)
            sitk.WriteImage(fused_label,
                            str(output_path),
                            imageIO="NiftiImageIO")

        return Segmentation(path=output_path, phase=subject_seg.phase)
示例#6
0
def meshGeneration(subject: Subject, template_dir: Path):
   
    print("\n ... Mesh Generation - step [1] -")
    for phase, segmented_path, segmented_LR_path in zip(
        ["ED", "ES"], subject.segmented_ed_es, subject.segmented_LR_ed_es
    ):
        # extract meshes of lvendo, lvepi, lvmyo, rv and rveip at ED and ES, respectively
        mirtk.calculate_element_wise(
            str(segmented_path),
            "-label", 3, 4,
            set=255, pad=0,
            output=str(subject.tmps_dir().joinpath("vtk_RV_{}.nii.gz".format(phase))),
        )
        mirtk.extract_surface(
            str(subject.tmps_dir().joinpath("vtk_RV_{}.nii.gz".format(phase))),
            str(subject.vtks_dir().joinpath("RV_{}.vtk".format(phase))),
            isovalue=120, blur=2,
        )
        mirtk.calculate_element_wise(
            str(segmented_path),
            "-label", 3, 4,
            set=255, pad=0,
            output=str(subject.tmps_dir().joinpath("vtk_RVepi_{}.nii.gz".format(phase))),
        )
        mirtk.extract_surface(
            str(subject.tmps_dir().joinpath("vtk_RVepi_{}.nii.gz".format(phase))),
            str(subject.vtks_dir().joinpath("RVepi_{}.vtk".format(phase))),
            isovalue=120, blur=2,
        )
        mirtk.calculate_element_wise(
            str(segmented_path),
            "-map", 3, 0, 4, 0,
            output=str(subject.tmps_dir().joinpath("vtk_LV_{}.nii.gz".format(phase))),
        )
        mirtk.calculate_element_wise(
            str(segmented_path),
            "-label", 1, set=255, pad=0,
            output=str(subject.tmps_dir().joinpath("vtk_LVendo_{}.nii.gz".format(phase))),
        )
        mirtk.extract_surface(
            str(subject.tmps_dir().joinpath("vtk_LVendo_{}.nii.gz".format(phase))),
            str(subject.vtks_dir().joinpath("LVendo_{}.vtk".format(phase))),
            isovalue=120, blur=2,
        )
        mirtk.calculate_element_wise(
            str(segmented_path),
            "-label", 1, 2, set=255, pad=0,
            output=str(subject.tmps_dir().joinpath("vtk_LVepi_{}.nii.gz".format(phase))),
        )
        mirtk.extract_surface(
            str(subject.tmps_dir().joinpath("vtk_LVepi_{}.nii.gz".format(phase))),
            str(subject.vtks_dir().joinpath("LVepi_{}.vtk".format(phase))),
            isovalue=120, blur=2,
        )
        mirtk.calculate_element_wise(
            str(segmented_path),
            "-label", 2, set=255, pad=0,
            output=str(subject.tmps_dir().joinpath("vtk_LVmyo_{}.nii.gz".format(phase))),
        )
        mirtk.extract_surface(
            str(subject.tmps_dir().joinpath("vtk_LVmyo_{}.nii.gz".format(phase))),
            str(subject.vtks_dir().joinpath("LVmyo_{}.vtk".format(phase))),
            isovalue=120, blur=2,
        )

    # use landmark to initialise the registration
    mirtk.register(
        str(subject.landmark_path),
        str(template_dir.joinpath("landmarks2.vtk")),
        model="Rigid",
        dofout=str(subject.dofs_dir().joinpath("landmarks.dof.gz")),
    )
    
    ###############################################################################

    print("\n ... Mesh Generation - step [2] -")
    for fr in ['ED', 'ES']:

        mirtk.register_points(
            "-t", str(subject.vtks_dir().joinpath("RV_{}.vtk".format(fr))),
            "-s", str(template_dir.joinpath("RV_{}.vtk".format(fr))),
            "-t", str(subject.vtks_dir().joinpath("LVendo_{}.vtk".format(fr))),
            "-s", str(template_dir.joinpath("LVendo_{}.vtk".format(fr))),
            "-t", str(subject.vtks_dir().joinpath("LVepi_{}.vtk".format(fr))),
            "-s", str(template_dir.joinpath("LVepi_{}.vtk".format(fr))),
            "-symmetric",
            dofin=str(subject.dofs_dir().joinpath("landmarks.dof.gz")),
            dofout=str(subject.tmps_dir().joinpath("{}.dof.gz".format(fr)))
        )

        mirtk.register_points(
            "-t", str(subject.vtks_dir().joinpath("LVendo_{}.vtk".format(fr))),
            "-s", str(template_dir.joinpath("LVendo_{}.vtk".format(fr))),
            "-t", str(subject.vtks_dir().joinpath("LVepi_{}.vtk".format(fr))),
            "-s", str(template_dir.joinpath("LVepi_{}.vtk".format(fr))),
            "-symmetric",
            dofin=str(subject.tmps_dir().joinpath("{}.dof.gz".format(fr))),
            dofout=str(subject.tmps_dir().joinpath("lv_{}_rreg.dof.gz".format(fr))),
        )

        mirtk.register_points(
            "-t", str(subject.vtks_dir().joinpath("RV_{}.vtk".format(fr))),
            "-s", str(template_dir.joinpath("RV_{}.vtk".format(fr))),
            "-symmetric",
            dofin=str(subject.tmps_dir().joinpath("{}.dof.gz".format(fr))),
            dofout=str(subject.tmps_dir().joinpath("rv_{}_rreg.dof.gz".format(fr))),
        )

        ###########################################################################
        # os.system('ptransformation '
        #           '{0}/RV_{2}.vtk '
        #           '{0}/N_RV_{2}.vtk '
        #           '-dofin {1}/rv_{2}_rreg.dof.gz >/dev/nul '
        #           .format(vtks_dir, tmps_dir, fr))
        mirtk.transform_points(
            str(subject.vtks_dir().joinpath("RV_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_RV_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("rv_{}_rreg.dof.gz".format(fr))),
        )

        # os.system('ptransformation '
        #           '{0}/RVepi_{2}.vtk '
        #           '{0}/N_RVepi_{2}.vtk '
        #           '-dofin {1}/rv_{2}_rreg.dof.gz >/dev/nul '
        #           .format(vtks_dir, tmps_dir, fr))
        mirtk.transform_points(
            str(subject.vtks_dir().joinpath("RVepi_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_RVepi_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("rv_{}_rreg.dof.gz".format(fr))),
        )
        # os.system('ptransformation '
        #           '{0}/LVendo_{2}.vtk '
        #           '{0}/N_LVendo_{2}.vtk '
        #           '-dofin {1}/lv_{2}_rreg.dof.gz >/dev/nul '
        #           .format(vtks_dir, tmps_dir, fr))
        mirtk.transform_points(
            str(subject.vtks_dir().joinpath("LVendo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVendo_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("lv_{}_rreg.dof.gz".format(fr))),
        )
        # os.system('ptransformation '
        #           '{0}/LVepi_{2}.vtk '
        #           '{0}/N_LVepi_{2}.vtk '
        #           '-dofin {1}/lv_{2}_rreg.dof.gz >/dev/nul '
        #           .format(vtks_dir, tmps_dir, fr))
        mirtk.transform_points(
            str(subject.vtks_dir().joinpath("LVepi_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVepi_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("lv_{}_rreg.dof.gz".format(fr))),
        )
        # os.system('ptransformation '
        #           '{0}/LVmyo_{2}.vtk '
        #           '{0}/N_LVmyo_{2}.vtk '
        #           '-dofin {1}/lv_{2}_rreg.dof.gz >/dev/nul '
        #           .format(vtks_dir, tmps_dir, fr))
        mirtk.transform_points(
            str(subject.vtks_dir().joinpath("LVmyo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVmyo_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("lv_{}_rreg.dof.gz".format(fr))),
        )
        # os.system('transformation '
        #           '{0}/vtk_RV_{1}.nii.gz '
        #           '{0}/N_vtk_RV_{1}.nii.gz '
        #           '-dofin {0}/lv_{1}_rreg.dof.gz '
        #           '-invert >/dev/nul '
        #           .format(tmps_dir, fr))

        mirtk.transform_image(
            str(subject.tmps_dir().joinpath("vtk_RV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("N_vtk_RV_{}.nii.gz".format(fr))),
            "-invert",
            dofin=str(subject.tmps_dir().joinpath("lv_{}_rreg.dof.gz".format(fr))),
        )
        # os.system('transformation '
        #           '{0}/vtk_LV_{1}.nii.gz '
        #           '{0}/N_vtk_LV_{1}.nii.gz '
        #           '-dofin {0}/lv_{1}_rreg.dof.gz '
        #           '-invert >/dev/nul '
        #           .format(tmps_dir, fr))
        mirtk.transform_image(
            str(subject.tmps_dir().joinpath("vtk_LV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("N_vtk_LV_{}.nii.gz".format(fr))),
            "-invert",
            dofin=str(subject.tmps_dir().joinpath("lv_{}_rreg.dof.gz".format(fr))),
        )
        ###########################################################################
        #affine

        # os.system('areg '
        #           '{0}/vtk_RV_{3}.nii.gz '
        #           '{1}/N_vtk_RV_{3}.nii.gz '
        #           '-dofout {1}/rv_{3}_areg.dof.gz '
        #           '-parin {2}/segareg.txt >/dev/nul '
        #           .format(template_dir, tmps_dir, param_dir, fr))

        mirtk.smooth_image(
            str(template_dir.joinpath("vtk_RV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("smoothed_template_vtk_RV_{}.nii.gz".format(fr))),
            1,
            "-float"
        )
        mirtk.register(
            str(subject.tmps_dir().joinpath("smoothed_template_vtk_RV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("N_vtk_RV_{}.nii.gz".format(fr))),
            model="Affine",
            dofout=str(subject.tmps_dir().joinpath("rv_{}_areg.dof.gz".format(fr))),
            parin=str(template_dir.joinpath("segareg.txt")),
        )
        # os.system('areg '
        #           '{0}/vtk_LV_{3}.nii.gz '
        #           '{1}/N_vtk_LV_{3}.nii.gz '
        #           '-dofout {1}/lv_{3}_areg.dof.gz '
        #           '-parin {2}/segareg.txt >/dev/nul '
        #           .format(template_dir, tmps_dir, param_dir, fr))
        mirtk.register(
            str(template_dir.joinpath("vtk_LV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("N_vtk_LV_{}.nii.gz".format(fr))),
            model="Affine",
            dofout=str(subject.tmps_dir().joinpath("lv_{}_areg.dof.gz".format(fr))),
            parin=str(template_dir.joinpath("segareg.txt")),
        )
        #non-rigid
        # os.system('nreg '
        #           '{0}/vtk_RV_{3}.nii.gz '
        #           '{1}/N_vtk_RV_{3}.nii.gz '
        #           '-dofin {1}/rv_{3}_areg.dof.gz '
        #           '-dofout {1}/rv_{3}_nreg.dof.gz '
        #           '-parin {2}/segreg.txt >/dev/nul '
        #           .format(template_dir, tmps_dir, param_dir, fr))

        mirtk.register(
            str(template_dir.joinpath("vtk_RV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("N_vtk_RV_{}.nii.gz".format(fr))),
            model="FFD",
            dofin=str(subject.tmps_dir().joinpath("rv_{}_areg.dof.gz".format(fr))),
            dofout=str(subject.tmps_dir().joinpath("rv_{}_nreg.dof.gz".format(fr))),
            parin=str(template_dir.joinpath("segreg.txt")),
        )
        # os.system('snreg '
        #           '{0}/RV_{3}.vtk '
        #           '{1}/N_RV_{3}.vtk '
        #           '-dofin {2}/rv_{3}_nreg.dof.gz '
        #           '-dofout {2}/rv{3}ds8.dof.gz '
        #           '-ds 8 -symmetric >/dev/nul '
        #           .format(template_dir, vtks_dir, tmps_dir, fr))
        mirtk.register(
            str(template_dir.joinpath("RV_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_RV_{}.vtk".format(fr))),
            # "-symmetric",
            "-par", "Point set distance correspondence", "CP",
            ds=8,
            model="FFD",
            dofin=str(subject.tmps_dir().joinpath("rv_{}_nreg.dof.gz".format(fr))),
            dofout=str(subject.tmps_dir().joinpath("rv{}ds8.dof.gz".format(fr))),
        )
        # # os.system('nreg '
        # #           '{0}/vtk_LV_{3}.nii.gz '
        # #           '{1}/N_vtk_LV_{3}.nii.gz '
        # #           '-dofin {1}/lv_{3}_areg.dof.gz '
        # #           '-dofout {1}/lv_{3}_nreg.dof.gz '
        # #           '-parin {2}/segreg.txt >/dev/nul '
        # #           .format(template_dir, tmps_dir, param_dir, fr))
        mirtk.register(
            str(template_dir.joinpath("vtk_LV_{}.nii.gz".format(fr))),
            str(subject.tmps_dir().joinpath("N_vtk_LV_{}.nii.gz".format(fr))),
            model="FFD",
            dofin=str(subject.tmps_dir().joinpath("lv_{}_areg.dof.gz".format(fr))),
            dofout=str(subject.tmps_dir().joinpath("lv_{}_nreg.dof.gz".format(fr))),
            parin=str(template_dir.joinpath("segreg.txt")),
        )
        # os.system('msnreg 2 '
        #           '{0}/LVendo_{3}.vtk '
        #           '{0}/LVepi_{3}.vtk '
        #           '{1}/N_LVendo_{3}.vtk '
        #           '{1}/N_LVepi_{3}.vtk '
        #           '-dofin {2}/lv_{3}_nreg.dof.gz '
        #           '-dofout {2}/lv{3}final.dof.gz '
        #           '-ds 4 -symmetric >/dev/nul '
        #           .format(template_dir, vtks_dir, tmps_dir, fr))
        mirtk.register(
            str(template_dir.joinpath("LVendo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVendo_{}.vtk".format(fr))),
            str(template_dir.joinpath("LVepi_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVepi_{}.vtk".format(fr))),
            # "-symmetric",
            "-par", "Energy function", "PCD(T o P(1:2:end), P(2:2:end))",
            model="FFD",
            dofin=str(subject.tmps_dir().joinpath("lv_{}_nreg.dof.gz".format(fr))),
            dofout=str(subject.tmps_dir().joinpath("lv{}final.dof.gz".format(fr))),
            ds=4,
        )
        # same number of points
        # os.system('cardiacsurfacemap '
        #           '{0}/LVendo_{3}.vtk '
        #           '{1}/N_LVendo_{3}.vtk '
        #           '{2}/lv{3}final.dof.gz '
        #           '{1}/F_LVendo_{3}.vtk >/dev/nul '
        #           .format(template_dir, vtks_dir, tmps_dir, fr))

        mirtk.match_points(
            str(template_dir.joinpath("LVendo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVendo_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("lv{}final.dof.gz".format(fr))),
            output=str(subject.vtks_dir().joinpath("F_LVendo_{}.vtk".format(fr))),
        )

        # os.system('cardiacsurfacemap '
        #           '{0}/LVepi_{3}.vtk '
        #           '{1}/N_LVepi_{3}.vtk '
        #           '{2}/lv{3}final.dof.gz '
        #           '{1}/F_LVepi_{3}.vtk >/dev/nul '
        #           .format(template_dir, vtks_dir, tmps_dir, fr))
        mirtk.match_points(
            str(template_dir.joinpath("LVepi_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_LVepi_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("lv{}final.dof.gz".format(fr))),
            output=str(subject.vtks_dir().joinpath("F_LVepi_{}.vtk".format(fr))),
        )
        # os.system('ptransformation '
        #           '{0}/LVmyo_{3}.vtk '
        #           '{1}/F_LVmyo_{3}.vtk '
        #           '-dofin {2}/lv{3}final.dof.gz >/dev/nul '
        #           .format(template_dir, vtks_dir, tmps_dir, fr))
        mirtk.transform_points(
            str(template_dir.joinpath("LVmyo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("F_LVmyo_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("lv{}final.dof.gz".format(fr))),
        )

        # os.system('cardiacsurfacemap '
        #           '{0}/RV_{3}.vtk '
        #           '{1}/N_RV_{3}.vtk '
        #           '{2}/rv{3}ds8.dof.gz '
        #           '{1}/C_RV_{3}.vtk >/dev/nul '
        #           .format(template_dir, vtks_dir, tmps_dir, fr))
        mirtk.match_points(
            str(template_dir.joinpath("RV_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_RV_{}.vtk".format(fr))),
            dofin=str(subject.tmps_dir().joinpath("rv{}ds8.dof.gz".format(fr))),
            output=str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
        )
        ###########################################################################
        # os.system('cp {0}/F_LVendo_{1}.vtk {0}/S_LVendo_{1}.vtk'.format(vtks_dir, fr))
        # os.system('cp {0}/F_LVepi_{1}.vtk {0}/S_LVepi_{1}.vtk'.format(vtks_dir, fr))
        # os.system('cp {0}/F_LVmyo_{1}.vtk {0}/S_LVmyo_{1}.vtk'.format(vtks_dir, fr))
        # os.system('cp {0}/F_LVmyo_{1}.vtk {0}/C_LVmyo_{1}.vtk'.format(vtks_dir, fr))
        # os.system('cp {0}/F_LVmyo_{1}.vtk {0}/W_LVmyo_{1}.vtk'.format(vtks_dir, fr))
        # os.system('cp {0}/C_RV_{1}.vtk {0}/S_RV_{1}.vtk'.format(vtks_dir, fr))
        # os.system('cp {0}/C_RV_{1}.vtk {0}/W_RV_{1}.vtk'.format(vtks_dir, fr))

        shutil.copy(
            str(subject.vtks_dir().joinpath("F_LVendo_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("S_LVendo_{}.vtk".format(fr))
        )
        shutil.copy(
            str(subject.vtks_dir().joinpath("F_LVepi_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("S_LVepi_{}.vtk".format(fr))
        )
        shutil.copy(
            str(subject.vtks_dir().joinpath("F_LVmyo_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("S_LVmyo_{}.vtk".format(fr))
        )
        shutil.copy(
            str(subject.vtks_dir().joinpath("F_LVmyo_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("C_LVmyo_{}.vtk".format(fr))
        )

        shutil.copy(
            str(subject.vtks_dir().joinpath("F_LVmyo_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("W_LVmyo_{}.vtk".format(fr))
        )
        shutil.copy(
            str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("S_RV_{}.vtk".format(fr))
        )
        shutil.copy(
            str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
            subject.vtks_dir().joinpath("W_RV_{}.vtk".format(fr))
        )

        print("\n ... Mesh Generation - step [3] -")

        ###########################################################################
        # compute the quantities of the heart with respect to template
        # os.system('cardiacwallthickness '
        #           '{0}/F_LVendo_{1}.vtk '
        #           '{0}/F_LVepi_{1}.vtk '
        #           '-myocardium '
        #           '{0}/W_LVmyo_{1}.vtk >/dev/nul '
        #           .format(vtks_dir, fr))

        mirtk.evaluate_distance(
            str(subject.vtks_dir().joinpath("F_LVendo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("F_LVepi_{}.vtk".format(fr))),
            name="WallThickness",
        )

        # os.system('cardiacenlargedistance '
        #           '{0}/S_LVendo_{2}.vtk '
        #           '{0}/S_LVepi_{2}.vtk '
        #           '{1}/LVendo_{2}.vtk '
        #           '{1}/LVepi_{2}.vtk '
        #           '-myocardium '
        #           '{0}/S_LVmyo_{2}.vtk >/dev/nul '
        #           .format(vtks_dir, template_dir, fr))
        mirtk.evaluate_distance(
            str(subject.vtks_dir().joinpath("S_LVendo_{}.vtk".format(fr))),
            str(template_dir.joinpath("LVendo_{}.vtk".format(fr))),
            name="WallThickness",
        )
        mirtk.evaluate_distance(
            str(subject.vtks_dir().joinpath("S_LVepi_{}.vtk".format(fr))),
            str(template_dir.joinpath("LVepi_{}.vtk".format(fr))),
            name="WallThickness",
        )
        
        # os.system('DiscreteCurvatureEstimator '
        #           '{0}/C_LVmyo_{1}.vtk '
        #           '{0}/FC_LVmyo_{1}.vtk >/dev/nul '
        #           .format(vtks_dir, fr))
        #
        # os.system('cardiaccurvature '
        #           '{0}/FC_LVmyo_{1}.vtk '
        #           '{0}/C_LVmyo_{1}.vtk >/dev/nul '
        #           '-smooth 64'
        #           .format(vtks_dir, fr))
        # mirtk.decimate_surface(
        #     str(subject.vtks_dir().joinpath("C_LVmyo_{}.vtk".format(fr))),
        #     str(subject.vtks_dir().joinpath("FC_LVmyo_{}.vtk".format(fr))),
        # )
        mirtk.calculate_surface_attributes(
            str(subject.vtks_dir().joinpath("C_LVmyo_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("C_LVmyo_{}.vtk".format(fr))),
            smooth_iterations=64,
        )
        
        # os.system('DiscreteCurvatureEstimator '
        #           '{0}/C_RV_{1}.vtk '
        #           '{0}/FC_RV_{1}.vtk >/dev/nul '
        #           .format(vtks_dir, fr))
        #
        # os.system('cardiaccurvature '
        #           '{0}/FC_RV_{1}.vtk '
        #           '{0}/C_RV_{1}.vtk '
        #           '-smooth 64 >/dev/nul '
        #           .format(vtks_dir, fr))

        # mirtk.decimate_surface(
        #     str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
        #     str(subject.vtks_dir().joinpath("FC_RV_{}.vtk".format(fr))),
        # )
        mirtk.calculate_surface_attributes(
            str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
            smooth_iterations=64,
        )

        # os.system('sevaluation '
        #           '{0}/S_RV_{2}.vtk '
        #           '{1}/RV_{2}.vtk '
        #           '-scalar '
        #           '-signed >/dev/nul '
        #           .format(vtks_dir, template_dir, fr))

        mirtk.evaluate_distance(
            str(subject.vtks_dir().joinpath("S_RV_{}.vtk".format(fr))),
            str(template_dir.joinpath("RV_{}.vtk".format(fr))),
            "-normal",
            name="WallThickness",
        )

        # os.system('cardiacwallthickness '
        #           '{0}/W_RV_{1}.vtk '
        #           '{0}/N_RVepi_{1}.vtk >/dev/nul '
        #           .format(vtks_dir, fr))

        mirtk.evaluate_distance(
            str(subject.vtks_dir().joinpath("W_RV_{}.vtk".format(fr))),
            str(subject.vtks_dir().joinpath("N_RVepi_{}.vtk".format(fr))),
            name="WallThickness",
        )
        
        ###########################################################################
#        os.system('vtk2txt {0}/C_RV_{1}.vtk {2}/rv_{1}_curvature.txt'.format(vtks_dir, fr, subject_dir))
#        os.system('vtk2txt {0}/W_RV_{1}.vtk {2}/rv_{1}_wallthickness.txt'.format(vtks_dir, fr, subject_dir))
#        os.system('vtk2txt {0}/S_RV_{1}.vtk {2}/rv_{1}_signeddistances.txt'.format(vtks_dir, fr, subject_dir))
#        os.system('vtk2txt {0}/W_LVmyo_{1}.vtk {2}/lv_myo{1}_wallthickness.txt'.format(vtks_dir, fr, subject_dir))
#        os.system('vtk2txt {0}/C_LVmyo_{1}.vtk {2}/lv_myo{1}_curvature.txt'.format(vtks_dir, fr, subject_dir))
#        os.system('vtk2txt {0}/S_LVmyo_{1}.vtk {2}/lv_myo{1}_signeddistances.txt'.format(vtks_dir, fr, subject_dir))
        if fr == 'ED':
            fr_ = 'ed'
        if fr == 'ES':
            fr_ = 'es'
        # os.system('vtk2txt {0}/C_RV_{1}.vtk {2}/rv_{3}_curvature.txt'.format(vtks_dir, fr, subject_dir, fr_))
        # os.system('vtk2txt {0}/W_RV_{1}.vtk {2}/rv_{3}_wallthickness.txt'.format(vtks_dir, fr, subject_dir, fr_))
        # os.system('vtk2txt {0}/S_RV_{1}.vtk {2}/rv_{3}_signeddistances.txt'.format(vtks_dir, fr, subject_dir, fr_))
        mirtk.convert_pointset(
            str(subject.vtks_dir().joinpath("C_RV_{}.vtk".format(fr))),
            str(subject.dir.joinpath("rv_{}_curvature.txt".format(fr_))),
        )
        mirtk.convert_pointset(
            str(subject.vtks_dir().joinpath("W_RV_{}.vtk".format(fr))),
            str(subject.dir.joinpath("rv_{}_wallthickness.txt".format(fr_))),
        )
        mirtk.convert_pointset(
            str(subject.vtks_dir().joinpath("S_RV_{}.vtk".format(fr))),
            str(subject.dir.joinpath("rv_{}_signeddistances.txt".format(fr_))),
        )
        ############################################################################################################
        # os.system('vtk2txt {0}/W_LVmyo_{1}.vtk {2}/lv_myo{3}_wallthickness.txt'.format(vtks_dir, fr, subject_dir, fr_))
        # os.system('vtk2txt {0}/C_LVmyo_{1}.vtk {2}/lv_myo{3}_curvature.txt'.format(vtks_dir, fr, subject_dir, fr_))
        # os.system('vtk2txt {0}/S_LVmyo_{1}.vtk {2}/lv_myo{3}_signeddistances.txt'.format(vtks_dir, fr, subject_dir, fr_))
        mirtk.convert_pointset(
            str(subject.vtks_dir().joinpath("W_LVmyo_{}.vtk".format(fr))),
            str(subject.dir.joinpath("lv_myo{}_wallthickness.txt".format(fr_))),
        )
        mirtk.convert_pointset(
            str(subject.vtks_dir().joinpath("C_LVmyo_{}.vtk".format(fr))),
            str(subject.dir.joinpath("lv_myo{}_curvature.txt".format(fr_))),
        )
        mirtk.convert_pointset(
            str(subject.vtks_dir().joinpath("S_LVmyo_{}.vtk".format(fr))),
            str(subject.dir.joinpath("lv_myo{}_signeddistances.txt".format(fr_))),
        )
示例#7
0
    def run(self,
            cine: CineImages,
            ed_segmentation: Segmentation,
            landmark_path: Path,
            ED_mesh: PhaseMesh,
            output_dir: Path,
            overwrite: bool = False):
        # Forward image registration
        forward_dofs = {}
        output_dir.mkdir(parents=True, exist_ok=True)
        dof_dir = output_dir.joinpath("dof")
        dof_dir.mkdir(parents=True, exist_ok=True)
        for fr in tqdm(range(1, len(cine))):

            target = cine[fr - 1]
            source = cine[fr]
            par = self.ffd_motion_cfg
            dof_output = dof_dir.joinpath("ffd_{:02d}_to_{:02d}.dof.gz".format(
                fr - 1, fr))
            if not dof_output.exists():
                mirtk.register(str(target),
                               str(source),
                               parin=str(par),
                               dofout=str(dof_output))
            forward_dofs[fr] = dof_output

        # Compose inter-frame transformation fields #
        print("\n ...  Compose inter-frame transformation fields")
        compose_dofs = {}
        for fr in tqdm(range(2, len(cine))):
            dof_out = dof_dir.joinpath(
                "ffd_comp_00_to_{:02d}.dof.gz".format(fr))
            dofs = [str(forward_dofs[k]) for k in range(1, fr + 1)]
            if not dof_out.exists():
                mirtk.compose_dofs(*dofs, str(dof_out))
            compose_dofs[fr] = dof_out

        # Refine motion fields
        # Composition of inter-frame motion fields can lead to accumulative errors.
        # At this step, we refine the motion fields by re-registering the n-th frame with the ED frame.
        refine_dofs = {}
        print("\n ...  Refine motion fields")
        for fr in tqdm(range(2, len(cine))):
            target = cine[0]
            source = cine[fr]
            dofin = compose_dofs[fr]
            dofout = dof_dir.joinpath("ffd_00_to_{:02d}.dof.gz".format(fr))

            if not dofout.exists():
                mirtk.register(str(target),
                               str(source),
                               parin=str(self.ffd_refine_cfg),
                               dofin=str(dofin),
                               dofout=str(dofout))
            refine_dofs[fr] = dofout
        refine_dofs[1] = forward_dofs[1]
        landmark_init_dof = dof_dir.joinpath("landmarks.dof.gz")
        if not landmark_init_dof.exists() or overwrite:
            mirtk.register(
                str(landmark_path),
                str(self.template.landmark),
                model="Rigid",
                dofout=str(landmark_init_dof),
            )

        lv_endo_frame_0 = self.transform_mesh(
            source_mesh=self.template.lv_endo(Phase.ED),
            target_mesh=ED_mesh.lv.endocardium,
            landmark_init_dof=landmark_init_dof,
            output_dir=output_dir.joinpath("lv", "endo"),
            overwrite=overwrite,
        )

        # Transform the mesh
        print("\n ...   Transform the LV endo mesh")
        self.motion_mesh(frame_0_mesh=lv_endo_frame_0,
                         motion_dofs=refine_dofs,
                         output_dir=output_dir.joinpath("lv", "endo"),
                         overwrite=overwrite)

        lv_epi_frame_0 = self.transform_mesh(
            source_mesh=self.template.lv_epi(Phase.ED),
            target_mesh=ED_mesh.lv.epicardium,
            landmark_init_dof=landmark_init_dof,
            output_dir=output_dir.joinpath("lv", "epi"),
            overwrite=overwrite,
        )

        # Transform the mesh
        print("\n ...   Transform the LV epi mesh")
        self.motion_mesh(frame_0_mesh=lv_epi_frame_0,
                         motion_dofs=refine_dofs,
                         output_dir=output_dir.joinpath("lv", "epi"),
                         overwrite=overwrite)

        rv_frame_0 = self.transform_mesh(
            source_mesh=self.template.rv(Phase.ED),
            target_mesh=ED_mesh.rv.rv,
            landmark_init_dof=landmark_init_dof,
            output_dir=output_dir.joinpath("rv"),
            overwrite=overwrite,
        )

        # Transform the mesh
        print("\n ...   Transform the RV mesh")
        self.motion_mesh(frame_0_mesh=rv_frame_0,
                         motion_dofs=refine_dofs,
                         output_dir=output_dir.joinpath("rv"),
                         overwrite=overwrite)
        output_dir.joinpath("seg").mkdir(parents=True, exist_ok=True)
        for fr in tqdm(range(0, len(cine) - 1)):
            # os.system('mirtk transform-image {0}/lvsa_seg_fr00.nii.gz '
            #           '{2}/lvsa_seg_wrap_ffd_fr{1:02d}.nii.gz '
            #           '-dofin {3}/ffd_00_to_{1:02d}.dof.gz '
            #           '-invert -interp NN'
            #           .format(seg_slice_path, fr, pred_path, dof_path))
            mirtk.transform_image(
                str(ed_segmentation),
                str(output_dir.joinpath("seg").joinpath(f"lvsa_{fr}.nii.gz")),
                "-invert",
                "-v",
                interp="NN",
                dofin=refine_dofs[fr + 1])
示例#8
0
    def transform_mesh(source_mesh: MeshResource,
                       target_mesh: MeshResource,
                       landmark_init_dof: Path,
                       output_dir: Path,
                       overwrite: bool = False) -> MeshResource:
        output_dir.mkdir(parents=True, exist_ok=True)
        temp_dir = output_dir.joinpath("temp")
        output_dir.joinpath("vtk").mkdir(parents=True, exist_ok=True)
        dof_dir = temp_dir.joinpath("dof")
        dof_dir.mkdir(parents=True, exist_ok=True)
        rigid_dof = dof_dir.joinpath("srreg.dof.gz")
        affine_dof = dof_dir.joinpath("sareg.dof.gz")
        nonrigid_dof = dof_dir.joinpath("snreg.dof.gz")
        temp_srreg_vtk = MeshResource(temp_dir.joinpath("srreg.vtk"))
        transformed_vtk = MeshResource(output_dir.joinpath("vtk", "fr00.vtk"))
        if not rigid_dof.exists() or overwrite:
            mirtk.register_points(
                "-t",
                str(target_mesh),
                "-s",
                str(source_mesh),
                "-symmetric",
                dofin=str(landmark_init_dof),
                dofout=str(rigid_dof),
            )
        if not temp_srreg_vtk.exists() or overwrite:
            mirtk.transform_points(
                str(source_mesh),
                str(temp_srreg_vtk),
                "-invert",
                dofin=str(rigid_dof),
            )

        if not affine_dof.exists() or overwrite:
            mirtk.register_points(
                "-t",
                str(temp_srreg_vtk),
                "-s",
                str(target_mesh),
                "-symmetric",
                model="Affine",
                dofout=str(affine_dof),
            )

        if not nonrigid_dof.exists() or overwrite:
            mirtk.register(
                str(temp_srreg_vtk),
                str(target_mesh),
                "-par",
                "Point set distance correspondence",
                "CP",
                ds=20,
                model="FFD",
                dofin=str(affine_dof),
                dofout=str(nonrigid_dof),
            )
        if not transformed_vtk.exists() or overwrite:
            mirtk.transform_points(
                str(temp_srreg_vtk),
                str(transformed_vtk),
                dofin=str(nonrigid_dof),
            )
        return transformed_vtk