2015年8月4日火曜日

GDCM 覚書

GDCM (Grassroots DICOM) memo memo

c#用wrapperの gdcmの覚書。

gdcm-2.4.4 の作成には cmakeはver2.8.9(cmake-2.8.9-win32-x86.zip), swigはver2.0.12(swigwin-2.0.12.zip)を使用しました。 swin3.0以降は不可のようです。
swigwinは実行ファイルのある場所にpathを切っておきます。

1. MONOCHROME2, シングルフレームのbitmap画像

  1. //MONOCHROME2,シングルフレーム Dicom Image
  2. var sw = new System.Diagnostics.Stopwatch();
  3. sw.Start();
  4. string fileName = @"chest.dcm";
  5. //
  6. var ir = new ImageReader();
  7. ir.SetFileName(fileName);
  8. if (!ir.Read()){
  9. Console.WriteLine("Err: ImageReader ");
  10. return;
  11. }
  12. gdcm.File file = ir.GetFile();
  13. gdcm.DataSet ds = file.GetDataSet(); //DataSetの取得
  14. gdcm.Image image = ir.GetImage(); //Imageの取得
  15. byte[] imgBuf = new byte[(int)image.GetBufferLength()];
  16. image.GetBuffer(imgBuf); //Image bufferの取得
  17. uint dims = image.GetNumberOfDimensions(); //ここではマルチフレームは未対応とする
  18. if (dims == 3) {
  19. Console.WriteLine("Err: マルチフレーム未対応"); return;
  20. }
  21. //
  22. if (image.GetPhotometricInterpretation().GetType() == gdcm.PhotometricInterpretation.PIType.RGB) {
  23. Console.WriteLine("Err: PhotometricInterpretation is RGB"); return;
  24. }
  25. if (image.GetPhotometricInterpretation().GetType() != gdcm.PhotometricInterpretation.PIType.MONOCHROME2) {
  26. Console.WriteLine("Err: PhotometricInterpretation is not MONOCHROME2"); return;
  27. }
  28. //8bpp用のpaletteを作成しておく
  29. var b = new System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  30. var GrayscalePalette = b.Palette;
  31. for (int i = 0; i < 256; i++)
  32. GrayscalePalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);
  33. //bitmapの作成とpaletteを設定
  34. //
  35. int wc,ww;
  36. if (!ds.FindDataElement(new gdcm.Tag(0x00281050))){
  37. Console.WriteLine("Err: Window Center値がありません"); return;
  38. }
  39. if (!ds.FindDataElement(new gdcm.Tag(0x00281051))){
  40. Console.WriteLine("Err: Window Width値がありません"); return;
  41. }
  42. if (ds.FindDataElement(new gdcm.Tag(0x00281052))){
  43. Console.WriteLine("Err: RescaleInterception未サポート"); return;
  44. }
  45. wc = Convert.ToInt32(Convert.ToDouble(ds.GetDataElement(new gdcm.Tag(0x00281050)).GetValue().toString()));
  46. ww = Convert.ToInt32(Convert.ToDouble(ds.GetDataElement(new gdcm.Tag(0x00281051)).GetValue().toString()));
  47. int max, min = 0;
  48. double invww = 0d;
  49. max = wc + (int)((double)ww * 0.5d);
  50. min = wc - (int)((double)ww * 0.5d);
  51. ushort max1 = (ushort)max;
  52. ushort min1 = (ushort)min;
  53. invww = 255.0d / (double)ww;
  54. //MONOCHROME2 image
  55. var bitmap = new System.Drawing.Bitmap((int)image.GetColumns(), (int)image.GetRows(), System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  56. bitmap.Palette = GrayscalePalette;
  57. var bmpData = bitmap.LockBits(new Rectangle(0, 0, (int)image.GetColumns(), (int)image.GetRows()), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  58. int padding = bmpData.Stride - bmpData.Width;
  59. unsafe
  60. {
  61. fixed (byte* pBuf = imgBuf)
  62. {
  63. byte* pBmpData = (byte*)bmpData.Scan0;
  64. //PixelRepresentation(0x00280103)=1の場合
  65.     //short* ptr = (short*)pBuf;
  66. //PixelRepresentation=なし,あるいは0の場合
  67. ushort* ptr = (ushort*)pBuf;
  68. int stride = bmpData.Stride;
  69. int pixel;
  70. for (int y = 0; y < bmpData.Height; y++)
  71. {
  72. for (int x = 0; x < bmpData.Width; x++)
  73. {
  74. int xy = *ptr++;
  75. pixel = xy = min ? 0 : (xy >= max ? 255 : (int)((xy - min) * invww)); //16bit image to 8bit image
  76. //MONOCROME1 背景白
  77. //pixel = xy = min ? 255 : (xy = max ? 0 : 255 - (int)((xy - min) * invWW));
  78. *pBmpData = (byte)pixel;
  79. pBmpData++;
  80. }
  81. pBmpData += padding;
  82. }
  83. bitmap.UnlockBits(bmpData);
  84. }
  85. }
  86. if (bitmap != null)
  87. pictureBox1.Image = bitmap;
  88. sw.Stop();
  89. Console.WriteLine(sw.ElapsedMilliseconds +" msec");

2. MONOCHROME2, マルチフレームの場合は次のようになります

  1. uint k = image.GetNumberOfDimensions();
  2. uint frames = 0;
  3. if(k==3)
  4. frames = image.GetDimension(2);
  5. var bitmaps = new System.Drawing.Bitmap[(int)frames];
  6. unsafe
  7. {
  8. fixed (byte* src = imgBuf)
  9. {
  10. for (uint i = 0; i < frames; i++)
  11. {
  12. var bitmap = new System.Drawing.Bitmap((int)image.GetColumns(), (int)image.GetRows(), System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  13. bitmap.Palette = GrayscalePalette;
  14. var bmpData = bitmap.LockBits(new Rectangle(0, 0, (int)image.GetColumns(), (int)image.GetRows()), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  15. int padding = bmpData.Stride - bmpData.Width;
  16. byte* pBmpData = (byte*)bmpData.Scan0;
  17. ushort* ptr = (ushort*)src;
  18. int stride = bmpData.Stride;
  19. int pixel;
  20. for (int y = 0; y < bmpData.Height; y++)
  21. {
  22. for (int x = 0; x < bmpData.Width; x++)
  23. {
  24. int xy = *ptr++;
  25. pixel = xy <= min ? 0 : (xy >= max ? 255 : (int)((xy - min) * invww));
  26. *pBmpData = (byte)pixel;
  27. pBmpData++;
  28. }
  29. pBmpData += padding;
  30. }
  31. bitmap.UnlockBits(bmpData);
  32. bitmaps[i] = bitmap;
  33. }
  34. }
  35. }
  36.  

0 件のコメント :

コメントを投稿