/// <summary>Anonymizes a Dicom file (dataset + metadata)</summary>
        /// <param name="file">The file containing the dataset to be altered</param>
        public DicomFile Anonymize(DicomFile file)
        {
            file = file ?? throw new ArgumentNullException(nameof(file));

            var transferSyntax = file.FileMetaInfo.Contains(DicomTag.TransferSyntaxUID) ? file.FileMetaInfo.TransferSyntax : null;
            var m = _mode;

            if (m == Mode.clone)
            {
                file = file.Clone();
                m    = Mode.inplace;
            }

            var ds = DoAnonymization(file.Dataset, new Stack <TagOrIndex>(), m);

            if (file.FileMetaInfo != null)
            {
                file = new DicomFile(ds);
                file.FileMetaInfo.ImplementationVersionName    = "";
                file.FileMetaInfo.SourceApplicationEntityTitle = "";
                if (transferSyntax != null)
                {
                    file.FileMetaInfo.AddOrUpdate(DicomTag.TransferSyntaxUID, transferSyntax);
                }
            }

            return(file);
        }
예제 #2
0
        public void EncodeDecodeRLE16()
        {
            var files = Directory.GetFiles(@"Test Data");

            foreach (var testFile in files)
            {
                try
                {
                    var       myOriginalDicomFilePath = testFile;
                    DicomFile myOriginalDicomFile     = DicomFile.Open(myOriginalDicomFilePath);
                    DicomFile myNewFile = myOriginalDicomFile.Clone(DicomTransferSyntax.RLELossless);
                    DicomFile myResFile = myNewFile.Clone(myOriginalDicomFile.Dataset.InternalTransferSyntax);

                    // Supporting 16bit encoded images
                    var myBitsAllocated = myResFile.Dataset.GetSingleValue <ushort>(DicomTag.BitsAllocated);
                    if (myBitsAllocated == 16)
                    {
                        byte[] myOriginalBytes = DicomPixelData.Create(myOriginalDicomFile.Dataset).GetFrame(0).Data;
                        byte[] myResBytes      = DicomPixelData.Create(myResFile.Dataset).GetFrame(0).Data;

                        if (!myOriginalBytes.SequenceEqual(myResBytes))
                        {
                            // Number of different bytes
                            int myDiffCount = myResBytes.Where((inT, inI) => inT != myOriginalBytes[inI]).Count();
                            Assert.Equal(0, myDiffCount);
                            Trace.WriteLine("Diff count " + myDiffCount);

                            // Run through all image
                            for (var myIndex = 0; myIndex < myOriginalBytes.Length; myIndex += 2)
                            {
                                // Get Pixel value from Original image
                                byte   myOriginalByte1      = myOriginalBytes[myIndex];
                                byte   myOrginalByte2       = myOriginalBytes[myIndex + 1];
                                ushort myOriginalPixelValue =
                                    BitConverter.ToUInt16(new byte[] { myOriginalByte1, myOrginalByte2 }, 0);

                                // Get Pixel value from RoundTrip image
                                byte   myResByte1      = myResBytes[myIndex];
                                byte   myResByte2      = myResBytes[myIndex + 1];
                                ushort myResPixelValue = BitConverter.ToUInt16(new byte[] { myResByte1, myResByte2 }, 0);

                                // If Value are different
                                if (myOriginalPixelValue != myResPixelValue)
                                {
                                    Trace.Write("Diff:" + Math.Abs(myOriginalPixelValue - myResPixelValue));
                                    Trace.Write(
                                        $" Original Value: {myOriginalPixelValue} ({myOriginalByte1}, {myOrginalByte2})");
                                    Trace.WriteLine($" Res Value: {myResPixelValue} ({myResByte1}, {myResByte2})");
                                    break;
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    // ignore
                }
            }
        }
예제 #3
0
        public void AddFile(string FileName)
        {
            if (!File.Exists(FileName) || !DicomFile.HasValidHeader(FileName))
            {
                return;
            }
            DicomFile dcmFile = DicomFile.Open(FileName);

            DicomFile tmpFile = dcmFile.Clone();

            var item = tmpFile.Dataset.Get <DicomItem>(DicomTag.PixelData);

            if (item == null)
            {
                return;
            }

            DicomImage dcmImage = new DicomImage(tmpFile.Dataset);

            _frame = dcmFile.Dataset.Get(DicomTag.NumberOfFrames, 0);//如果该字段不存在,则默认值为1


            // Image img = dcmImage.RenderImage(0);
            Image img = ZoomPicture(dcmImage.RenderImage(0), 150, 150);

            img = SetIconInfo(img, _frame, m_IconList.Count);

            DicomIcon icon = new DicomIcon();

            icon.m_Img        = img;
            icon.m_FileName   = FileName;
            icon.m_DicomFile  = dcmFile;
            icon.m_DicomImage = dcmImage;
            m_IconList.Add(icon);
        }
예제 #4
0
        public static List <string> ExtractMultiframes2Singleframe(string src)
        {
            List <string> destFiles  = new List <string>();
            DicomFile     dcmFile    = DicomFile.Open(src);
            DicomDataset  dcmDataset = dcmFile.Dataset;
            int           frames     = dcmFile.Dataset.Get <int>(DicomTag.NumberOfFrames);

            if (frames > 1)
            {
                for (int i = 0; i < frames; ++i)
                {
                    try
                    {
                        DicomFile tmpFile    = dcmFile.Clone();
                        string    seriesiuid = tmpFile.Dataset.Get <string>(DicomTag.SeriesInstanceUID, "1.2.3.4.5.6.7.8.9.2234");
                        tmpFile.Dataset.Remove(new DicomTag[] { DicomTag.InstanceNumber, DicomTag.NumberOfFrames, DicomTag.SOPInstanceUID, DicomTag.PixelData });
                        tmpFile.Dataset.Add <int>(DicomTag.NumberOfFrames, 1);
                        tmpFile.Dataset.Add <string>(DicomTag.SOPInstanceUID, string.Format("{0}.{1}", seriesiuid, i));
                        tmpFile.Dataset.Add <int>(DicomTag.InstanceNumber, i + 1);
                        IByteBuffer pixelData = ExtractSingleFrame(dcmDataset, i);
                        CreateAndAddPixelData(tmpFile.Dataset, pixelData);
                        string srcName     = Path.GetFileName(src);
                        string tmpFileName = string.Format(@"{2}linkingmed.{1}.frame{0}.dcm", i, srcName.Split('.')[0], Path.GetTempPath());
                        tmpFile.Save(tmpFileName);
                        destFiles.Add(tmpFileName);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(string.Format("Errors:{0},Details:{1}", e.Message + e.StackTrace));
                    }
                }
            }
            return(destFiles);
        }
예제 #5
0
        /// <summary>
        /// returns dicomFile in the content type given by finalContentType in a HttpResponseMessage.
        /// If content type is dicom, transfer syntax must be set to the given transferSyntax parameter.
        /// </summary>
        /// <param name="dicomFile"></param>
        /// <param name="finalContentType"></param>
        /// <param name="transferSyntax"></param>
        /// <returns></returns>
        private HttpResponseMessage ReturnImageAsHttpResponse(DicomFile dicomFile, string finalContentType, string transferSyntax)
        {
            MediaTypeHeaderValue header = null;
            Stream streamContent        = null;

            if (finalContentType == JpegImageContentType)
            {
                DicomImage image = new DicomImage(dicomFile.Dataset);
                Bitmap     bmp   = image.RenderImage(0).As <Bitmap>();

                //When an image/jpeg MIME type is returned, the image shall be encoded using the JPEG baseline lossy 8
                //bit Huffman encoded non-hierarchical non-sequential process ISO/IEC 10918.
                //TODO Is it the case with default Jpeg format from Bitmap?
                header        = new MediaTypeHeaderValue(JpegImageContentType);
                streamContent = new MemoryStream();
                bmp.Save(streamContent, ImageFormat.Jpeg);
                streamContent.Seek(0, SeekOrigin.Begin);
            }
            else if (finalContentType == AppDicomContentType)
            {
                //By default, the transfer syntax shall be
                //"Explicit VR Little Endian".
                //Note: This implies that retrieved images are sent un-compressed by default.
                DicomTransferSyntax requestedTransferSyntax = DicomTransferSyntax.ExplicitVRLittleEndian;

                if (transferSyntax != null)
                {
                    requestedTransferSyntax = GetTransferSyntaxFromString(transferSyntax);
                }

                bool transferSyntaxIsTheSameAsSourceFile =
                    dicomFile.FileMetaInfo.TransferSyntax == requestedTransferSyntax;

                //we only change transfer syntax if we need to
                DicomFile dicomFileToStream;
                if (!transferSyntaxIsTheSameAsSourceFile)
                {
                    dicomFileToStream = dicomFile.Clone(requestedTransferSyntax);
                }
                else
                {
                    dicomFileToStream = dicomFile;
                }


                header        = new MediaTypeHeaderValue(AppDicomContentType);
                streamContent = new MemoryStream();
                dicomFileToStream.Save(streamContent);
                streamContent.Seek(0, SeekOrigin.Begin);
            }

            var result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(streamContent)
            };

            result.Content.Headers.ContentType = header;
            return(result);
        }
        public IList <TestInstanceInfo> Save(string destDir, string filenamePrefix, DicomTransferSyntax transferSyntax, int instancesToGenerate = 1, string sopClassUid = "1.2.840.10008.5.1.4.1.1.11.1")
        {
            Console.Write("Generating test files.");
            if (!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }

            var dataset = new DicomDataset();

            baseDataset.CopyTo(dataset);
            dataset.AddOrUpdate(DicomTag.SOPClassUID, sopClassUid);

            var dicomFile = new DicomFile(dataset);

            if (transferSyntax != dicomFile.Dataset.InternalTransferSyntax)
            {
                var transcoder = new DicomTranscoder(dicomFile.Dataset.InternalTransferSyntax, transferSyntax, outputCodecParams: new DicomJpegParams()
                {
                    Quality = 100, ConvertColorspaceToRGB = true
                });
                dicomFile = transcoder.Transcode(dicomFile);
            }

            var instancesCreated = new List <TestInstanceInfo>();

            for (int i = 0; i < instancesToGenerate; i++)
            {
                Console.Write(".");
                var sopInstanceUid = DicomUIDGenerator.GenerateDerivedFromUUID();
                var filePath       = Path.Combine(destDir, $"{filenamePrefix}-{i:00000}.dcm");
                dicomFile.Dataset.AddOrUpdate(DicomTag.SOPInstanceUID, sopInstanceUid);
                dicomFile.FileMetaInfo.AddOrUpdate(DicomTag.MediaStorageSOPInstanceUID, sopInstanceUid);
                dicomFile.FileMetaInfo.AddOrUpdate(DicomTag.MediaStorageSOPClassUID, sopClassUid);

                dicomFile.Clone().Save(filePath);

                instancesCreated.Add(new TestInstanceInfo
                {
                    PatientId         = dicomFile.Dataset.GetSingleValue <string>(DicomTag.PatientID),
                    StudyInstanceUid  = dicomFile.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID),
                    SeriesInstanceUid = dicomFile.Dataset.GetSingleValue <string>(DicomTag.SeriesInstanceUID),
                    SopInstanceUid    = dicomFile.Dataset.GetSingleValue <string>(DicomTag.SOPInstanceUID),
                    FilePath          = filePath
                });
            }
            Console.WriteLine(".");
            return(instancesCreated);
        }
예제 #7
0
        private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                DicomFile dcmFile = new DicomFile();
                dcmFile = ((DicomIcon)(e.Item.Tag)).m_DicomFile;
                int        frames       = dcmFile.Dataset.Get(DicomTag.NumberOfFrames, 0);//如果该字段不存在,则默认值为1
                DicomFile  tmpFile      = dcmFile.Clone();
                DicomImage dcmSingleImg = new DicomImage(tmpFile.Dataset);
                Image      img          = dcmSingleImg.RenderImage(0);
                Image      process_img  = ZoomPicture(img, pictureBox_Display.Width, pictureBox_Display.Height);
                pictureBox_Display.Image = process_img;
                _image = dcmSingleImg;
                dcmFile.Dataset.Get(DicomTag.NumberOfFrames, 0);
                _grayscale = !_image.PhotometricInterpretation.IsColor;
                if (_grayscale)
                {
                    _windowWidth  = _image.WindowWidth;
                    _windowCenter = _image.WindowCenter;
                }

                int nRate = GetFrameRate(dcmSingleImg);//设置默认播放速度
                numericUpDown1.Value = nRate;

                ushort group   = ushort.Parse("0028", System.Globalization.NumberStyles.HexNumber);
                ushort element = ushort.Parse("0008", System.Globalization.NumberStyles.HexNumber);

                int frame_count = Convert.ToInt16(_image.Dataset.Get <string>(new DicomTag(group, element)));//设置进度条
                trackBar1.Maximum = frame_count;

                StartPlay();//开启播放
            }

            if (radiobtn1.Checked)  //设置标签
            {
                ShowDicomInfo(false);
            }

            else
            {
                ShowDicomInfo(true);
            }
        }
