2014-10-16 161 views
4

我需要使用c#和一些免費庫將JPEG圖像保存爲DICOM。我讀了很多關於如何做相反的事情的主題,但是我找不到如何執行我所需要的任何內容。我可以實現的最好的方法是使用ClearCanvas保存圖像,但會變形。如何將圖像保存爲DICOM

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"); 

任何人都可以告訴我上面的代碼有什麼問題,或者提供任何其他免費庫的簡單工作示例?

+2

檢查此[使用ClearCanvas編碼JPG圖像文件作爲DICOM PixelData取出(http://stackoverflow.com/questions/25498247/encode- jpg-image-file-as-dicom-pixeldata-using-clearcanvas) – JohnnyQ 2014-10-16 14:50:12

+0

@RogerRowland,就像我上面所說的那樣,我唯一可以得到一些結果的是ClearCanvas,但使用這個確切的庫不是我的主要原因。如果有人會告訴我如何在另一個圖書館的幫助下做出我需要的東西,只要它是免費的就可以了。 – KorsaR 2014-10-16 14:50:42

+0

在上面的喜歡的帖子Johnny Q說:_You還應該設置follwing標籤:PhotometricInterpretation =「RGB」,SamplesPerPixel = 3,PlanarConfiguration = 0_ – TaW 2014-10-16 14:52:44

回答

0

這是一點代碼,但這是我如何做到的。這似乎是一個重複的常見問題。我在Clear Canvas論壇上將這些內容拼湊在一起,但它對於所提問題是一個完全有效的答案。

如果需要從標準圖像文件(如jpg)創建DICOM二次採集圖像,並且希望它們能夠與所有PACS,VNA和其他DICOM應用程序正常工作,那麼此處的代碼適用於。

好的,我必須再編輯一次。我拼湊在一起是爲了好玩,我只需要能夠做到這一點。我創建的一些DICOM圖像添加到了我的測試套件中,但我比它更有趣。我把荷馬辛普森的大腦圖片包裹起來。以及'放射科醫生拍照時'的圖片。不要忘記我做的最後一個,最近新聞中有一條高質量的Moray鰻魚X射線照片,因此我也將它包裝在DICOM中。因此你看到的例子。

好的,甚至還有一個編輯。自寫這個答案以來,我發現了這個代碼非常有價值的能力。我可以用任何方式生成像素數據來測試我們的產品。我已經可以在顯式小端模式下生成DICOM圖像,顯示尺寸爲10,000 X 10,000像素,這肯定會導致DICOM產品出現問題,但是我可以在沒有問題的情況下使用Clear Canvas生成DICOM圖像。

我還可以使用此代碼使用簡單的小型5 x 5像素圖像發送數據,它可以幫助測試快速構建大型數據庫或增加某些積壓。我只希望別人認爲這有用,因爲我有。

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); 

那麼這裏就是它所有的休息:

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; 
    } 
} 
+0

如何設置圖像的傳輸語法? – codeDr 2015-12-06 23:22:54

+0

@codeDr此行默認生成一個part10格式的DICOM文件,默認傳輸語法爲Explicit VR Little Endian。 DicomFile dicomFile = new DicomFile(fileName,new DicomAttributeCollection(),_baseDataSet.Copy()); – Jake 2015-12-07 16:56:58