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画像
//MONOCHROME2,シングルフレーム Dicom Image var sw = new System.Diagnostics.Stopwatch(); sw.Start(); string fileName = @"chest.dcm"; // var ir = new ImageReader(); ir.SetFileName(fileName); if (!ir.Read()){ Console.WriteLine("Err: ImageReader "); return; } gdcm.File file = ir.GetFile(); gdcm.DataSet ds = file.GetDataSet(); //DataSetの取得 gdcm.Image image = ir.GetImage(); //Imageの取得 byte[] imgBuf = new byte[(int)image.GetBufferLength()]; image.GetBuffer(imgBuf); //Image bufferの取得 uint dims = image.GetNumberOfDimensions(); //ここではマルチフレームは未対応とする if (dims == 3) { Console.WriteLine("Err: マルチフレーム未対応"); return; } // if (image.GetPhotometricInterpretation().GetType() == gdcm.PhotometricInterpretation.PIType.RGB) { Console.WriteLine("Err: PhotometricInterpretation is RGB"); return; } if (image.GetPhotometricInterpretation().GetType() != gdcm.PhotometricInterpretation.PIType.MONOCHROME2) { Console.WriteLine("Err: PhotometricInterpretation is not MONOCHROME2"); return; } //8bpp用のpaletteを作成しておく var b = new System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); var GrayscalePalette = b.Palette; for (int i = 0; i < 256; i++) GrayscalePalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i); //bitmapの作成とpaletteを設定 // int wc,ww; if (!ds.FindDataElement(new gdcm.Tag(0x00281050))){ Console.WriteLine("Err: Window Center値がありません"); return; } if (!ds.FindDataElement(new gdcm.Tag(0x00281051))){ Console.WriteLine("Err: Window Width値がありません"); return; } if (ds.FindDataElement(new gdcm.Tag(0x00281052))){ Console.WriteLine("Err: RescaleInterception未サポート"); return; } wc = Convert.ToInt32(Convert.ToDouble(ds.GetDataElement(new gdcm.Tag(0x00281050)).GetValue().toString())); ww = Convert.ToInt32(Convert.ToDouble(ds.GetDataElement(new gdcm.Tag(0x00281051)).GetValue().toString())); int max, min = 0; double invww = 0d; max = wc + (int)((double)ww * 0.5d); min = wc - (int)((double)ww * 0.5d); ushort max1 = (ushort)max; ushort min1 = (ushort)min; invww = 255.0d / (double)ww; //MONOCHROME2 image var bitmap = new System.Drawing.Bitmap((int)image.GetColumns(), (int)image.GetRows(), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); bitmap.Palette = GrayscalePalette; var bmpData = bitmap.LockBits(new Rectangle(0, 0, (int)image.GetColumns(), (int)image.GetRows()), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); int padding = bmpData.Stride - bmpData.Width; unsafe { fixed (byte* pBuf = imgBuf) { byte* pBmpData = (byte*)bmpData.Scan0; //PixelRepresentation(0x00280103)=1の場合 //short* ptr = (short*)pBuf; //PixelRepresentation=なし,あるいは0の場合 ushort* ptr = (ushort*)pBuf; int stride = bmpData.Stride; int pixel; for (int y = 0; y < bmpData.Height; y++) { for (int x = 0; x < bmpData.Width; x++) { int xy = *ptr++; pixel = xy = min ? 0 : (xy >= max ? 255 : (int)((xy - min) * invww)); //16bit image to 8bit image //MONOCROME1 背景白 //pixel = xy = min ? 255 : (xy = max ? 0 : 255 - (int)((xy - min) * invWW)); *pBmpData = (byte)pixel; pBmpData++; } pBmpData += padding; } bitmap.UnlockBits(bmpData); } } if (bitmap != null) pictureBox1.Image = bitmap; sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds +" msec");
2. MONOCHROME2, マルチフレームの場合は次のようになります
uint k = image.GetNumberOfDimensions(); uint frames = 0; if(k==3) frames = image.GetDimension(2); var bitmaps = new System.Drawing.Bitmap[(int)frames]; unsafe { fixed (byte* src = imgBuf) { for (uint i = 0; i < frames; i++) { var bitmap = new System.Drawing.Bitmap((int)image.GetColumns(), (int)image.GetRows(), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); bitmap.Palette = GrayscalePalette; var bmpData = bitmap.LockBits(new Rectangle(0, 0, (int)image.GetColumns(), (int)image.GetRows()), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); int padding = bmpData.Stride - bmpData.Width; byte* pBmpData = (byte*)bmpData.Scan0; ushort* ptr = (ushort*)src; int stride = bmpData.Stride; int pixel; for (int y = 0; y < bmpData.Height; y++) { for (int x = 0; x < bmpData.Width; x++) { int xy = *ptr++; pixel = xy <= min ? 0 : (xy >= max ? 255 : (int)((xy - min) * invww)); *pBmpData = (byte)pixel; pBmpData++; } pBmpData += padding; } bitmap.UnlockBits(bmpData); bitmaps[i] = bitmap; } } }
0 件のコメント :
コメントを投稿