Exemple #1
0
        private void ReadInlineBinary
        (
            fo.DicomTag tag,
            fo.DicomVR vr,
            JsonTextReader reader,
            fo.DicomDataset dataset,
            int level
        )
        {
            if (reader.Read( ))
            {
                fo.IO.Buffer.MemoryByteBuffer buffer = null;
                byte[] data   = new byte[0];
                string base64 = (string)reader.Value;


                if (!string.IsNullOrEmpty(base64))
                {
                    buffer = new fo.IO.Buffer.MemoryByteBuffer(System.Convert.FromBase64String(base64));
                }

                if (tag == fo.DicomTag.PixelData && level == 0)
                {
                    dataset.AddOrUpdatePixelData(vr, buffer, fo.DicomTransferSyntax.Parse(TransferSyntaxUID));
                }
                else
                {
                    dataset.AddOrUpdate <fo.IO.Buffer.IByteBuffer> (vr, tag, buffer);
                }
            }
        }
Exemple #2
0
        private void ReadInlineBinary
        (
            DicomTag tag,
            DicomVR vr,
            JsonTextReader reader,
            DicomDataset dataset,
            int level
        )
        {
            if (reader.Read( ))
            {
                Dicom.IO.Buffer.MemoryByteBuffer buffer = null;
                string base64 = (string)reader.Value;


                if (!string.IsNullOrEmpty(base64))
                {
                    buffer = new Dicom.IO.Buffer.MemoryByteBuffer(System.Convert.FromBase64String(base64));
                }

                if (tag == DicomTag.PixelData && level == 0)
                {
                    var pixelData = DicomPixelData.Create(dataset, true);  //2nd parameter is true since we are adding new data here

                    pixelData.AddFrame(buffer);
                }
                else
                {
                    dataset.AddOrUpdate <Dicom.IO.Buffer.IByteBuffer> (vr, tag, buffer);
                }
            }
        }
Exemple #3
0
        private void AddGreyscaleImage(Bitmap bitmap, int index)
        {
            if (_currentFilmBox == null)
            {
                throw new InvalidOperationException("Start film box first!");
            }
            if (index < 0 || index > _currentFilmBox.BasicImageBoxes.Count)
            {
                throw new ArgumentOutOfRangeException("Image box index out of range");
            }

            if (bitmap.PixelFormat != PixelFormat.Format24bppRgb &&
                bitmap.PixelFormat != PixelFormat.Format32bppArgb &&
                bitmap.PixelFormat != PixelFormat.Format32bppRgb
                )
            {
                throw new ArgumentException("Not supported bitmap format");
            }

            var dataset = new DicomDataset();

            dataset.Add <ushort>(DicomTag.Columns, (ushort)bitmap.Width)
            .Add <ushort>(DicomTag.Rows, (ushort)bitmap.Height)
            .Add <ushort>(DicomTag.BitsAllocated, 8)
            .Add <ushort>(DicomTag.BitsStored, 8)
            .Add <ushort>(DicomTag.HighBit, 7)
            .Add(DicomTag.PixelRepresentation, (ushort)PixelRepresentation.Unsigned)
            .Add(DicomTag.PlanarConfiguration, (ushort)PlanarConfiguration.Interleaved)
            .Add <ushort>(DicomTag.SamplesPerPixel, 1)
            .Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2.Value);

            var pixelData = DicomPixelData.Create(dataset, true);

            var pixels = GetGreyBytes(bitmap);
            var buffer = new Dicom.IO.Buffer.MemoryByteBuffer(pixels.Data);

            pixelData.AddFrame(buffer);

            var imageBox = _currentFilmBox.BasicImageBoxes[index];

            imageBox.ImageSequence = dataset;

            pixels.Dispose();
        }