예제 #8
0
        private void insertFrame()
        {
            try
            {
                var result = bmDialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    var bitmap = new Bitmap(bmDialog.FileName);
                    if (bitmap.Width != img.Width || bitmap.Height != img.Height)
                    {
                        result = MessageBox.Show($"The size of selected image is not matched with current frame sequence, continue inserting?\nImage source: {bitmap.Width}x{bitmap.Height}\nFrame sequence: {img.Width}x{img.Height}", PROGRAM_NAME, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                        if (result == DialogResult.Yes)
                        {
                            result = MessageBox.Show("Scale image to fit the frame sequence?\nIf choose no, the frame will looks strange.", PROGRAM_NAME, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                            if (result == DialogResult.Yes)
                            {
                                bitmap = ImageUtil.ResizeImage(bitmap, img.Width, img.Height);
                            }
                        }
                        else
                        {
                            return;
                        }
                    }

                    byte[] pixels = ImageUtil.GetPixels(bitmap);

                    //TODO: very bad perfomance, needs improvement
                    var fileDecode = file.Clone(DicomTransferSyntax.ExplicitVRLittleEndian);
                    var pixelData  = DicomPixelData.Create(fileDecode.Dataset);
                    var buffer     = new MemoryByteBuffer(pixels);
                    pixelData.AddFrame(buffer);
                    file = fileDecode.Clone(file.Dataset.InternalTransferSyntax);

                    initImage();
                    initFrameList();
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Image invaild, insertion failed.", PROGRAM_NAME, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
예제 #9
0
        /// <summary>
        /// returns dicomFile in the content type given by finalContentType in a HttpResponseMessage.
        /// If content type is dicom, transfer syntax must be set to the given transferSyntax parameter.
        /// </summary>
        /// <param name="dicomFile"></param>
        /// <param name="finalContentType"></param>
        /// <param name="transferSyntax"></param>
        /// <param name="frameIndex"></param>
        /// <returns></returns>
        private ActionResult ReturnImageAsHttpResponse(DicomFile dicomFile, string finalContentType, string transferSyntax, int frameIndex)
        {
            MediaTypeHeaderValue header = null;
            Stream streamContent        = null;

            if (finalContentType == JpegImageContentType)
            {
                DicomImage image = new DicomImage(dicomFile.Dataset);
                Bitmap     bmp   = image.RenderImage(frameIndex).As <Bitmap>();

                //When an image/jpeg MIME type is returned, the image shall be encoded using the JPEG baseline lossy 8
                //bit Huffman encoded non-hierarchical non-sequential process ISO/IEC 10918.
                //TODO Is it the case with default Jpeg format from Bitmap?
                header        = new MediaTypeHeaderValue(JpegImageContentType);
                streamContent = new MemoryStream();
                bmp.Save(streamContent, ImageFormat.Jpeg);
                streamContent.Seek(0, SeekOrigin.Begin);
            }
            else if (finalContentType == AppDicomContentType)
            {
                //By default, the transfer syntax shall be
                //"Explicit VR Little Endian".
                //Note: This implies that retrieved images are sent un-compressed by default.
                //DicomTransferSyntax requestedTransferSyntax = DicomTransferSyntax.JPEG2000Lossless;
                DicomTransferSyntax requestedTransferSyntax = DicomTransferSyntax.ExplicitVRLittleEndian;

                if (transferSyntax != null)
                {
                    requestedTransferSyntax = GetTransferSyntaxFromString(transferSyntax);
                }

                bool transferSyntaxIsTheSameAsSourceFile =
                    dicomFile.FileMetaInfo.TransferSyntax == requestedTransferSyntax;

                //we only change transfer syntax if we need to
                DicomFile dicomFileToStream;
                if (!transferSyntaxIsTheSameAsSourceFile)
                {
                    dicomFileToStream = dicomFile.Clone(requestedTransferSyntax);
                }
                else
                {
                    dicomFileToStream = dicomFile;
                }

                // Check if this is a multiframe image
                int numberOfFrame = 1;
                dicomFileToStream.Dataset.TryGetValue <int>(DicomTag.NumberOfFrames, 0, out numberOfFrame);
                if (numberOfFrame > 1)
                {
                    // This is a multiframe image, only return the speicify frame
                    var bytesImage = DicomPixelData.Create(dicomFileToStream.Dataset).GetFrame(frameIndex).Data;
                    dicomFileToStream.Dataset.AddOrUpdatePixelData(DicomVR.OB, new Dicom.IO.Buffer.MemoryByteBuffer(bytesImage));
                }
                else
                {
                    // This must be a single frame image
                    Debug.Assert(frameIndex == 0);
                }

                header        = new MediaTypeHeaderValue(AppDicomContentType);
                streamContent = new MemoryStream();
                dicomFileToStream.Save(streamContent);
                streamContent.Seek(0, SeekOrigin.Begin);
            }


            //HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            //result.Content = new StreamContent(streamContent);
            //result.Content.Headers.ContentType = header;
            //Response.ContentType = header;

            return(File(streamContent, AppDicomContentType));;
        }
예제 #10
0
        private void ChangeSyntax(DicomTransferSyntax syntax, DicomCodecParams param = null)
        {
            var file = _file.Clone(syntax, param);

            OpenFile(file);
        }
예제 #11
0
        void ExtractMultiframes2Singleframe(object o)
        {
            float nPercent             = 0;
            ConvertProcessEventArgs ev = new ConvertProcessEventArgs(0);

            JpegFileList.Clear();
            if (!File.Exists(SourceFileName))
            {
                return;
            }

            DicomFile    dcmFile    = DicomFile.Open(SourceFileName);
            DicomDataset dcmDataset = dcmFile.Dataset;
            int          frames     = dcmFile.Dataset.Get <int>(DicomTag.NumberOfFrames);

            if (frames == 0)
            {
                frames = 1;
            }

            string srcName = Path.GetFileName(SourceFileName);
            string tmpPath = AppDomain.CurrentDomain.BaseDirectory + "tmpframe\\";

            if (!Directory.Exists(tmpPath))
            {
                Directory.CreateDirectory(tmpPath);
            }
            else
            {
                DeleteDir(tmpPath);
            }

            for (int i = 0; i < frames; i++)
            {
                try
                {
                    DicomFile  tmpFile        = dcmFile.Clone();
                    string     sopinstanceuid = tmpFile.Dataset.Get <string>(DicomTag.SOPInstanceUID, "");
                    DicomImage dcmSingleImg   = new DicomImage(tmpFile.Dataset);

                    Image  img        = dcmSingleImg.RenderImage(i);
                    string tmpJpgName = string.Format(sopinstanceuid + "-{0}.jpg", i.ToString().PadLeft(5, '0'), tmpPath);
                    tmpJpgName = tmpPath + tmpJpgName;
                    if (img != null)
                    {
                        img.Save(tmpJpgName);
                    }
                    JpegFileList.Add(tmpJpgName);
                    nPercent = (i + 1.0f) / frames * 100;
                    string s = nPercent.ToString(("#.##"));
                    callback(nPercent);
                    Thread.Sleep(1);
                }
                catch (Exception e)
                {
                    //MessageBox.Show(string.Format("Errors:{0},Details:{1}", e.Message + e.StackTrace));
                }

                ev.Percent = 100;
            }
        }
예제 #12
0
        void ConvertDicom2AVIFormat(object o)
        {
            float nPercent             = 0;
            ConvertProcessEventArgs ev = new ConvertProcessEventArgs(0);

            #region 多帧文件存在

            if (File.Exists(strMultiFrameDicomFileName))
            {
                AVIWriter aviWriter = new AVIWriter();

                DicomFile dcmFile = DicomFile.Open(strMultiFrameDicomFileName);


                dcmFile.Dataset.Get <string>(DicomTag.SOPInstanceUID, "");

                int bmWidth  = Convert.ToInt16(dcmFile.Dataset.Get <string>(DicomTag.Columns, ""));
                int bmHeight = Convert.ToInt16(dcmFile.Dataset.Get <string>(DicomTag.Rows, ""));

                string strDestFile = strOutPutAVIName;

                aviWriter.Create(strDestFile, (UInt16)nFrs, bmWidth, bmHeight);

                try
                {
                    for (int i = nBeginFrame; i < nEndFrame; i++)
                    {
                        DicomFile  tmpFile      = dcmFile.Clone();
                        DicomImage dcmSingleImg = new DicomImage(tmpFile.Dataset);
                        Image      img          = dcmSingleImg.RenderImage(i);
                        Bitmap     bmp          = new Bitmap(img);
                        bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
                        aviWriter.LoadFrame(bmp);
                        aviWriter.AddFrame();
                        if (nEndFrame == 0)
                        {
                            nEndFrame = Convert.ToInt16(dcmFile.Dataset.Get <string>(DicomTag.NumberOfFrames, ""));
                        }
                        float f = (float)100 / (float)nEndFrame - nBeginFrame;
                        nPercent += f;
                        string s = nPercent.ToString(("#.##"));
                        ev.LastPercent = ev.Percent;
                        ev.Percent     = Convert.ToSingle(s);
                        callback(nPercent);
                        Thread.Sleep(1);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
                finally
                {
                    aviWriter.Close();
                }
            }
            #endregion

            #region 单帧文件列表存在

            if (listSingleFrameFileName.Count > 0)
            {
                AVIWriter aviWriter = new AVIWriter();

                DicomFile tmp_dcmFile = DicomFile.Open(listSingleFrameFileName[0]);

                int bmWidth  = Convert.ToInt16(tmp_dcmFile.Dataset.Get <string>(DicomTag.Columns, ""));
                int bmHeight = Convert.ToInt16(tmp_dcmFile.Dataset.Get <string>(DicomTag.Rows, ""));


                string strDestFile = strOutPutAVIName;

                aviWriter.Create(strDestFile, (UInt16)nFrs, bmWidth, bmHeight);

                try
                {
                    for (int i = 0; i < listSingleFrameFileName.Count; i++)
                    {
                        tmp_dcmFile = DicomFile.Open(listSingleFrameFileName[0]);
                        DicomFile  tmpFile      = tmp_dcmFile.Clone();
                        DicomImage dcmSingleImg = new DicomImage(tmpFile.Dataset);
                        Image      img          = dcmSingleImg.RenderImage(0);
                        Bitmap     bmp          = new Bitmap(img);
                        bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
                        aviWriter.LoadFrame(bmp);
                        aviWriter.AddFrame();
                        float f = (float)100 / (float)listSingleFrameFileName.Count;
                        nPercent += f;
                        string s = nPercent.ToString(("#.##"));
                        ev.LastPercent = ev.Percent;
                        ev.Percent     = Convert.ToSingle(s);
                        callback(nPercent);
                        Thread.Sleep(1);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
                finally
                {
                    aviWriter.Close();
                }

                #endregion
            }

            ev.Percent = 100;
        }
예제 #13
0
        /// <summary>
        /// Convert single file to a set of files acording the number of frames
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="outRoot"></param>
        static void ConvertFile(string fileFullName, string outRoot)
        {
            try
            {
                Console.WriteLine("Reading file: " + fileFullName);

                DicomFile file    = DicomFile.Open(fileFullName);
                ushort    nframes = file.Dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, (ushort)1);

                // If file ocoursanally has only one frame we copy it with new name according to converter policy.
                if (nframes <= 1)
                {
                    Console.WriteLine("Copying");
                    var fname = outRoot + CreateImageFileName(file);
                    CreatePathToFileIfNeeded(fname);
                    file.Save(fname);
                }
                else
                {
                    Console.WriteLine("Converting");

                    //
                    // The most Important part !!!
                    //
                    // Here is going multiframe file spliting logic.
                    // We copy all dicom tags from original file except that we know in advance decribse frames.
                    // Than we add image position, orientation and number, taken from frames description sequences.
                    // Than we replace pixel data with particular frame.
                    //

                    // Clone dicom object, which we will use as a template
                    var templateObject = file.Clone();

                    // Base for instance uids
                    var mediaSopInstUid = file.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty);
                    var sopInstUid      = file.Dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty);

                    // One frame in output
                    templateObject.Dataset.AddOrUpdate(DicomTag.NumberOfFrames, 1);

                    // Sequence with data to copy to output image
                    if (!file.Dataset.TryGetSequence(DicomTag.PerFrameFunctionalGroupsSequence, out DicomSequence mfseq))
                    {
                        throw new ApplicationException("Shared Functional Groups Sequence (0x5200, 0x9230) is expected to get sencitive information");
                    }

                    // Remove multiframe Shared Functional Groups Sequence
                    templateObject.Dataset.Remove(DicomTag.PerFrameFunctionalGroupsSequence);

                    // Original file pixel data
                    var oldPixelData = DicomPixelData.Create(file.Dataset, false);

                    // Frames iteration
                    for (ushort i = 0; i < nframes; i++)
                    {
                        // Instance UID is formed from original file plus dot and frame number
                        templateObject.FileMetaInfo.AddOrUpdate(DicomTag.MediaStorageSOPInstanceUID, mediaSopInstUid + '.' + i.ToString());
                        templateObject.Dataset.AddOrUpdate(DicomTag.SOPInstanceUID, sopInstUid + '.' + i.ToString());
                        templateObject.Dataset.AddOrUpdate(DicomTag.InstanceNumber, i + 1);

                        // Technical information
                        var sqitem = mfseq.Items[i];
                        foreach (var element in sqitem)
                        {
                            if (element.ValueRepresentation == DicomVR.SQ)
                            {
                                var sq = element as DicomSequence;
                                foreach (var ds in sq)
                                {
                                    ds.CopyTo(templateObject.Dataset);
                                }
                            }
                            else
                            {
                                templateObject.Dataset.AddOrUpdate(element);
                            }
                        }

                        // Pixel data
                        var pixelData   = DicomPixelData.Create(templateObject.Dataset, true);
                        var framepixels = oldPixelData.GetFrame(i);
                        pixelData.AddFrame(framepixels);

                        // Save to file
                        var fname = outRoot + CreateImageFileName(templateObject);
                        CreatePathToFileIfNeeded(fname);
                        templateObject.Save(fname);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error in processing file: " + fileFullName + " / " + e.Message);
            }
        }