2015年9月2日水曜日

GDCM memo

Move Scu

1) Study >> Series move
2) Study >> image move

1) Study からSeriesを抽出。series単位で move

  1. var scp = new gdcm.ServiceClassUser();
  2. ushort port = 11112;
  3. ushort portScp = 104;
  4. string aetcalled = "DCM4CHEE";
  5. string aetcalling = "any";
  6. string host = "192.168.0.100";
  7. //
  8. string patId = "12345";
  9. //sendmove
  10. var scu = new gdcm.ServiceClassUser();
  11. //scu.SetHostname("192.168.17.13"); scu.SetAETitle("any");
  12. scu.SetHostname(host);
  13. scu.SetAETitle(aetcalling);//
  14. scu.SetPort(port);
  15. scu.SetTimeout(1d);
  16. scu.SetCalledAETitle(aetcalled);
  17. // InitializeConnection
  18. if (!scu.InitializeConnection())
  19. { Console.WriteLine("Err :Init"); return; }
  20. var generator = new PresentationContextGenerator();
  21. var retDatasets = new DataSetArrayType();
  22. // Find SCU
  23. var theTagPair = new gdcm.KeyValuePairArrayType();
  24. theTagPair.Add(new gdcm.KeyValuePairType(new gdcm.Tag(0x0010, 0x0020), patId));
  25. theTagPair.Add(new gdcm.KeyValuePairType(new gdcm.Tag(0x0020, 0x000D), "*")); //StudyInstanceUID
  26. var findquery = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType, gdcm.EQueryLevel.eStudy, theTagPair);
  27. if (!generator.GenerateFromUID(findquery.GetAbstractSyntaxUID()))
  28. { Console.WriteLine("Err :VerificationSOPClass"); return; }
  29. scu.SetPresentationContexts(generator.GetPresentationContexts());
  30. string studyInstanceUid = string.Empty;
  31. string seriesInstanceUid = string.Empty;
  32. if (!scu.StartAssociation())
  33. { Console.WriteLine("Err :StartAssociation"); return; }
  34. if (scu.SendFind(findquery, retDatasets))
  35. {
  36. if (retDatasets.Count > 0)
  37. {
  38. foreach (gdcm.DataSet d in retDatasets)
  39. Console.WriteLine("StudyInstanceUID :" + d.GetDataElement(new gdcm.Tag(0x0020, 0x000D)).toString());
  40. // Find Last StudyInstancUID to SeriesInstanceUID
  41. theTagPair = new KeyValuePairArrayType();
  42. studyInstanceUid=retDatasets[retDatasets.Count - 1].GetDataElement(new gdcm.Tag(0x0020, 0x000D)).GetValue().toString();
  43. Console.WriteLine(studyInstanceUid);
  44. theTagPair.Add(new gdcm.KeyValuePairType(new gdcm.Tag(0x0020, 0x000D), studyInstanceUid));
  45. theTagPair.Add(new gdcm.KeyValuePairType(new gdcm.Tag(0x0020, 0x000E), "*"));
  46. findquery = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType, gdcm.EQueryLevel.eSeries, theTagPair);
  47. if (!generator.GenerateFromUID(findquery.GetAbstractSyntaxUID()))
  48. { Console.WriteLine("Err :VerificationSOPClass"); return; }
  49. scu.SetPresentationContexts(generator.GetPresentationContexts());
  50. retDatasets=new DataSetArrayType();
  51. if (scu.SendFind(findquery, retDatasets))
  52. {
  53. Console.WriteLine(retDatasets.Count);
  54. if (retDatasets.Count > 0)
  55. {
  56. foreach (gdcm.DataSet d in retDatasets)
  57. Console.WriteLine("SeriesInstanceUID :" + d.GetDataElement(new gdcm.Tag(0x0020, 0x000D)).toString());
  58. }
  59. }
  60. }
  61. }
  62. if (!scu.StopAssociation())
  63. { Console.WriteLine("Err :scu StopAssociation"); return; }
  64. //
  65. if (retDatasets.Count == 0)
  66. return;
  67. var moveds = new gdcm.DataSet();
  68. // Last SeriesInstanceUID
  69. moveds.Insert(retDatasets[0].GetDataElement(new gdcm.Tag(0x0020, 0x000D)));
  70. moveds.Insert(retDatasets[0].GetDataElement(new gdcm.Tag(0x0020, 0x000E)));
  71. //
  72. var movequery = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType, gdcm.EQueryLevel.eImage, moveds, true);
  73. //
  74. if (!generator.GenerateFromUID(movequery.GetAbstractSyntaxUID()))
  75. { Console.WriteLine("Err :VerificationSOPClass"); return; }
  76. scu.SetPresentationContexts(generator.GetPresentationContexts());
  77. scu.SetPortSCP(portScp); //PortSCU
  78. if (!scu.StartAssociation())
  79. { Console.WriteLine("Err :scu StartAssociation"); return; }
  80. var data = new gdcm.DataSetArrayType();
  81. if (!scu.SendMove(movequery, data))
  82. Console.WriteLine("Err : SendMove");
  83. if (!scu.StopAssociation())
  84. { Console.WriteLine("Err :scu StopAssociation"); return; }
  85. foreach (gdcm.DataSet d in data)
  86. {
  87. // represent Photmetric Interpretation
  88. if(d.FindDataElement(new gdcm.Tag(0x0028,0004)))
  89. Console.WriteLine(d.GetDataElement(new gdcm.Tag(0x0028,0004)).GetValue().toString());
  90.  
  91. }
  92. Console.WriteLine("...End");

