如何保存图像为DICOM [英] How to save image as DICOM

查看:3080
本文介绍了如何保存图像为DICOM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要的JPEG图像保存为使用C#和一些免费的图书馆DICOM。我读了很多它被描述了如何做相反的话题,但我找不到任何地方如何执行我需要什么。我能做到的最好的是用ClearCanvas保存的图像,但它被扭曲。

I need to save JPEG image as a DICOM using c# and some free library. 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.

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.

如果它是需要从创建DICOM二次采集图像标准图像文件,如JPG,而你希望他们与所有的PACS,VNA的,和其他DICOM应用程序正常工作在那里,然后在这里这段代码适用于这一点。

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.

OK我不得不修改一次。这是我的乐趣拼凑起来的,我只需要能够做到这一点。我创建了一些DI​​COM图像我加入到我的测试套件,但我有更多的乐趣与它比任何东西。我把辛普森脑部图像和包裹它。还有的当放射科医生拿自拍照片。不要忘记最后一个我所做的,有一个在新闻海鳗的X射线的高质量画面最近,所以我裹着一个在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. 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. Hence the example you see.

好吧,即使多了一个编辑。由于写这个答案,我发现此代码非常有价值的能力。我可以以任何方式产生的像素数据来测试我们的产品。已经我可以生成显式小端DICOM图像,在10000万像素,这绝对可以引起DICOM产品在那里的问题,但我可以清除画布生成它没有问题!

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!

我也可以发送使用此代码使用简单的小5×5像素的图像数据,并帮助这么多的测试,以快速建立大型数据库,或坡道一定的积压。我只希望别人认为我有这个有用

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. 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;
    }
}

这篇关于如何保存图像为DICOM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