简体   繁体   English

如何将图像保存为DICOM

[英]How to save image as DICOM

I need to save JPEG image as a DICOM using c# and some free library. 我需要使用c#和一些免费库将JPEG图像保存为DICOM。 I read a lot of topics where it was described how to do the opposite, but I couldn't find anywhere how to perform what I need. 我阅读了很多主题,其中描述了如何做相反的事情,但我找不到任何地方如何执行我需要的东西。 The best I could achieve is to save image using ClearCanvas, but it gets distorted. 我能做的最好的事情是使用ClearCanvas保存图像,但它会变形。

DicomFile dicomFile = new DicomFile();
dicomFile.MediaStorageSopClassUid = SopClass.DigitalXRayImageStorageForPresentation.Uid;
dicomFile.DataSet[DicomTags.SopClassUid].SetStringValue(SopClass.DigitalXRayImageStorageForPresentation.Uid);
dicomFile.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
dicomFile.DataSet[DicomTags.ImageType].SetStringValue(@"ORIGINAL\PRIMARY");
dicomFile.DataSet[DicomTags.Columns].SetInt32(0, width);
dicomFile.DataSet[DicomTags.Rows].SetInt32(0, height);
dicomFile.DataSet[DicomTags.BitsStored].SetInt16(0, bitsPerPixel);
dicomFile.DataSet[DicomTags.BitsAllocated].SetInt16(0, 8);
dicomFile.DataSet[DicomTags.HighBit].SetInt16(0, 7);
dicomFile.DataSet[DicomTags.PixelData].Values = imageBuffer;
dicomFile.Save("e:\\tempFile.dcm");

Can anyone please tell me what's wrong with the code above or provide a simple working example on any other free library? 任何人都可以告诉我上面的代码有什么问题,或者在任何其他免费图书馆提供一个简单的工作示例?

It is a little bit of code but this is how I do it. 这是一些代码,但我就是这样做的。 This appears to be a common question with duplicates. 这似乎是一个重复的常见问题。 I pieced this together over time from the Clear Canvas forums, but it is a completely valid answer to the question asked. 我随着时间的推移从Clear Canvas论坛中将它拼凑在一起,但这是对所提问题的完全有效的答案。

If it is needed to create DICOM Secondary Capture images from standard image files like jpg, and you desire for them to work correctly with all the PACS, VNA's, and other DICOM applications out there, then this code here works for that. 如果需要从标准图像文件(如jpg)创建DICOM二级捕获图像,并且您希望它们能够与所有PACS,VNA和其他DICOM应用程序一起正常工作,那么此代码就适用于此。

OK I have to edit one more time. 好的我必须再编辑一次。 This I pieced together for fun, I just needed to be able to do it. 我拼凑起来玩得很开心,我只需要能够做到这一点。 Some DICOM images I created I added to my test suite, but I had more fun with it than anything. 我创建的一些DICOM图像添加到了我的测试套件中,但我比它更有趣。 I took the Homer Simpson brain picture and wrapped it. 我拿着荷马辛普森的脑图并将其包裹起来。 As well the 'When Radiologists take a selfie' picture. 还有'当放射科医生拍摄自拍照'时。 Not to forget the last one I did, there was a high quality picture of a X-Ray of a Moray eel in the news fairly recently, so I wrapped that one in DICOM too. 不要忘记我做的最后一个,最近新闻中有一张高质量的海鳗X射线照片,所以我把它包裹在DICOM中。 Hence the example you see. 因此你看到的例子。

Ok even one more edit. 好吧甚至还有一个编辑。 Since writing this answer, I have discovered a very valuable ability with this code. 自写这个答案以来,我发现了这个代码非常有价值的能力。 I can generate pixel data in any fashion to test our product. 我可以以任何方式生成像素数据来测试我们的产品。 Already I can generate DICOM images in Explicit Little Endian, at 10,000 X 10,000 pixels, and that can definitely cause problems in the DICOM products out there, but I can generate it with Clear Canvas without problems! 我已经可以使用Explicit Little Endian生成DICOM图像,10,000 X 10,000像素,这肯定会导致DICOM产品出现问题,但我可以使用Clear Canvas生成它而不会出现问题!

I can also send data using this code using simple small 5 x 5 pixel images, and it helps so much for testing to build large databases quickly, or ramp up certain backlogs. 我还可以使用这个代码使用简单的小型5 x 5像素图像发送数据,这对于测试快速构建大型数据库或增加某些积压数据有很大帮助。 I only hope someone else finds this as useful as I have. 我只希望别人觉得这和我一样有用。

