Beispiel #1
0
        /// <summary>
        /// Uses the ANTS implementation of the N4 bias correction algorithm to correct the given file.
        /// </summary>
        /// <param name="inputFile">Path to input nifti file.</param>
        /// <param name="updates">Event handler for updates from the process</param>
        /// <returns>Path for output nifti file.</returns>
        public static string AntsN4(string inputFile, DataReceivedEventHandler updates = null)
        {
            string niftiInPath  = Path.GetFullPath(inputFile);
            string niftiOutPath = Path.GetFullPath(inputFile + ".antsN4.out.nii");
            var    args         = $"-i \"{niftiInPath}\" -o \"{niftiOutPath}\"";

            Log.GetLogger().Info("    --Starting AntsN4..");
            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.N4BiasFieldCorrection, args, outputDataReceived: updates, errorOccuredInProcess: updates);
            return(niftiOutPath);
        }
Beispiel #2
0
        public static void ConvertBmpToDicom(string bmpFilepath, string dicomFilePath, string dicomHeadersFilePath = "")
        {
            var arguments = string.Empty;

            if (!string.IsNullOrEmpty(dicomHeadersFilePath))
            {
                arguments = $"-df \"{dicomHeadersFilePath}\" "; // Copy dicom headers from dicom file: -df = dataset file
            }
            arguments += $"-i BMP \"{bmpFilepath}\" \"{dicomFilePath}\"";
            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.img2dcm, arguments);
        }
Beispiel #3
0
        /// <summary>
        /// Uses the BrainSuite BSE tool to extract the brain from the given Nifti file path.
        /// </summary>
        /// <param name="inputFile">Path to .nii file which needs a brain extractin'</param>
        /// <param name="updates">Event handler to accept progress updates from the tool.</param>
        /// <returns>The path of the output file.</returns>
        public static string BrainSuiteBSE(string inputFile, DataReceivedEventHandler updates = null)
        {
            string niftiInPath  = Path.GetFullPath(inputFile);
            string niftiOutPath = Path.GetFullPath(inputFile + ".bse.out.nii");

            var args = $"--auto --trim -i \"{niftiInPath}\" -o \"{niftiOutPath}\"";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.bse, args, outputDataReceived: updates);


            return(niftiOutPath);
        }
Beispiel #4
0
        public static string CMTKResliceUsingPrevious(string floatingFile, string niftiRefPath, DataReceivedEventHandler updates = null)
        {
            Environment.SetEnvironmentVariable("CMTK_WRITE_UNCOMPRESSED", "1");
            string niftiOutPath = floatingFile + ".cmtkrego.out.nii";

            string regOutPath = "reg";

            var args = $"-o \"{niftiOutPath}\" --floating \"{floatingFile}\" \"{niftiRefPath}\" \"{regOutPath}\"";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.reformatx, args, outputDataReceived: updates);

            return(niftiOutPath);
        }
Beispiel #5
0
        public static string ANTSApplyTransforms(string floatingFile, string referenceFile, DataReceivedEventHandler updates = null)
        {
            floatingFile  = Path.GetFullPath(floatingFile);
            referenceFile = Path.GetFullPath(referenceFile);

            string niftiOutPath = Path.Combine("warped.nii");

            string args = $"-d 3 --float 1 -i \"{floatingFile}\" -r \"{referenceFile}\" -o \"{niftiOutPath}\" -n Linear -t \"{niftiOutPath}0GenericAffine.mat\"";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.antsApplyTransforms, args, outputDataReceived: updates);

            return(niftiOutPath);
        }
Beispiel #6
0
        /// <summary>
        /// Uses the BrainSuite BSE tool to extract the brain from a given INifti.
        /// </summary>
        /// <param name="input">Nifti which contains the brain to be extracted</param>
        /// <param name="updates">Data handler for updates from the BSE tool.</param>
        /// <returns>The INifti containing the extracted brain.</returns>
        public static INifti <float> BrainSuiteBSE(INifti <float> input, DataReceivedEventHandler updates = null)
        {
            // Setup our temp file names.
            string niftiInPath  = Path.GetFullPath(Tools.TEMPDIR + input.GetHashCode() + ".bse.in.nii");
            string niftiOutPath = Path.GetFullPath(Tools.TEMPDIR + input.GetHashCode() + ".bse.out.nii");

            // Write nifti to temp directory.
            input.WriteNifti(niftiInPath);

            var args = $"--auto --trim -i \"{niftiInPath}\" -o \"{niftiOutPath}\"";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.bse, args, outputDataReceived: updates);

            var output = input.DeepCopy(); // Sometimes this messes with the header and gives us a 4-up???

            output.ReadNifti(niftiOutPath);

            return(output);
        }
Beispiel #7
0
        /// <summary>
        /// Uses the ANTS implementation of the N4 bias correction algorithm.
        /// </summary>
        /// <param name="input">The input nifti to be corrected</param>
        /// <param name="updates">Event handler for updates from the process</param>
        /// <returns>New, corrected nifti</returns>
        public static INifti <float> AntsN4(INifti <float> input, DataReceivedEventHandler updates = null)
        {
            // Setup our temp file names.
            string niftiInPath  = Path.GetFullPath(Tools.TEMPDIR + input.GetHashCode() + ".antsN4.in.nii");
            string niftiOutPath = Path.GetFullPath(Tools.TEMPDIR + input.GetHashCode() + ".antsN4.out.nii");

            // Write nifti to temp directory.
            input.WriteNifti(niftiInPath);

            var args = $"-i \"{niftiInPath}\" -o \"{niftiOutPath}\"";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.N4BiasFieldCorrection, args, outputDataReceived: updates);

            var output = input.DeepCopy();

            output.ReadNifti(niftiOutPath);
            output.RecalcHeaderMinMax();

            return(output);
        }
Beispiel #8
0
        public static string ANTSRegistration(string floatingFile, string fixedFile, DataReceivedEventHandler updates = null)
        {
            string niftiOutPath = floatingFile + "warped.nii";

            // ANTS didn't like me splitting args into a nicely tabbed string so it's all one big line.
            // --dimensionality 3 :: we have a 3-d image
            // --float 1 :: we want to keep things floating point
            // --interpolation Linear :: using linear interpolation for the warped image
            // --use-histogram-matching 0 :: histogram matching is pre-normalisation (we're avoiding this in case we have hyper-intense fat on one and not the other)
            // --initial-moving-transform [{fixedFile},{floatingFile}, 1] :: inputs
            // --transform Rigid[0.1] :: using an rigid transform (6 degrees of freedom, linear)
            // --metric MI[{fixedFile},{floatingFile},1,32,Regular,0.25] :: metric is mutual information, although we could use cross correlation so long as we're registering the same sequence type
            // --convergence [1000x500x250x100,1e-6,10] :: convergence is the iterations at each level and the threashold for imporovement in the metric
            // --shrink-factors 8x4x2x1 :: shrink factors control the resolution at each level
            // --smoothing-sigmas 3x2x1x0vox :: not really sure what smoothing sigmas do but the values should be fine
            // --output [_, {niftiOutPath}] :: output the transform value + our sweet nifti file.
            var args = $" --dimensionality 3 --float 1 --interpolation Linear --use-histogram-matching 0 --initial-moving-transform [\"{fixedFile}\",\"{floatingFile}\", 1] --transform Affine[0.1] --metric MI[\"{fixedFile}\",\"{floatingFile}\",1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --output [\"{niftiOutPath}\", \"{niftiOutPath}\"]";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.antsRegistration, args, outputDataReceived: updates);

            return(niftiOutPath);
        }
Beispiel #9
0
        /// <summary>
        /// Converts the given Dicom path to a nifti file which is loaded and returned as a nifti object.
        /// </summary>
        /// <param name="dicomPath">Path to the DICOM</param>
        /// <param name="updates">Event handler to handle updates.</param>
        /// <returns></returns>
        public static string Dcm2Nii(string dicomPath, string name, DataReceivedEventHandler updates = null)
        {
            if (!FileSystem.DirectoryIsValidAndNotEmpty(dicomPath))
            {
                Log.GetLogger().Error("Directory " + dicomPath + " does not seem to exist, or is empty.");
                return(null);
            }

            var niftiPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(dicomPath), name));

            var tmpDir = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(niftiPath), "tmp"));

            if (Directory.Exists(tmpDir))
            {
                Directory.Delete(tmpDir, true);
            }
            FileSystem.DirectoryExistsIfNotCreate(tmpDir);


            var args = $" -o \"{tmpDir}\" \"{dicomPath}\"";

            ProcessBuilder.CallExecutableFile(CapiConfig.GetConfig().Binaries.dcm2niix, args, outputDataReceived: updates);

            if (!Directory.Exists(tmpDir))
            {
                throw new DirectoryNotFoundException("dcm2niix output folder does not exist!");
            }
            var outFiles = Directory.GetFiles(tmpDir);
            // Rather than cracking a tanty when we have more than one nii in the stack, we're just going to use the biggest one.
            // This is in case we have a reference slide at the front or end of the dicom stack, which can happen.
            var nims = outFiles.Where(f => Path.GetExtension(f) == ".nii").OrderByDescending(f => new FileInfo(f)?.Length);
            var nim  = nims.FirstOrDefault();

            if (nim == null)
            {
                if (!File.Exists(CapiConfig.GetConfig().Binaries.dcm2niix))
                {
                    Log.GetLogger().Error("Could not find dcm2niix at: " + CapiConfig.GetConfig().Binaries.dcm2niix);
                }

                var log = Log.GetLogger();
                log.Error("Could not find valid output for dcm2niix. Files output were: ");

                foreach (var of in outFiles)
                {
                    log.Error($"[{of}]");
                }

                throw new FileNotFoundException("Could not find output of dcm2niix");
            }

            if (File.Exists(niftiPath))
            {
                File.Delete(niftiPath);
            }
            File.Move(nim, niftiPath);

            Directory.Delete(tmpDir, true);

            return(niftiPath);
        }