PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/DICOM/Imaging/DicomOverlayData.cs

https://github.com/petnet/fo-dicom
C# | 223 lines | 131 code | 30 blank | 62 comment | 13 complexity | 3057e4b41fffec914db482f6fa17488f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using Dicom.IO.Buffer;
  7. namespace Dicom.Imaging {
  8. /// <summary>
  9. /// DICOM Overlay
  10. /// </summary>
  11. public class DicomOverlayData {
  12. #region Private Members
  13. private ushort _group;
  14. private int _rows;
  15. private int _columns;
  16. private string _type;
  17. private int _originX;
  18. private int _originY;
  19. private int _bitsAllocated;
  20. private int _bitPosition;
  21. private IByteBuffer _data;
  22. private string _description;
  23. private string _subtype;
  24. private string _label;
  25. private int _frames;
  26. private int _frameOrigin;
  27. #endregion
  28. #region Public Constructors
  29. /// <summary>
  30. /// Initializes overlay from DICOM dataset and overlay group.
  31. /// </summary>
  32. /// <param name="ds">Dataset</param>
  33. /// <param name="group">Overlay group</param>
  34. public DicomOverlayData(DicomDataset ds, ushort group) {
  35. _group = group;
  36. Load(ds);
  37. }
  38. #endregion
  39. #region Public Properties
  40. /// <summary>
  41. /// Overlay group
  42. /// </summary>
  43. public ushort Group {
  44. get { return _group; }
  45. }
  46. /// <summary>
  47. /// Number of rows in overlay
  48. /// </summary>
  49. public int Rows {
  50. get { return _rows; }
  51. }
  52. /// <summary>
  53. /// Number of columns in overlay
  54. /// </summary>
  55. public int Columns {
  56. get { return _columns; }
  57. }
  58. /// <summary>
  59. /// Overlay type
  60. /// </summary>
  61. public string Type {
  62. get { return _type; }
  63. }
  64. /// <summary>
  65. /// Position of the first column of an overlay
  66. /// </summary>
  67. public int OriginX {
  68. get { return _originX; }
  69. }
  70. /// <summary>
  71. /// Position of the first row of an overlay
  72. /// </summary>
  73. public int OriginY {
  74. get { return _originY; }
  75. }
  76. /// <summary>
  77. /// Number of bits allocated in overlay data
  78. /// </summary>
  79. public int BitsAllocated {
  80. get { return _bitsAllocated; }
  81. }
  82. /// <summary>
  83. /// Bit position of embedded overlay
  84. /// </summary>
  85. public int BitPosition {
  86. get { return _bitPosition; }
  87. }
  88. /// <summary>
  89. /// Overlay data
  90. /// </summary>
  91. public IByteBuffer Data {
  92. get { return _data; }
  93. }
  94. /// <summary>
  95. /// Description of overlay
  96. /// </summary>
  97. public string Description {
  98. get { return _description; }
  99. }
  100. /// <summary>
  101. /// Subtype
  102. /// </summary>
  103. public string Subtype {
  104. get { return _subtype; }
  105. }
  106. /// <summary>
  107. /// Overlay label
  108. /// </summary>
  109. public string Label {
  110. get { return _label; }
  111. }
  112. /// <summary>
  113. /// Number of frames
  114. /// </summary>
  115. public int NumberOfFrames {
  116. get { return _frames; }
  117. }
  118. /// <summary>
  119. /// First frame of overlay
  120. /// </summary>
  121. public int OriginFrame {
  122. get { return _frameOrigin; }
  123. }
  124. #endregion
  125. #region Public Members
  126. /// <summary>
  127. /// Gets the overlay data.
  128. /// </summary>
  129. /// <param name="bg">Background color</param>
  130. /// <param name="fg">Foreground color</param>
  131. /// <returns>Overlay data</returns>
  132. public int[] GetOverlayDataS32(int bg, int fg) {
  133. int[] overlay = new int[Rows * Columns];
  134. BitArray bits = new BitArray(_data.Data);
  135. if (bits.Length < overlay.Length)
  136. throw new DicomDataException("Invalid overlay length: " + bits.Length);
  137. for (int i = 0, c = overlay.Length; i < c; i++) {
  138. if (bits.Get(i))
  139. overlay[i] = fg;
  140. else
  141. overlay[i] = bg;
  142. }
  143. return overlay;
  144. }
  145. /// <summary>
  146. /// Gets all overlays in a DICOM dataset.
  147. /// </summary>
  148. /// <param name="ds">Dataset</param>
  149. /// <returns>Array of overlays</returns>
  150. public static DicomOverlayData[] FromDataset(DicomDataset ds) {
  151. var groups = new List<ushort>();
  152. groups.AddRange(ds.Where(x => x.Tag.Group >= 0x6000 && x.Tag.Group <= 0x60FF && x.Tag.Element == 0x0010).Select(x => x.Tag.Group));
  153. var overlays = new List<DicomOverlayData>();
  154. foreach (var group in groups) {
  155. DicomOverlayData overlay = new DicomOverlayData(ds, group);
  156. overlays.Add(overlay);
  157. }
  158. return overlays.ToArray();
  159. }
  160. #endregion
  161. #region Private Methods
  162. private DicomTag OverlayTag(DicomTag tag) {
  163. return new DicomTag(_group, tag.Element);
  164. }
  165. private void Load(DicomDataset ds) {
  166. _rows = ds.Get<ushort>(OverlayTag(DicomTag.OverlayRows));
  167. _columns = ds.Get<ushort>(OverlayTag(DicomTag.OverlayColumns));
  168. _type = ds.Get<string>(OverlayTag(DicomTag.OverlayType), "Unknown");
  169. DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);
  170. if (ds.Contains(tag)) {
  171. short[] xy = ds.Get<short[]>(tag);
  172. if (xy != null && xy.Length == 2) {
  173. _originX = xy[0];
  174. _originY = xy[1];
  175. }
  176. }
  177. _bitsAllocated = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
  178. _bitPosition = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);
  179. tag = OverlayTag(DicomTag.OverlayData);
  180. if (ds.Contains(tag)) {
  181. var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
  182. _data = elem.Buffer;
  183. }
  184. _description = ds.Get<string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
  185. _subtype = ds.Get<string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
  186. _label = ds.Get<string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);
  187. _frames = ds.Get<int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
  188. _frameOrigin = ds.Get<ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);
  189. //TODO: include ROI
  190. }
  191. #endregion
  192. }
  193. }