using ClearCanvas.Dicom.Codec;
using ClearCanvas.Common.Utilities;
using ClearCanvas.Dicom;
using ClearCanvas.Dicom.Network;
using ClearCanvas.Common;
using ClearCanvas.ImageViewer;
using ClearCanvas.ImageViewer.Imaging;
using ClearCanvas.ImageViewer.Graphics;
using ClearCanvas.ImageViewer.StudyManagement;





            DicomFile df = null;
            Bitmap bm = LoadImage(tbImageFile.Text);
            CreateBaseDataSet();
            df = ConvertImage(bm, 1);
            df.Save(@"C:\test.dcm", DicomWriteOptions.Default);

Then here is all the rest of it: 然后是其余部分:

    private void CreateBaseDataSet()
    {
        _baseDataSet = new DicomAttributeCollection();

        //Sop Common
        _baseDataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid);

        ////Patient
        //_baseDataSet[DicomTags.PatientId].SetStringValue(_parent.PatientId);
        //_baseDataSet[DicomTags.PatientsName].SetStringValue(String.Format("{0}^{1}^{2}^^",
        //                                                                  _parent.LastName, _parent.FirstName, _parent.MiddleName));

        //_baseDataSet[DicomTags.PatientsBirthDate].SetDateTime(0, _parent.Dob);
        //_baseDataSet[DicomTags.PatientsSex].SetStringValue(_parent.Sex.ToString());

        ////Study
        //_baseDataSet[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
        //_baseDataSet[DicomTags.StudyDate].SetDateTime(0, _parent.StudyDate);
        //_baseDataSet[DicomTags.StudyTime].SetDateTime(0, _parent.StudyTime);
        //_baseDataSet[DicomTags.AccessionNumber].SetStringValue(_parent.AccessionNumber);
        //_baseDataSet[DicomTags.StudyDescription].SetStringValue(_parent.StudyDescription);


        //Patient
        _baseDataSet[DicomTags.PatientId].SetStringValue("PIDEEL");
        _baseDataSet[DicomTags.PatientsName].SetStringValue(String.Format("Moray^Eel^X-Ray"));
        //_baseDataSet[DicomTags.PatientsAddress].SetString (0,"Hubertus");
        //_baseDataSet[DicomTags.PatientsBirthDate].SetDateTime(0, DateTime.Now);
        //_baseDataSet[DicomTags.PatientsBirthDate].SetString(0, "19550512");

        _baseDataSet[DicomTags.PatientsSex].SetStringValue("O");

        //Study
        _baseDataSet[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
        _baseDataSet[DicomTags.StudyDate].SetDateTime(0, DateTime.Now);
        _baseDataSet[DicomTags.StudyTime].SetDateTime(0, DateTime.Now);
        _baseDataSet[DicomTags.AccessionNumber].SetStringValue("ACCEEL");
        _baseDataSet[DicomTags.StudyDescription].SetStringValue("X-Ray of a Moray Eel");

        _baseDataSet[DicomTags.ReferringPhysiciansName].SetNullValue();
        _baseDataSet[DicomTags.StudyId].SetNullValue();

        //Series
        _baseDataSet[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
        _baseDataSet[DicomTags.Modality].SetStringValue("OT");
        _baseDataSet[DicomTags.SeriesNumber].SetStringValue("1");

        //SC Equipment
        _baseDataSet[DicomTags.ConversionType].SetStringValue("WSD");

        //General Image
        _baseDataSet[DicomTags.ImageType].SetStringValue(@"DERIVED\SECONDARY");
        _baseDataSet[DicomTags.PatientOrientation].SetNullValue();


        _baseDataSet[DicomTags.WindowWidth].SetStringValue("");
        _baseDataSet[DicomTags.WindowCenter].SetStringValue("");

        //Image Pixel
        if (rbMonoChrome.Checked )
        {
                _baseDataSet[DicomTags.SamplesPerPixel].SetInt32(0, 1);
                _baseDataSet[DicomTags.PhotometricInterpretation].SetStringValue("MONOCHROME2");
                _baseDataSet[DicomTags.BitsAllocated].SetInt32(0, 8);
                _baseDataSet[DicomTags.BitsStored].SetInt32(0, 8);
                _baseDataSet[DicomTags.HighBit].SetInt32(0, 7);
                _baseDataSet[DicomTags.PixelRepresentation].SetInt32(0, 0);
                _baseDataSet[DicomTags.PlanarConfiguration].SetInt32(0, 0);
        }
        if (rbColor.Checked)
        {
                _baseDataSet[DicomTags.SamplesPerPixel].SetInt32(0, 3);
                _baseDataSet[DicomTags.PhotometricInterpretation].SetStringValue("RGB");
                _baseDataSet[DicomTags.BitsAllocated].SetInt32(0, 8);
                _baseDataSet[DicomTags.BitsStored].SetInt32(0, 8);
                _baseDataSet[DicomTags.HighBit].SetInt32(0, 7);
                _baseDataSet[DicomTags.PixelRepresentation].SetInt32(0, 0);
                _baseDataSet[DicomTags.PlanarConfiguration].SetInt32(0, 0);
        }
    }



    private DicomFile ConvertImage(Bitmap image, int instanceNumber)
    {
        DicomUid sopInstanceUid = DicomUid.GenerateUid();

        string fileName = @"C:\test.dcm";// String.Format("{0}.dcm", sopInstanceUid.UID);
        //fileName = System.IO.Path.Combine(_tempFileDirectory, fileName);


        DicomFile dicomFile = new DicomFile(fileName, new DicomAttributeCollection(), _baseDataSet.Copy());

        //meta info
        dicomFile.MediaStorageSopInstanceUid = sopInstanceUid.UID;
        dicomFile.MediaStorageSopClassUid = SopClass.SecondaryCaptureImageStorageUid;

        //General Image
        dicomFile.DataSet[DicomTags.InstanceNumber].SetInt32(0, instanceNumber);

        DateTime now = Platform.Time;
        DateTime time = DateTime.MinValue.Add(new TimeSpan(now.Hour, now.Minute, now.Second));

        //SC Image
        dicomFile.DataSet[DicomTags.DateOfSecondaryCapture].SetDateTime(0, now);
        dicomFile.DataSet[DicomTags.TimeOfSecondaryCapture].SetDateTime(0, time);

        //Sop Common
        dicomFile.DataSet[DicomTags.InstanceCreationDate].SetDateTime(0, now);
        dicomFile.DataSet[DicomTags.InstanceCreationTime].SetDateTime(0, time);
        dicomFile.DataSet[DicomTags.SopInstanceUid].SetStringValue(sopInstanceUid.UID);

        //int rows, columns;
        //Image Pixel


        if (rbMonoChrome.Checked)
        {
            dicomFile.DataSet[DicomTags.PixelData].Values = GetMonochromePixelData(image, out rows, out columns);
        }

        if (rbColor.Checked)
        {
            dicomFile.DataSet[DicomTags.PixelData].Values = GetColorPixelData(image, out rows, out columns);
        }


        //Image Pixel
        dicomFile.DataSet[DicomTags.Rows].SetInt32(0, rows);
        dicomFile.DataSet[DicomTags.Columns].SetInt32(0, columns);

        return dicomFile;
    }



    private static byte[] GetMonochromePixelData(Bitmap image, out int rows, out int columns)
    {
        rows = image.Height;
        columns = image.Width;

        //At least one of rows or columns must be even.
        if (rows % 2 != 0 && columns % 2 != 0)
            --columns; //trim the last column.

        int size = rows * columns;
        //byte[] pixelData = MemoryManager.Allocate<byte>(size);
        byte[] pixelData = new byte[size];
        int i = 0;

        for (int row = 0; row < rows; ++row)
        {
            for (int column = 0; column < columns; column++)
            {
                pixelData[i++] = image.GetPixel(column, row).R;
            }
        }

        return pixelData;
    }



    private static byte[] GetColorPixelData(Bitmap image, out int rows, out int columns)
    {
        rows = image.Height;
        columns = image.Width;

        //At least one of rows or columns must be even.
        if (rows % 2 != 0 && columns % 2 != 0)
            --columns; //trim the last column.

        BitmapData data = image.LockBits(new Rectangle(0, 0, columns, rows), ImageLockMode.ReadOnly, image.PixelFormat);
        IntPtr bmpData = data.Scan0;

        try
        {
            int stride = columns * 3;
            int size = rows * stride;

            //byte[] pixelData = MemoryManager.Allocate<byte>(size);
            byte[] pixelData = new byte[size];

            for (int i = 0; i < rows; ++i)
                Marshal.Copy(new IntPtr(bmpData.ToInt64() + i * data.Stride), pixelData, i * stride, stride);

            //swap BGR to RGB
            SwapRedBlue(pixelData);
            return pixelData;
        }
        finally
        {
            image.UnlockBits(data);
        }
    }




private static Bitmap LoadImage(string file)
{
    Bitmap image = Image.FromFile(file, true) as Bitmap;
    if (image == null)
        throw new ArgumentException(String.Format("The specified file cannot be loaded as a bitmap {0}.", file));

    if (image.PixelFormat != PixelFormat.Format24bppRgb)
    {
        Platform.Log(LogLevel.Info, "Attempting to convert non RBG image to RGB ({0}) before converting to Dicom.", file);

        Bitmap old = image;
        using (old)
        {
            image = new Bitmap(old.Width, old.Height, PixelFormat.Format24bppRgb);
            using (Graphics g = Graphics.FromImage(image))
            {
                g.DrawImage(old, 0, 0, old.Width, old.Height);
            }
        }
    }

    return image;
}

private static void SwapRedBlue(byte[] pixels)
{
    for (int i = 0; i < pixels.Length; i += 3)
    {
        byte temp = pixels[i];
        pixels[i] = pixels[i + 2];
        pixels[i + 2] = temp;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM