Пример #1
0
    //RENDER FIRST DICOM FILE FROM DICOMDIR TO TEXTURE2D
    public static Texture2D CreateTextureFromFirstDicom(string path, bool anonymize, ref dicomInfoTools info)
    {
        string stream = null;

        DirectoryInfo dicomDirectoryInfo = new DirectoryInfo(path);

        foreach (var dicom in dicomDirectoryInfo.GetFiles(".", SearchOption.AllDirectories))
        {
            if (DicomFile.HasValidHeader(dicom.FullName))
            {
                stream = dicom.FullName;
                break;
            }
        }

        Debug.Log(stream);

        var file = DicomFile.Open(stream);

        Debug.Log($"Dicom File at {path} loaded");

        info = new dicomInfoTools(file, anonymize);

        Texture2D texture = new DicomImage(file.Dataset).RenderImage().As <Texture2D>();

        Debug.Log($"Single 2D Texture loaded");

        return(texture);
    }
Пример #2
0
    //CREATE A COMPLETE TEXTURE3D FROM A DICOMDIR
    public static Texture3D createTexture3DAsAssetScript(List <string> fileNameList, dicomInfoTools dicomInformation, int textureWidth, int textureHeight, int textureDepth)
    {
        /////Copy pixel data of 2D Textures in array into color array
        var colorsForCubeTexture = CreateColorArrayFromDicomdir(fileNameList, dicomInformation, textureWidth, textureHeight, textureDepth);

        //Debug.Log($" Color: {colorsForCubeTexture[15000000]}");

        /////Map 2D Texture color pixels to 3D Texture
        var cubeTexture = CreateTexture3D(colorsForCubeTexture, textureWidth, textureHeight, textureDepth);

        //Debug.Log($"3D Texture created.");

        return(cubeTexture);
    }
Пример #3
0
    //RENDER DICOM FILE TO TEXTURE2D
    public static Texture2D CreateTextureFromDicom(string path, bool anonymize, ref dicomInfoTools info)
    {
        var stream = File.OpenRead(path);

        var file = DicomFile.Open(stream);

        Debug.Log($"Dicom File at {path} loaded");

        info = new dicomInfoTools(file, anonymize);

        Texture2D texture = new DicomImage(file.Dataset).RenderImage().As <Texture2D>();

        Debug.Log($"Single 2D Texture loaded");

        return(texture);
    }
