ivmartel / dwv

DICOM Web Viewer: open source zero footprint medical image library.
https://ivmartel.github.io/dwv/
GNU General Public License v3.0
1.63k stars 588 forks source link

Multiplanar Reconstruction (MPR) for multiframe dicom file #1536

Open komissarovea opened 8 months ago

komissarovea commented 8 months ago

I have single dicom file that contains 551 slices inside. dwv viewer displays just line (one slice) for saggital and coronal projections in mpr layout. Is it possible to fix? Or can you give me advice what utility or lib can split big dicom into separate slices?

image

Dicom info: MediaStorage is 1.2.840.10008.5.1.4.1.1.2.1 [Enhanced CT Image Storage] TransferSyntax is 1.2.840.10008.1.2.1 [Explicit VR Little Endian] NumberOfDimensions: 3 Dimensions: (551,551,551) SamplesPerPixel :1 BitsAllocated :16 BitsStored :12 HighBit :11 PixelRepresentation:0 ScalarType found :UINT16 PhotometricInterpretation: MONOCHROME2 PlanarConfiguration: 0 TransferSyntax: 1.2.840.10008.1.2.1 Origin: (0,0,110.2) Spacing: (0.2,0.2,-0.2) DirectionCosines: (1,0,0,0,1,0) Rescale Intercept/Slope: (-1000,1) Orientation Label: AXIAL

ivmartel commented 8 months ago

The library does not perform MPR on multi-frame data since it considers multi-frames as different time points, not volume. I do not know any tool for splitting the data...

komissarovea commented 8 months ago

@ivmartel thanks for reply and for your great library! I found the way how to split multi-frame dicom and prepare it for dicom viewer using this project: https://github.com/fo-dicom/fo-dicom

arunjoshtech commented 8 months ago

Can you give example page link of F DICOM. if I click the link it takes me to general github page

komissarovea commented 8 months ago

Can you give example page link of F DICOM. if I click the link it takes me to general github page

@arunjoshtech here is my sample that splits dicom:

using FellowOakDicom.Imaging;
using FellowOakDicom.IO.Buffer;
using FellowOakDicom;
using System.IO;
using System.Threading.Tasks;

public static class DicomConvert
{
    public static async Task<string> SplitDicom(string filePath)
    {
        string resultPath = filePath;
        if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath))
        {
            string dirPath = Path.GetDirectoryName(filePath);
            string fileName = Path.GetFileNameWithoutExtension(filePath);
            resultPath = Path.Combine(dirPath, $"{fileName}_dir");
            Directory.CreateDirectory(resultPath);

            DicomFile inputFile = await DicomFile.OpenAsync(filePath);
            DicomDataset inputDataset = inputFile.Dataset;
            DicomPixelData inputData = DicomPixelData.Create(inputDataset);

            int instanceNumber = inputDataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 0);
            decimal thickness = inputDataset.GetSingleValueOrDefault<decimal>(DicomTag.SliceThickness, 0);

            for (var i = 1; i <= inputData.NumberOfFrames; i++)
            {
                DicomDataset dataset = inputDataset.Clone();
                dataset.AddOrUpdate(new DicomDecimalString(DicomTag.ImagePositionPatient, 0, 0, thickness * i));
                dataset.AddOrUpdate(new DicomDecimalString(DicomTag.PixelSpacing, thickness, thickness));
                dataset.AddOrUpdate(DicomTag.InstanceNumber, instanceNumber + i);

                DicomPixelData pixelData = DicomPixelData.Create(dataset, true);
                IByteBuffer buffer = inputData.GetFrame(inputData.NumberOfFrames - i);
                pixelData.AddFrame(buffer);

                DicomFile newFile = new DicomFile(dataset);
                newFile.Save(Path.Combine(resultPath, $"{i:D4}.dcm"));
            }
        }

        return resultPath;
    }
}