2)  Study から imageごとに move

  1. var scp = new gdcm.ServiceClassUser();
  2. ushort port = 11112;
  3. ushort portScp = 104;
  4. string aetcalled = "DCM4CHEE";
  5. string aetcalling = "any";
  6. string host = "192.168.0.100";
  7. //
  8. string patId = "12345";
  9. //sendmove
  10. var scu = new gdcm.ServiceClassUser();
  11. //scu.SetHostname("192.168.17.13"); scu.SetAETitle("any");
  12. scu.SetHostname(host);
  13. scu.SetAETitle(aetcalling);//
  14. scu.SetPort(port);
  15. scu.SetTimeout(1d);
  16. scu.SetCalledAETitle(aetcalled);
  17. // InitializeConnection
  18. if (!scu.InitializeConnection())
  19. { Console.WriteLine("Err :Init"); return; }
  20. var generator = new PresentationContextGenerator();
  21. var retDatasets = new DataSetArrayType();
  22. // Find SCU
  23. var theTagPair = new gdcm.KeyValuePairArrayType();
  24. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0010, 0x0020), patId));
  25. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0008, 0x0018), "*"));//SOPInstanceUID
  26. var findquery = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType, gdcm.EQueryLevel.eImage, theTagPair);
  27. if (!generator.GenerateFromUID(findquery.GetAbstractSyntaxUID()))
  28. { Console.WriteLine("Err :VerificationSOPClass"); return; }
  29. scu.SetPresentationContexts(generator.GetPresentationContexts());
  30. if (!scu.StartAssociation())
  31. { Console.WriteLine("Err :StartAssociation"); return; }
  32. if (!scu.SendFind(findquery, retDatasets))
  33. { Console.WriteLine("Err :SendFind"); return; }
  34. if (!scu.StopAssociation())
  35. { Console.WriteLine("Err :scu StopAssociation"); return; }
  36. //
  37. if (retDatasets.Count == 0)
  38. return;
  39.  
  40. var moveds = new gdcm.DataSet();
  41. moveds.Insert(retDatasets[0].GetDataElement(new gdcm.Tag(0x0010, 0x0020)));
  42. moveds.Insert(retDatasets[0].GetDataElement(new gdcm.Tag(0x0020, 0x000D)));
  43. moveds.Insert(retDatasets[0].GetDataElement(new gdcm.Tag(0x0020, 0x000E)));
  44. //
  45. var movequery = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType, gdcm.EQueryLevel.eImage, moveds, true);
  46. //
  47. if (!generator.GenerateFromUID(movequery.GetAbstractSyntaxUID()))
  48. { Console.WriteLine("Err :VerificationSOPClass"); return; }
  49. scu.SetPresentationContexts(generator.GetPresentationContexts());
  50. scu.SetPortSCP(portScp);
  51.  
  52. if (!scu.StartAssociation())
  53. { Console.WriteLine("Err :scu StartAssociation"); return; }
  54. for (int i = 0; i < retDatasets.Count; i++)
  55. {
  56. var queryds = movequery.GetQueryDataSet();
  57.  
  58. var instanceuid = retDatasets[i].GetDataElement(new gdcm.Tag(0x0008, 0x0018));
  59. Console.WriteLine(instanceuid.toString());
  60. queryds.Replace(instanceuid);
  61. var data = new gdcm.DataSetArrayType();
  62. if (!scu.SendMove(movequery, data))
  63. { Console.WriteLine("Err : SendMove"); break; }
  64. var d = data[0];
  65. // represent Photmetric Interpretation
  66. if (d.FindDataElement(new gdcm.Tag(0x0028, 0004)))
  67. Console.WriteLine(d.GetDataElement(new gdcm.Tag(0x0028, 0004)).GetValue().toString());
  68.  
  69.  
  70. }
  71. if (!scu.StopAssociation())
  72. { Console.WriteLine("Err :scu StopAssociation"); return; }
  73. Console.WriteLine("End");

2015年8月28日金曜日

GDCM memo

Find Scu

PatID>>StudyInstansUID>>SeriesInstanceUID>>SOPInstanceUID
患者番号からSOPInstanceUIDを抽出

  1. ushort port = 11112;
  2. string aetcalled = "DCM4CHEE";
  3. string aetcalling = "any";
  4. string host = "192.168.0.1";
  5. //Patient Number
  6. string patId="123";
  7. //Study Level
  8. gdcm.PresentationContextGenerator generator = new PresentationContextGenerator();
  9. gdcm.KeyValuePairArrayType theTagPair = new KeyValuePairArrayType();
  10. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0010, 0x0020), patId));
  11. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0010, 0x0010), "*")); //Name
  12. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0010, 0x0030), "*")); //Birthday
  13. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0010, 0x0040), "*")); //Sex
  14. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0020, 0x000D), "*")); //StudyInstanceUID
  15. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0008, 0x0050), "*")); //AccessionNumber
  16. var query = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.ePatientRootType,
  17. gdcm.EQueryLevel.eStudy, theTagPair);
  18. var ret = new DataSetArrayType();
  19. bool b = gdcm.CompositeNetworkFunctions.CFind(host, port, query, ret, aetcalling, aetcalled);
  20. List studyInsUidList = new List();
  21. for (int i = 0; i < ret.Count; i++)
  22. {
  23. var ds = ret[i];
  24. Console.WriteLine("StudyInsUid:" + ds.GetDataElement(new gdcm.Tag(0x0020, 0x000D)).GetValue().toString());
  25. studyInsUidList.Add(ds.GetDataElement(new gdcm.Tag(0x0020, 0x000D)).GetValue().toString());
  26. }
  27. //Series Level
  28. string studyInsUid = studyInsUidList[0].Trim(); //Select First Series
  29. theTagPair = new KeyValuePairArrayType();
  30. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0020, 0x000D), studyInsUid)); //StudyInstanceUID
  31. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0020, 0x000E), "*")); //SeriesInstanceUID
  32. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0008, 0x0060), "*")); //Modality
  33. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0020, 0x0011), "*")); //SeriesNumber
  34. query = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType,
  35. gdcm.EQueryLevel.eSeries, theTagPair);
  36. ret = new DataSetArrayType();
  37. gdcm.CompositeNetworkFunctions.CFind(host, port, query, ret, aetcalling, aetcalled);
  38. List seriesInsUidList = new List();
  39. for (int i = 0; i < ret.Count; i++)
  40. {
  41. var ds = ret[i];
  42. Console.WriteLine("SeriesInsUid:" + ds.GetDataElement(new gdcm.Tag(0x0020, 0x000E)).GetValue().toString());
  43. seriesInsUidList.Add(ds.GetDataElement(new gdcm.Tag(0x0020, 0x000E)).GetValue().toString());
  44. }
  45. //Image Level
  46. string seriesInsUid = seriesInsUidList[0].Trim(); //Select First Series
  47. theTagPair = new KeyValuePairArrayType();
  48. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0020, 0x000E), seriesInsUid)); //SeriesInstanceUID
  49. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0020, 0x0013), "*")); //InstanceNumber
  50. theTagPair.Add(new KeyValuePairType(new gdcm.Tag(0x0008, 0x0018), "*")); //SOPInstanceUID
  51. query = gdcm.CompositeNetworkFunctions.ConstructQuery(gdcm.ERootType.eStudyRootType,
  52. gdcm.EQueryLevel.eImage, theTagPair);
  53. ret = new DataSetArrayType();
  54. gdcm.CompositeNetworkFunctions.CFind(host, port, query, ret, aetcalling, aetcalled);
  55. for (int i = 0; i < ret.Count; i++)
  56. {
  57. var ds = ret[i];
  58. Console.WriteLine("SopInsUid:" + ds.GetDataElement(new gdcm.Tag(0x0008, 0x0018)).GetValue().toString());
  59. }