Пример #4
0
    //IMPORT DICOM SLICES
    public void CreateTexture3DAssets()
    {
        try
        {
            savedTextureDestinationPath = Path.Combine(rootPath, savedTextureDestinationDirectory);
            bool exists = Directory.Exists(savedTextureDestinationPath); // Create/Check for Folder: Saved Slices

            if (!exists)
            {
                Directory.CreateDirectory(savedTextureDestinationPath);
            }

            ressourceDestinationPath     = Path.Combine("Assets/Resources/MediVR/Textures", assetDestinationDirectory); //Set some paths
            thisRessourceDestinationPath = Path.Combine(ressourceDestinationPath, userDefinedFolderName);

            exists = Directory.Exists(ressourceDestinationPath); // Create/Check for Folder: Dicom 3D Textures

            if (!exists)
            {
                Directory.CreateDirectory(ressourceDestinationPath);
            }

            exists = Directory.Exists(thisRessourceDestinationPath); // Create/Check for Folder: Dicom 3D Textures/dicomFileDirecory (CT_Series)

            if (!exists)
            {
                Directory.CreateDirectory(thisRessourceDestinationPath);
            }


            //Debug.Log($"Path to Directory: {dirPath}");
            Debug.Log($"Path to Directory: {userDefinedDicomPath}");
            Debug.Log($"Path to 3D Textures folder in Ressources Directory: {ressourceDestinationPath}");
            //Debug.Log($"Path to {dicomFileDirectory} folder in Ressources Directory: {thisRessourceDestinationPath}");
            Debug.Log($"Path to {userDefinedFolderName} folder in Ressources Directory: {thisRessourceDestinationPath}");

            string pathTo3DTextures = "MediVR/Textures/" + assetDestinationDirectory + "/" + userDefinedFolderName; //dicomFileDirectory;

            //Debug.Log($"Initializing 3D Texture from {dirPath}.");
            Debug.Log($"Initializing 3D Texture from {userDefinedDicomPath}.");

            //var dicomDirectoryInfo = new DirectoryInfo(dirPath);
            var dicomDirectoryInfo = new DirectoryInfo(userDefinedDicomPath);

            int dicomFileCount = dicomDirectoryInfo.GetFiles().Length;
            Debug.Log($"Files found in Directory: {dicomFileCount}");
            //Debug.Log($"Loading Dicom files from Directory {dirPath} into Array");
            Debug.Log($"Loading Dicom files from Directory {userDefinedDicomPath} into Array");

            //READ FILE NAMES

            List <string> dicomFileNameList = new List <string>();

            foreach (var dicomFile in dicomDirectoryInfo.GetFiles(".", SearchOption.AllDirectories))
            {
                if (DicomFile.HasValidHeader(dicomFile.FullName))
                {
                    dicomFileNameList.Add(dicomFile.FullName);
                }
            }

            if (dicomFileNameList.Count != 0)
            {
                Debug.Log($"Valid Dicom files found in Directory: {dicomFileNameList.Count}. File names loaded onto list.");

                if (reverseSliceOrder)
                {
                    dicomFileNameList.Reverse();
                }

                textureDepth = dicomImageTools.NextPow2(dicomFileNameList.Count);

                var file = DicomFile.Open(dicomFileNameList[0]);

                dicomInformation = new dicomInfoTools(file, anonymizeDicomMetaData);

                Debug.Log($"Metadata loaded from file: {dicomFileNameList[0]}.");

                //////// SAVE METADATA

                metadataRessourceName = thisRessourceDestinationPath + "/" + userDefinedFolderName + "_3DTexture_" + textureWidth + "x" + textureHeight + "x" + textureDepth + "_MetaData.XML";

                XmlSerializer serializer = new XmlSerializer(typeof(dicomInfoTools));
                using (TextWriter writer = new StreamWriter(metadataRessourceName))
                {
                    serializer.Serialize(writer, dicomInformation);
                }

                Debug.Log($"Metadata saved to file: {metadataRessourceName}.");

                //////// SAVE SINGLE SLICES

                sliceRessourceName = userDefinedFolderName + "_3DTexture_" + textureWidth + "x" + textureHeight + "x" + textureDepth + "_Slice";

                dicomSlices = dicomImageTools.CreateNumberedTextureArrayFromDicomdir(dicomFileNameList, 5);
                dicomImageTools.SaveTextureArrayAsAssets(dicomSlices, thisRessourceDestinationPath, sliceRessourceName);

                //////// SAVE 3D TEXTURE

                textureRessourceName = userDefinedFolderName + "_3DTexture_" + textureWidth + "x" + textureHeight + "x" + textureDepth;
                threeDimTexture      = dicomImageTools.createTexture3DAsAssetScript(dicomFileNameList, dicomInformation, textureWidth, textureHeight, textureDepth);
                dicomImageTools.exportTexture3DToAsset(threeDimTexture, thisRessourceDestinationPath, textureRessourceName);

                //////// SAVE IMPORTED DIRECTORY NAMES

                SaveImportedTextureDirectoryNames();
            }
            else
            {
                Debug.Log($"Valid Dicom files found in Directory: {dicomFileNameList.Count}. Import failed. Try with valid directory.");
            }
        }
        catch (ArgumentException aE)//else
        {
            Debug.Log($"Exception: {aE.ToString()} thrown. Path to directory invalid. Try with valid directory.");
        }
    }
Пример #5
0
    // Start is called before the first frame update
    void Start()
    {
        //////// PATHS

        dirName = setCurrentDirectory.currentDirectory;
        destinationTextureDirName = initialImportDicom.assetDestinationDirectory;
        textureDestinationPath    = initialImportDicom.savedTextureDestinationPath;

        //////// LOAD 3D TEXTURE

        if (dirName != null)
        {
            pathTo3DTextures = "MediVR/Textures/" + destinationTextureDirName + "/" + dirName;

            loadedTextures = Resources.LoadAll(pathTo3DTextures, typeof(Texture3D)); //TRY TO LOAD 3D TEXTURE FROM FOLDER
        }

        if (loadedTextures != null)
        {
            if (loadedTextures.Length > 0)
            {
                threeDimTexture = (Texture3D)loadedTextures[0];

                //Debug.Log($"{loadedTextures[0].name}");

                //////// LOAD METADATA

                metadataName = pathTo3DTextures + "/" + loadedTextures[0].name + "_MetaData";

                var resource = Resources.Load <TextAsset>(metadataName);
                if (resource != null)
                {
                    metaData = resource.text;
                }

                //Debug.Log($"{metaData}");

                if (metaData != null)
                {
                    metaData = metaData.Replace("&#x0;", "");

                    XmlSerializer deserializer = new XmlSerializer(typeof(dicomInfoTools));

                    using (StringReader reader = new StringReader(metaData))
                    {
                        object obj = deserializer.Deserialize(reader);

                        dicomInformation = (dicomInfoTools)obj;
                        dicomInformation.GetDicomInfoString();
                    }
                }

                //Debug.Log($"{dicomInformation.PatientId}");

                //Debug.Log($"{metaData}");

                //////// LOAD SINGLE SLICES

                loaded2DTextures = Resources.LoadAll(pathTo3DTextures, typeof(Texture2D)); //TRY TO LOAD 2D TEXTURES FROM FOLDER

                if (loaded2DTextures != null)
                {
                    if (loaded2DTextures.Length == 5)
                    {
                        dicomSlices = new Texture2D[5];

                        for (int i = 0; i < loaded2DTextures.Length; i++)
                        {
                            dicomSlices[i] = (Texture2D)loaded2DTextures[i];
                        }
                    }
                }
            }
        }
    }
