- string path;
- if (Path.GetFileName(path).Equals("DICOMDIR"))
- retern;
- TreeView treeView = new TreeView();
- TreeNode treeNode = new TreeNode();
- List<string[]> imageList = new List<string[]>();
- treeNode.Nodes.Clear();
- treeView.Nodes.Clear();
- //DicomDir dicomDir = new DicomDir(path);
- //ReadDicomDir(dicomDir);
- Stream stream = null;
- DcmParser parser = null;
- Dataset ds = null;
- try
- {
- stream = new BufferedStream(new FileStream(path, FileMode.Open, FileAccess.Read));
- parser = new org.dicomcs.data.DcmParser(stream);
- org.dicomcs.data.FileFormat format = parser.DetectFileFormat();
- if (format != null)
- {
- ds = new org.dicomcs.data.Dataset();
- parser.DcmHandler = ds.DcmHandler;
- parser.ParseDcmFile(format);
- TreeNode nodePatient = new TreeNode();
- TreeNode nodeStudy = new TreeNode();
- TreeNode nodeSeries = new TreeNode();
- TreeNode nodeStudat = new TreeNode();
- //
- int tmpStudat = 0;
- int patBirdat = 0;
- string patName = string.Empty;
- //
- DcmObject doRoot = (DcmObject)ds;
- IEnumerator enuRoot = doRoot.GetEnumerator();
- int count = 0;
- while (enuRoot.MoveNext())
- {
- DcmElement elRoot = (DcmElement)enuRoot.Current;
- if (elRoot.HasItems())
- {
- for (int i = 0; i < elRoot.vm(); i++)
- {
- DcmObject dcmObj = (DcmObject)elRoot.GetItem(i);
- IEnumerator enu = dcmObj.GetEnumerator();
- while (enu.MoveNext())
- {
- DcmElement el = (DcmElement)enu.Current;
- if (el.tag() == DcmTags.DirectoryRecordType)
- {
- string rs = el.GetString(Encoding.Unicode);
- if (rs == "PATIENT")
- {
- PatientTable pt = new PatientTable();
- if (dcmObj.Contains(Tags.PatientBirthDate))
- patBirdat = Convert.ToInt32(dcmObj.GetDate(DcmTags.PatientBirthDate).ToString("yyyyMMdd"));
- if (dcmObj.Contains(Tags.PatientName))
- patName = dcmObj.GetString(DcmTags.PatientName);
- }
- else if (rs == "STUDY")
- {
- if (dcmObj.Contains(DcmTags.StudyDate))
- {
- int studat = Convert.ToInt32(dcmObj.GetDate(Tags.StudyDate).ToString("yyyyMMdd"));
- string stuinsuid = string.Empty;
- string studes = string.Empty;
- if (dcmObj.Contains(DcmTags.StudyInstanceUID))
- stuinsuid = dcmObj.GetString(DcmTags.StudyInstanceUID);
- if (dcmObj.Contains(DcmTags.StudyDescription))
- studes = dcmObj.GetString(DcmTags.StudyInstanceUID);
- if (studat != tmpStudat)
- {
- nodeStudat = new TreeNode(studat.ToString("####/##/##"));
- nodeStudat.Tag = studat;
- treeViewStudy.Nodes.Add(nodeStudat);
- tmpStudat = studat;
- }
- nodeStudy = new TreeNode("");
- nodeStudat.Nodes.Add(nodeStudy);
- }
- }
- else if (rs == "SERIES")
- {
- imageList = new List<string[]>();
- string serinsuid = string.Empty;
- string sernum = string.Empty; ;
- string numserrelima = string.Empty;
- string serdes = string.Empty;
- string bodparexa = string.Empty;
- string modality = string.Empty;
- if (dcmObj.Contains(DcmTags.SeriesInstanceUID))
- serinsuid = dcmObj.GetString(DcmTags.SeriesInstanceUID);
- if (dcmObj.Contains(DcmTags.SeriesNumber))
- sernum = dcmObj.GetString(DcmTags.SeriesNumber);
- if (dcmObj.Contains(DcmTags.SeriesDescription))
- serdes = dcmObj.GetString(DcmTags.SeriesDescription);
- if (dcmObj.Contains(DcmTags.Modality))
- modality = dcmObj.GetString(DcmTags.Modality);
- nodeSeries = new TreeNode(modality + "." + sernum);
- nodeStudy.Nodes.Add(nodeSeries);
- if (nodeStudy.Text == string.Empty)
- nodeStudy.Text = modality;
- nodeSeries.Tag=imageList; //Add (refFile and uid)List
- }
- else if (rs == "IMAGE")
- {
- string refFileID = string.Empty;
- string uid = string.Empty;
- if (dcmObj.Contains(DcmTags.RefFileID))
- refFileID = dcmObj.GetString(DcmTags.RefFileID);
- if (dcmObj.Contains(DcmTags.RefSOPInstanceUIDInFile))
- uid = dcmObj.GetString(DcmTags.RefSOPInstanceUIDInFile);
- string[] ss = new string[2];
- ss[0] = refFileID;
- ss[1] = uid;
- imageList.Add(ss);
- }
- }
- }
- }
- }
- }
2011年9月17日土曜日
DICOMDIR から TreeNode へ
2011年5月24日火曜日
dicom-cs あるいは dicomネットワークツール
C#用のDICOMネットワークツール。
イメージ用のソースは無いが元ネタのdcm-4cheにあり。
参照設定
log4net用にlog4net.config設定ファイル
[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"log4net.config", Watch = true)]
を入れておく。
出力に
'System.IO.EndOfStreamException' の初回例外が mscorlib.dll で発生しました。
が出る。。。。
stream 読み取り時、エラーが出たら次のtagを読みに行くという設定のためか?
どうしたら出ないようにできるものか。。。。
PixelDataの取得は
イメージ用のソースは無いが元ネタのdcm-4cheにあり。
参照設定
- using org.dicomcs.dict;
- using org.dicomcs.data;
- using org.dicomcs.net;
- using org.dicomcs.util;
- using log4net;
log4net用にlog4net.config設定ファイル
[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"log4net.config", Watch = true)]
を入れておく。
出力に
'System.IO.EndOfStreamException' の初回例外が mscorlib.dll で発生しました。
が出る。。。。
stream 読み取り時、エラーが出たら次のtagを読みに行くという設定のためか?
どうしたら出ないようにできるものか。。。。
PixelDataの取得は
- org.dicomcs.util.ByteBuffer buff = dataSet.GetByteBuffer(Tags.PixelData);
- byte[] pixelData = (byte[])buff.ToArray();
2011年3月23日水曜日
カラービットマップ
pixelDataからカラービットマップを取得
BGR > RGB の変換が必要
BGR > RGB の変換が必要
.net 4.0から Parallel.For が使えるようになったので一部訂正。2015-08-12
- {
- if(PhotometricInterpretation != "RGB")
- retern;
- //dataSet: DicomDataSet
- Bitmap bitmap;
- int columns = dataSet.Columns;
- int rows = dataSet.Rows;
- byte[] pixelData = dataSet.PixelData;
- bitmap = new Bitmap(columns, rows, PixelFormat.Format24bppRgb);
- BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, columns, rows),
- ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
- int padding = bitmapData.Stride - columns;
- byte* pBitmap = (byte*)bitmapData.Scan0;
- int j = 0, i = 0;
- for (int y = 0; y < rows; y++)
- {
- j = y * columns;
- for (int x = 0; x < columns; x++)
- {
- i = j + x;
- pBitmap[i * 3] = pixelData[i * 3 + 2]; //G
- pBitmap[i * 3 + 1] = pixelData[i * 3 + 1]; //B
- pBitmap[i * 3 + 2] = pixelData[i * 3]; //R
- }
- i += padding;
- }
- bitmap.UnlockBits(bitmapData);
- return bitmap;
- }
- fixed (byte* pData = pixelData)
- {
- byte* rgb = pData;
- int stride = bmpData.Stride;
- Parallel.For(0, rows, y =>
- {
- for (int x = 0; x < columns; x++)
- {
- int pos = (x * 3) + y * stride;
- pBitmap[pos] = rgb[pos + 2]; //G
- pBitmap[pos + 1] = rgb[pos + 1]; //B
- pBitmap[pos + 2] = rgb[pos]; //R
- }
- });
- }
2011年3月21日月曜日
マルチフレーム
NumberOfFrames タグ (0028,0008)があるとマルチフレーム画像。
PixelData(7FD0,0010)の長さをNumberOfFramesで割った値が一枚当たりの画像の PixelData 。
PixelData(7FD0,0010)の長さをNumberOfFramesで割った値が一枚当たりの画像の PixelData 。
- List<byte[]> pixelDataList = new List<byte[]>();
- int numberOfFrames = dicomData.NumberOfFrames;
- int length = dicomData.PixelData.Length / numberOfFrames;
- for(int k=0; k < numberOfFrames;k++)
- {
- byte[] buf;
- Array.Copy(dicomData.PixelData, numberOfFrames * length, buf, 0, length);
- pixelDataList.Add(buf);
- }
RescaleIntercept タグ と RescaleSlopeタグ
他院からのCDで Rescale Interceptタグ と Rescale Slopeタグがある DICOM Fileを散見。
シーメンスのCTなど。
画像データに傾斜と切片を付加して8bitグレースケールを得る。
シーメンスのCTなど。
画像データに傾斜と切片を付加して8bitグレースケールを得る。
- fixed (byte* pData = pixelData)
- {
- int pixel;
- short* ptr = (short*)pData; //short型ポインタ
- byte* pBitmap = (byte*)bitmapData.Scan0;
- int j = 0, i = 0;
- int difference = max - min;
- if (rescaleIntercept == 0.0d )
- {
- for (int x = 0; x < _columns; x++)
- {
- pixel = (int)(((*ptr + rescaleIntercept - windowCenter) / windowWidth + 0.5d) * 255.0d);
- if (pixel > 255) pixel = 255;
- else if (pixel < 0) pixel = 0;
- *pBitmap = (byte)pixel; ptr++; pBitmap++;
- }
- pBitmap += padding;
- }
- else
- {
- for (int y = 0; y < _rows; y++)
- {
- j = y * _columns;
- for (int x = 0; x < _columns; x++)
- {
- pixel = (int)((((int)ptr[j + x] + rescaleIntercept - windowCenter) / windowWidth + 0.5d) * 255.0d);
- if (pixel > 255) pixel = 255;
- if (pixel < 0) pixel = 0;
- pixel = (int)(rescaleSlope * pixel + rescaleIntercept);
- pBitmap[i] = (byte)pixel;
- i++;
- }
- i += padding;
- }
- }
- }
16 bit グレースケール
CT, MR, CR, DR などの医用画像は殆どが16bit グレースケール画像。
PCでは8bitしか表示できないので、これを変換。
また Bitmap.SetPixel がとても遅いため LockBits を使用。
1byteが1pixelのグレースケール用ColorPaletteを作成する。
3byte=1pixelのグレースケール(R=G=B)より容量減か。
データの挿入 ()
PCでは8bitしか表示できないので、これを変換。
また Bitmap.SetPixel がとても遅いため LockBits を使用。
DICOMオブジェクト
- using System;
- using System.Drawing;
- using System.Drawing.Imaging;
ビットマップ
- int columns = dicomData.Columns;
- int rows = dicomData.Rows;
- int windowCenter = dicomData.WindowCenter;
- int windowWidth = dicomData.WindowWidth;
1byteが1pixelのグレースケール用ColorPaletteを作成する。
3byte=1pixelのグレースケール(R=G=B)より容量減か。
- byte[] pixelData = dicomData.PixelData;Bitmap bitmap;
- ColorPalette colorPalette;
- for (int i = 0; i < 256; i++)
- colorPalette.Entries[i] = Color.FromArgb(i, i, i);
- Bitmap bitmap = new Bitmap(columns, rows, PixelFormat.Format8bppIndexed);
データの挿入 ()
- public unsafe Bitmap Grayscale16To8()
- {
- int padding = bitmapData.Stride - columns;
- int min = windowCenter - windowWidth / 2;
- int max = windowCenter + windowWidth / 2;
- fixed (byte* pData = pixelData)
- {
- int pixel;
- short* ptr = (short*)pData;
- byte* pBitmap = (byte*)bitmapData.Scan0;
- int j = 0, i = 0;
- for (int y = 0; y < _rows; y++)
- {
- j = y * _columns;
- for (int x = 0; x < _columns; x++)
- {
- pixel = (int)ptr[j + x];
- if (pixel <= min)
- pixel = 0;
- else if (pixel >= max)
- pixel = 255;
- else
- pixel = (int)((pixel - min) * 255 / (max - min));
- pBitmap[i] = (byte)pixel;
- i++;
- }
- i += padding;
- }
- }
- bitmap.UnlockBits(bitmapData);
- return bitmap;
- }
登録:
投稿
(
Atom
)