Exemple #4
0
        private void AddGreyscaleImage(Bitmap bitmap, int index)
        {
            if (_currentFilmBox == null)
            {
                throw new InvalidOperationException("Start film box first!");
            }
            if (index < 0 || index > _currentFilmBox.BasicImageBoxes.Count)
            {
                throw new ArgumentOutOfRangeException("Image box index out of range");
            }

            if (bitmap.PixelFormat != PixelFormat.Format24bppRgb &&
               bitmap.PixelFormat != PixelFormat.Format32bppArgb &&
               bitmap.PixelFormat != PixelFormat.Format32bppRgb
              )
            {
                throw new ArgumentException("Not supported bitmap format");
            }

            var dataset = new DicomDataset();
            dataset.Add<ushort>(DicomTag.Columns, (ushort)bitmap.Width)
                   .Add<ushort>(DicomTag.Rows, (ushort)bitmap.Height)
                   .Add<ushort>(DicomTag.BitsAllocated, 8)
                   .Add<ushort>(DicomTag.BitsStored, 8)
                   .Add<ushort>(DicomTag.HighBit, 7)
                   .Add(DicomTag.PixelRepresentation, (ushort)PixelRepresentation.Unsigned)
                   .Add(DicomTag.PlanarConfiguration, (ushort)PlanarConfiguration.Interleaved)
                   .Add<ushort>(DicomTag.SamplesPerPixel, 1)
                   .Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2.Value);

            var pixelData = DicomPixelData.Create(dataset, true);

            var pixels = GetGreyBytes(bitmap);
            var buffer = new Dicom.IO.Buffer.MemoryByteBuffer(pixels.Data);

            pixelData.AddFrame(buffer);

            var imageBox = _currentFilmBox.BasicImageBoxes[index];
            imageBox.ImageSequence = dataset;

            pixels.Dispose();
        }