Пример #6
0
    /////CREATE COLOR ARRAY FROM LIST OF FILES IN DICOMDIR. COLOR ARRAY IS USED TO SET PIXELS OF TEXTURE3D
    public static Color[] CreateColorArrayFromDicomdir(List <string> fileNameList, dicomInfoTools dicomInformation, int textureWidth, int textureHeight, int textureDepth)
    {
        //Debug.Log($"Preparing stuff for color array creation.");

        var w = textureWidth;
        var h = textureHeight;
        var d = textureDepth;

        var textureCount = 0;

        Color[] colors = new Color[w * h * d];

        Debug.Log($"Populating color array for 3D Texture");

        var slicesCount = -1;

        //CENTRE SLICES IN TEXTURE3D
        var sliceCountOffset    = Mathf.FloorToInt(d - fileNameList.Count) / 2;
        var invSliceCountOffset = sliceCountOffset + fileNameList.Count;

        //SET INITIAL HOUNSFIELD VALUES
        short hounsfieldUnitMaximumIntenisty = 3071;
        short hounsfieldUnitMinimumIntenisty = -1024;
        short hounsfieldUnitRange            = (short)(hounsfieldUnitMaximumIntenisty - hounsfieldUnitMinimumIntenisty);

        //GET FRAME SIZE
        int dicomFrameWidth  = dicomInformation.ImageWidth;
        int dicomFrameHeight = dicomInformation.ImageHeight;

        Texture2D newDicomTex = null;

        Color[] dicomOriginalTextureRescaledHU = new Color[dicomFrameWidth * dicomFrameHeight];

        //SET COMPRESSION TYPE
        DicomTransferSyntax defaultDicomTransferSyntax = DicomTransferSyntax.ImplicitVRLittleEndian;

        bool rescale = false;

        //GET RESCALE PARAMETERS
        short  rescaleSlope     = (short)dicomInformation.ImageRescaleSlope;
        short  rescaleIntercept = (short)dicomInformation.ImageRescaleIntercept;
        string modality         = dicomInformation.Modality;

        //APPLY RESCALE PARAMETERS ONLY FOR CT IMAGES
        if (modality == "CT")
        {
            rescale = true;
        }

        Debug.Log($"Image frame width: {dicomFrameWidth} pixels and frame height: {dicomFrameHeight} pixels.");
        Debug.Log($"Image Transfer Syntax: {dicomInformation.ImageTransferSyntax}. Applying Decompression Transfer Syntax: {defaultDicomTransferSyntax}.");
        Debug.Log($"Image Rescale Slope: {rescaleSlope} and Rescale Intercept: {rescaleIntercept}.");

        Debug.Log($"Modality is: {modality} and Rescale is set to: {rescale}.");

        //Debug.Log($"Done peparing stuff for color array creation.");

        for (int z = 0; z < d; z++)
        {
            textureCount++;

            if (z > sliceCountOffset && z < invSliceCountOffset)
            {
                slicesCount++;

                //Debug.Log($"Opening Dicom File Nr. {z - sliceCountOffset}.");

                //DECOMPRESS DICOM FILE

                var dicomFileCompressed = DicomFile.Open(fileNameList[slicesCount]);

                var dicomFileUncompressed = new DicomFile();

                if (dicomFileCompressed.Dataset.InternalTransferSyntax.IsEncapsulated)
                {
                    dicomFileUncompressed = dicomFileCompressed.Clone(defaultDicomTransferSyntax);
                }
                else
                {
                    dicomFileUncompressed = dicomFileCompressed;
                }

                dicomFileUncompressed = dicomFileCompressed.Clone(defaultDicomTransferSyntax);

                //GET RAW PIXEL DATA

                var dicomFramePixelData = DicomPixelData.Create(dicomFileUncompressed.Dataset);

                var dicomFrame = dicomFramePixelData.GetFrame(0);

                //Debug.Log($"Copying Bytes into Array.");

                byte[] dicomFrameByteArray = dicomFrame.Data;

                //Debug.Log($"Transforming Bytes to Shorts.");

                //CONVERT BYTES TO SHORTS

                short[] dicomFrameShortArray = new short[(int)Math.Ceiling((double)(dicomFrameByteArray.Length / 2))];
                Buffer.BlockCopy(dicomFrameByteArray, 0, dicomFrameShortArray, 0, dicomFrameByteArray.Length);

                //Debug.Log($"Transforming complete.");

                //ITERATE THROUGH PIXEL DATA, PARALLELIZED FOR SPEED
                Parallel.For(0, dicomFramePixelData.Width * dicomFramePixelData.Height, x =>
                {
                    int dicomFileHUPixel = 0;

                    //APPLY RESCALE PARAMETERS IF IMAGE COMES FROM CT

                    if (rescale)
                    {
                        dicomFileHUPixel = (dicomFrameShortArray[x] * rescaleSlope) + rescaleIntercept;
                    }
                    else
                    {
                        dicomFileHUPixel = dicomFrameShortArray[x];
                    }

                    //CONVERT RAW PIXEL VALUES INTO HOUSFIELD UNITS AND THEN INTO COLOR FLOAT VALUES BETWEEN 0 AND 1

                    float dicomFileRescaledHUIntensity = ((float)dicomFileHUPixel - (float)hounsfieldUnitMinimumIntenisty) / hounsfieldUnitRange;
                    Color readyRescaledHUColor         = new Color(dicomFileRescaledHUIntensity, dicomFileRescaledHUIntensity, dicomFileRescaledHUIntensity);
                    dicomOriginalTextureRescaledHU[x]  = readyRescaledHUColor;
                });

                //SET COLOR ARRAY TO TEXTURE2D

                newDicomTex = new Texture2D(dicomFramePixelData.Width, dicomFramePixelData.Height, TextureFormat.ARGB32, true, true);
                newDicomTex.SetPixels(dicomOriginalTextureRescaledHU);
                newDicomTex.Apply();

                //Debug.Log($"Texture created. Rescaling texture.");

                //RESCALE IMAGE, TYPICALLY IF LARGER THAN 256X256

                if (w < dicomFramePixelData.Width || h < dicomFramePixelData.Height)
                {
                    TextureScale.Bilinear(newDicomTex, w, h);
                }
            }

            //Debug.Log($"Building color slice from texture.");

            //BUILD COLOR ARRAY FOR 3D TEXTURE
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    //INDEX FOR PIXEL VALUE IN COLOR ARRAY
                    var idx = x + (y * w) + (z * (w * h));

                    Color c = Color.clear;

                    if (z > sliceCountOffset && z < invSliceCountOffset)
                    {
                        c = newDicomTex.GetPixel(x, (h - y));
                    }

                    colors [idx] = c;
                }
            }

            //Debug.Log($"Slice added to color array.");
        }

        Debug.Log($"Textures loaded into color array: {textureCount}");

        return(colors);
    }