2015年8月22日土曜日

GDCM memo / send scu

  1. var dir = new System.IO.DirectoryInfo(@"c:\dicom");
  2. var filesInfo = dir.GetFiles("*.dcm");
  3. //
  4. var scu = new gdcm.ServiceClassUser();
  5. scu.SetHostname("host");
  6. scu.SetPort((ushort)11112);
  7. scu.SetCalledAETitle("DCM4CHEE");
  8. scu.SetAETitle("any");
  9. scu.SetTimeout(2000);
  10. if (!scu.InitializeConnection())
  11. { Console.WriteLine("Err :suc initialize connection"); return; }
  12. var ft = new gdcm.FilenamesType();
  13. foreach (FileInfo fi in filesInfo)
  14. ft.Add(fi.FullName);
  15. var g = new gdcm.PresentationContextGenerator();
  16. g.GenerateFromFilenames(ft);
  17. scu.SetPresentationContexts(g.GetPresentationContexts());
  18. if (!scu.StartAssociation())
  19. { Console.WriteLine(": suc Start Association"); return; }
  20. foreach (FileInfo fi in filesInfo)
  21. {
  22. if (!scu.SendStore(fi.FullName))
  23. {
  24. Console.WriteLine("Err: Send scu[" + fi.FullName +"]");
  25. break;
  26. }
  27. }
  28. if (!scu.StopAssociation())
  29. { Console.WriteLine("\r\nErr: suc Stop Association\n"); return; }
  30. Console.WriteLine("\r\nEnd");
  31. scu.Dispose();
  32. g.Dispose();
  33. ft.Dispose();

2015年8月11日火曜日

GDCM 覚書2 YBR_FULL_422

GDCM memo 2

YBR_FULL_422の画像

  1. string photometricInterpretation = ds.GetDataElement(new gdcm.Tag(0x00280004)).GetValue().toString();
  2. byte* pBmpData = (byte*)_bmpData.Scan0;
  3. if (photometricInterpretation == "YBR_FULL_422")
  4. {
  5. fixed (byte* pData = _pixelData)
  6. {
  7. byte* ybr = pData;
  8. for (int y = 0; y < _rows; y++)
  9. {
  10. for (int x = 0; x < _columns; x++)
  11. {
  12. int Y = ybr[0] - 16;
  13. int Cb = ybr[1] - 128;
  14. int Cr = ybr[2] - 128;
  15. int r = ((298 * Y + 409 * Cr + 128) / 256);
  16. int g = ((298 * Y - 100 * Cb - 208 * Cr + 128) / 256);
  17. int b = ((298 * Y + 516 * Cb + 128) / 256);
  18. pBmpData[2] = (byte)(r < 0 ? 0 : (r > 255 ? 255 : r));
  19. pBmpData[1] = (byte)(g < 0 ? 0 : (g > 255 ? 255 : g));
  20. pBmpData[0] = (byte)(b < 0 ? 0 : (b > 255 ? 255 : b));
  21. pBmpData += 3;
  22. ybr += 3;
  23. }
  24. pBmpData += padding;
  25. }
  26. }
  27. }

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.