Exemple #5
0
        string WorkerFunc(Tuple <string, Tuple <int, int, int, int>, List <string> > param, BackgroundWorker worker, DoWorkEventArgs e)
        {
            List <string> lFailed            = new List <string>();
            string        strPath            = param.Item1;
            Tuple <int, int, int, int> lCrop = param.Item2;
            List <string> files = param.Item3;

            bool bCrop = lCrop.Item1 + lCrop.Item2 + lCrop.Item3 + lCrop.Item4 > 0 ? true : false;

            DicomUIDGenerator uidGen = new DicomUIDGenerator();
            List <Tuple <string, string, string, string> > listDCM = new List <Tuple <string, string, string, string> >();

            int i = 0, k = 0;

            // Randomize input list
            Random rand = new Random();

            // For each spot in the array, pick
            // a random item to swap into that spot.
            for (k = 0; k < files.Count - 1; k++)
            {
                int    j    = rand.Next(k, files.Count);
                string temp = files[k];
                files[k] = files[j];
                files[j] = temp;
            }

            DateTime dt = DateTime.Now;


            int nSuccess = 0;

            foreach (string strFile in files)
            {
                i++;
                DicomFile file;
                try
                {
                    file = DicomFile.Open(strFile);
                }
                catch (Exception ex)
                {
                    // Transmit message back with worker?
                    lFailed.Add(strFile);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    continue;
                }

                string strOriginalPatientID = "";

                try
                {
                    strOriginalPatientID = file.Dataset.GetValue <string>(DicomTag.PatientID, 0);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }

                DicomAnonymizer anon = new DicomAnonymizer();
                DicomFile       fileAnon;
                try
                {
                    fileAnon = anon.Anonymize(file);
                }
                catch (Exception ex)
                {
                    // Transmit message back with worker?
                    lFailed.Add(strFile);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    continue;
                }


                DicomTag[] tagsToRemove = { DicomTag.StudyDate, DicomTag.StudyTime, DicomTag.PatientID, DicomTag.StudyID, DicomTag.StudyInstanceUID };

                foreach (DicomTag d in tagsToRemove)
                {
                    try
                    {
                        fileAnon.Dataset.Remove(d);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine("Error removing element: " + ex.ToString());
                    }
                }


                fileAnon.Dataset.Add(DicomTag.StudyInstanceUID, DicomUID.Generate());
                fileAnon.Dataset.Add(DicomTag.StudyDate, dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00"));
                fileAnon.Dataset.Add(DicomTag.StudyTime, dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00"));
                fileAnon.Dataset.Add(DicomTag.PatientID, i.ToString());
                fileAnon.Dataset.Add(DicomTag.StudyID, i.ToString());

                string strStudyID = fileAnon.Dataset.GetValue <string>(DicomTag.StudyInstanceUID, 0);



                try
                {
                    var header    = DicomPixelData.Create(fileAnon.Dataset);
                    var pixelData = PixelDataFactory.Create(header, header.NumberOfFrames - 1);

                    int rows    = header.Height;
                    int columns = header.Width;

                    Array  a;
                    byte[] result;

                    bool b16bit = false;

                    if (pixelData is GrayscalePixelDataU16)
                    {
                        ushort[] pixels = ((GrayscalePixelDataU16)pixelData).Data;
                        a      = pixels;
                        b16bit = true;
                    }
                    else if (pixelData is GrayscalePixelDataS16)
                    {
                        short[] pixels = ((GrayscalePixelDataS16)pixelData).Data;
                        a      = pixels;
                        b16bit = true;
                    }
                    else if (pixelData is GrayscalePixelDataU32)
                    {
                        uint[] pixels = ((GrayscalePixelDataU32)pixelData).Data;
                        a = pixels;
                    }
                    else if (pixelData is GrayscalePixelDataS32)
                    {
                        int[] pixels = ((GrayscalePixelDataS32)pixelData).Data;
                        a = pixels;
                    }
                    else if (pixelData is GrayscalePixelDataU8)
                    {
                        byte[] pixels = ((GrayscalePixelDataU8)pixelData).Data;
                        a = pixels;
                    }
                    else
                    {
                        throw new Exception("DICOM image format not supported (this program only supports greyscale).");
                    }

                    // Can't seem to figure out the byte formatting between 16-bit greyscale DCM versus C#'s 16-bit greyscale.
                    //b16bit = false;

                    if (bCrop)
                    {
                        // Top
                        if (lCrop.Item1 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (columns * lCrop.Item1));
                            Array.Copy(a, columns * lCrop.Item1, cropped, 0, cropped.Length);
                            a     = cropped;
                            rows -= lCrop.Item1;
                        }

                        // Right
                        if (lCrop.Item2 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (rows * lCrop.Item2));

                            for (k = 0; k < rows; k++)
                            {
                                Array.Copy(a, k * columns, cropped, k * (columns - lCrop.Item2), columns - lCrop.Item2);
                            }

                            a        = cropped;
                            columns -= lCrop.Item2;
                        }

                        // Bottom
                        if (lCrop.Item3 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (columns * lCrop.Item3));
                            Array.Copy(a, 0, cropped, 0, cropped.Length);
                            a     = cropped;
                            rows -= lCrop.Item3;
                        }

                        // Left
                        if (lCrop.Item4 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (rows * lCrop.Item4));

                            for (k = 0; k < rows; k++)
                            {
                                Array.Copy(a, k * columns + lCrop.Item4, cropped, k * (columns - lCrop.Item4), columns - lCrop.Item4);
                            }

                            a        = cropped;
                            columns -= lCrop.Item4;
                        }

                        // Now we need to copy the Array "a" into a byte array.
                        // But first!  Should we make sure that it's actually a 16-bit array?
                        int nBytes = a.Length * System.Runtime.InteropServices.Marshal.SizeOf(a.GetValue(0));
                        result = new byte[nBytes];
                        Buffer.BlockCopy(a, 0, result, 0, nBytes);

                        Dicom.IO.Buffer.MemoryByteBuffer buffer = new Dicom.IO.Buffer.MemoryByteBuffer(result);
                        DicomDataset dataset = new DicomDataset();

                        dataset = fileAnon.Dataset.Clone();

                        dataset.AddOrUpdate(DicomTag.Rows, (ushort)rows);
                        dataset.AddOrUpdate(DicomTag.Columns, (ushort)columns);

                        DicomPixelData newPixelData = DicomPixelData.Create(dataset, true);
                        newPixelData.BitsStored                = header.BitsStored;
                        newPixelData.SamplesPerPixel           = header.SamplesPerPixel;
                        newPixelData.HighBit                   = header.HighBit;
                        newPixelData.PhotometricInterpretation = header.PhotometricInterpretation;
                        newPixelData.PixelRepresentation       = header.PixelRepresentation;
                        newPixelData.PlanarConfiguration       = header.PlanarConfiguration;
                        newPixelData.Height = (ushort)rows;
                        newPixelData.Width  = (ushort)columns;
                        newPixelData.AddFrame(buffer);

                        fileAnon = new DicomFile(dataset);
                    }

                    // Only do this if it's a 16bit file that we want a 16bit png for
                    if (b16bit)
                    {
                        int nBytes = a.Length * System.Runtime.InteropServices.Marshal.SizeOf(a.GetValue(0));
                        result = new byte[nBytes];

                        // If we're using a format that's "16bit" but actually less, scale the values?
                        if (header.BitsStored < header.BitsAllocated)
                        {
                            int nShift = header.BitsAllocated - header.BitsStored;
                            int nFlag  = (0x1 << header.BitsStored) - 1;
                            for (k = 0; k < a.Length; k++)
                            {
                                a.SetValue((ushort)(((nFlag - ((ushort)a.GetValue(k) & nFlag)) << nShift) & 0xFFFF), k);
                            }
                        }

                        Buffer.BlockCopy(a, 0, result, 0, nBytes);

                        unsafe
                        {
                            fixed(byte *ptr = result)
                            {
                                using (Bitmap img16 = new Bitmap(columns, rows, 4 * ((2 * columns + 3) / 4), System.Drawing.Imaging.PixelFormat.Format16bppGrayScale, new IntPtr(ptr)))
                                {
                                    SaveBmp(img16, strPath + "/Anonymised/" + strStudyID + "-16bitGreyscale.tif");
                                    //img16.Save(strPath + "/Anonymised/" + strStudyID + "-16bitGreyscale.png");
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("Failed to crop image");
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }


                fileAnon.Save(strPath + "/Anonymised/" + strStudyID + ".dcm");

                listDCM.Add(new Tuple <string, string, string, string>(i.ToString(), strStudyID, strFile, strOriginalPatientID));

                var img = new DicomImage(strPath + "/Anonymised/" + strStudyID + ".dcm");

                // Convert DCM to a 32-bit per pixel (8-bit per each color RGB + 8-bit unused) PNG file
                try
                {
                    Dicom.IO.PinnedIntArray px = img.RenderImage().Pixels;
                    int[] pxi = px.Data;

                    byte[] result = new byte[px.ByteSize];
                    Buffer.BlockCopy(pxi, 0, result, 0, result.Length);

                    unsafe
                    {
                        fixed(byte *ptr = result)
                        {
                            using (Bitmap image = new Bitmap(img.Width, img.Height, img.Width * 4,
                                                             System.Drawing.Imaging.PixelFormat.Format32bppRgb, new IntPtr(ptr)))
                            {
                                image.Save(strPath + "/Anonymised/" + strStudyID + ".png");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }


                worker.ReportProgress(i * 100 / files.Count);
                nSuccess++;

                //Console.WriteLine("Anonymized image " + i + " (of " + nFrames + " frame" + (nFrames == 1 ? "" : "s") + "): " + strFile);
            }

            // Create a map file

            using (System.IO.StreamWriter file =
                       new System.IO.StreamWriter(new FileStream(strPath + "/Anonymised/Map.csv", FileMode.Create, FileAccess.ReadWrite), Encoding.UTF8))
            {
                file.WriteLine("NewPatientID,NewStudyInstanceUID,OriginalFile,OriginalPatientID");
                foreach (Tuple <string, string, string, string> line in listDCM)
                {
                    file.WriteLine(line.Item1 + "," + line.Item2 + "," + line.Item3 + "," + line.Item4);
                }
            }

            string strRet = nSuccess.ToString() + " images successfully anonymised, Map.csv created.\nOutput at:\n" + strPath + "\\Anonymised";

            if (lFailed.Count > 0)
            {
                strRet += "\nThese files failed to anonymise:";
                foreach (string sf in lFailed)
                {
                    strRet += "\n" + sf;
                }
            }
            return(strRet);
        }
Exemple #6
0
        private void ReadElement
        (
            fo.DicomDataset ds,
            XElement element,
            fo.DicomTag tag,
            fo.DicomVR dicomVr,
            int level
        )
        {
            if (dicomVr == fo.DicomVR.PN)
            {
                string personNameValue = "";

                foreach (var personNameElementValue in element.Elements( ).OrderBy(n => n.Attribute(Constants.ATTRIBUTE_NUMBER)))
                {
                    foreach (var personNameComponent in personNameElementValue.Elements( ))
                    {
                        if (personNameComponent.Name == Utilities.PersonNameComponents.PN_COMP_ALPHABETIC ||
                            personNameComponent.Name == Utilities.PersonNameComponents.PN_COMP_IDEOGRAPHIC ||
                            personNameComponent.Name == Utilities.PersonNameComponents.PN_COMP_PHONETIC)
                        {
                            personNameValue = UpdatePersonName(personNameValue, personNameComponent, Utilities.PersonNameParts.PN_Family);
                            personNameValue = UpdatePersonName(personNameValue, personNameComponent, Utilities.PersonNameParts.PN_Given);
                            personNameValue = UpdatePersonName(personNameValue, personNameComponent, Utilities.PersonNameParts.PN_Midlle);
                            personNameValue = UpdatePersonName(personNameValue, personNameComponent, Utilities.PersonNameParts.PN_Prefix);
                            personNameValue = UpdatePersonName(personNameValue, personNameComponent, Utilities.PersonNameParts.PN_Suffix, true);

                            personNameValue = personNameValue.TrimEnd('^');    // extra cleanup

                            personNameValue += "=";
                        }
                    }

                    personNameValue = personNameValue.TrimEnd('=');

                    personNameValue += "\\";
                }

                personNameValue = personNameValue.TrimEnd('\\');
                ds.AddOrUpdate <string> (dicomVr, tag, personNameValue);
            }
            else if (Utilities.IsBinaryVR(dicomVr))
            {
                var dataElement = element.Elements( ).OfType <XElement> ( ).FirstOrDefault( );

                if (null != dataElement)
                {
                    fo.IO.Buffer.IByteBuffer data;


                    if (dataElement.Name == Constants.ELEMENT_BULKDATA)
                    {
                        string uri = dataElement.Attribute(Constants.ATTRIBUTE_BULKDATAURI).Value;


                        data = new fo.IO.Buffer.BulkDataUriByteBuffer(uri);
                    }
                    else
                    {
                        var base64 = System.Convert.FromBase64String(dataElement.Value);


                        data = new fo.IO.Buffer.MemoryByteBuffer(base64);
                    }

                    if (tag == fo.DicomTag.PixelData && level == 0)
                    {
                        ds.AddOrUpdatePixelData(dicomVr, data, TransferSyntax);
                    }
                    else
                    {
                        ds.AddOrUpdate <fo.IO.Buffer.IByteBuffer> (dicomVr, tag, data);
                    }
                }
            }
            else
            {
                var values = ReadValue(element);

                if (tag == fo.DicomTag.TransferSyntaxUID)
                {
                    TransferSyntax = fo.DicomTransferSyntax.Parse(values.FirstOrDefault( ));
                }

                ds.AddOrUpdate <string> (dicomVr, tag, values.ToArray( ));
            }
        }