Exemplo n.º 1
0
        /// <summary>
        /// Returns the value of the tag within the given dataset. Throws an exception if the tag was not present or if the
        /// tag value cannot be converted to type T.
        /// </summary>
        /// <typeparam name="T">The expected return type of the DICOM attribute.</typeparam>
        /// <param name="dataset">The DICOM dataset you wish to extract the tag from</param>
        /// <param name="tag">The tag you wish to extract from the dataset</param>
        /// <param name="i">For multivalue tags, specify the ith element to return</param>
        /// <returns>The required DICOM attribute as type T.</returns>
        /// <exception cref="ArgumentException">The dataset did not contain the expected tag or the DICOM tag does not have a value at index 'i'.</exception>
        /// <exception cref="ArgumentNullException">The DICOM dataset or DICOM tag provided was null.</exception>
        /// <exception cref="InvalidCastException">The DICOM tag could not be converted into the expected type.</exception>
        public static T GetRequiredDicomAttribute <T>(this DicomDataset dataset, DicomTag tag, uint i = 0)
        {
            dataset = dataset ?? throw new ArgumentNullException(nameof(dataset));
            tag     = tag ?? throw new ArgumentNullException(nameof(tag));

            // Attempt to find the expected tag in the DICOM dataset.
            if (!(dataset.FirstOrDefault(x => x.Tag == tag) is DicomElement dicomElement))
            {
                throw new ArgumentException($"The DICOM dataset does not contain the required attribute: {tag}.");
            }

            if (i >= dicomElement.Count)
            {
                throw new ArgumentException($"The DICOM tag {tag} only has {dicomElement.Count} parts. Expected to get value at index {i}.");
            }

            try
            {
                // Attempt to cast the i(th) element to the expected return type.
                return(dicomElement.Get <T>((int)i));
            }
            catch (Exception)
            {
                throw new InvalidCastException($"The attribute: {tag} could not be converted to the expected type: {typeof(T)}.");
            }
        }
Exemplo n.º 2
0
        private void Load(DicomDataset ds)
        {
            _rows    = ds.Get <ushort>(OverlayTag(DicomTag.OverlayRows));
            _columns = ds.Get <ushort>(OverlayTag(DicomTag.OverlayColumns));
            _type    = ds.Get <string>(OverlayTag(DicomTag.OverlayType), "Unknown");

            DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);

            if (ds.Contains(tag))
            {
                short[] xy = ds.Get <short[]>(tag);
                if (xy != null && xy.Length == 2)
                {
                    _originX = xy[0];
                    _originY = xy[1];
                }
            }

            _bitsAllocated = ds.Get <ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
            _bitPosition   = ds.Get <ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

            tag = OverlayTag(DicomTag.OverlayData);
            if (ds.Contains(tag))
            {
                var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
                _data = elem.Buffer;
            }

            _description = ds.Get <string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
            _subtype     = ds.Get <string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
            _label       = ds.Get <string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

            _frames      = ds.Get <int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
            _frameOrigin = ds.Get <ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

            //TODO: include ROI
        }
Exemplo n.º 3
0
        private DicomDirectoryRecord CreateRecordSequenceItem(DicomDirectoryRecordType recordType, DicomDataset dataset)
        {
            if (recordType == null)
            {
                throw new ArgumentNullException("recordType");
            }
            if (dataset == null)
            {
                throw new ArgumentNullException("dataset");
            }

            var sequenceItem = new DicomDirectoryRecord();

            //add record item attributes
            sequenceItem.Add <uint>(DicomTag.OffsetOfTheNextDirectoryRecord, 0);
            sequenceItem.Add <ushort>(DicomTag.RecordInUseFlag, 0xFFFF);
            sequenceItem.Add <uint>(DicomTag.OffsetOfReferencedLowerLevelDirectoryEntity, 0);
            sequenceItem.Add <string>(DicomTag.DirectoryRecordType, recordType.ToString());

            //copy the current dataset character set
            sequenceItem.Add(dataset.FirstOrDefault(d => d.Tag == DicomTag.SpecificCharacterSet));

            foreach (var tag in recordType.Tags)
            {
                if (dataset.Contains(tag))
                {
                    sequenceItem.Add(dataset.Get <DicomItem>(tag));
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Cannot find tag {0} for record type {1}", tag, recordType);
                }
            }

            return(sequenceItem);
        }
Exemplo n.º 4
0
		private DicomDirectoryRecord CreateRecordSequenceItem(DicomDirectoryRecordType recordType, DicomDataset dataset) {
			if (recordType == null)
				throw new ArgumentNullException("recordType");
			if (dataset == null)
				throw new ArgumentNullException("dataset");

			var sequenceItem = new DicomDirectoryRecord();

			//add record item attributes
			sequenceItem.Add<uint>(DicomTag.OffsetOfTheNextDirectoryRecord, 0);
			sequenceItem.Add<ushort>(DicomTag.RecordInUseFlag, 0xFFFF);
			sequenceItem.Add<uint>(DicomTag.OffsetOfReferencedLowerLevelDirectoryEntity, 0);
			sequenceItem.Add<string>(DicomTag.DirectoryRecordType, recordType.ToString());

			//copy the current dataset character set
			sequenceItem.Add(dataset.FirstOrDefault(d => d.Tag == DicomTag.SpecificCharacterSet));

			foreach (var tag in recordType.Tags) {
				if (dataset.Contains(tag)) {
					sequenceItem.Add(dataset.Get<DicomItem>(tag));
				} else {
					System.Diagnostics.Debug.WriteLine("Cannot find tag {0} for record type {1}", tag, recordType);
				}
			}

			return sequenceItem;
		}
Exemplo n.º 5
0
		private void Load(DicomDataset ds) {
			_rows = ds.Get<ushort>(OverlayTag(DicomTag.OverlayRows));
			_columns = ds.Get<ushort>(OverlayTag(DicomTag.OverlayColumns));
			
			var type = ds.Get<string>(OverlayTag(DicomTag.OverlayType), "Unknown");
			if (type.StartsWith("R"))
				_type = DicomOverlayType.ROI;
			else
				_type = DicomOverlayType.Graphics;

			DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);
			if (ds.Contains(tag)) {
				_originX = ds.Get<short>(tag, 0, 1);
				_originY = ds.Get<short>(tag, 1, 1);
			}

			_bitsAllocated = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
			_bitPosition = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

			tag = OverlayTag(DicomTag.OverlayData);
			if (ds.Contains(tag)) {
				var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
				_data = elem.Buffer;
			} else {
				// overlay embedded in high bits of pixel data
				if (ds.InternalTransferSyntax.IsEncapsulated)
					throw new DicomImagingException("Attempted to extract embedded overlay from compressed pixel data. Decompress pixel data before attempting this operation.");

				var pixels = DicomPixelData.Create(ds);

				// (1,1) indicates top left pixel of image
				int ox = Math.Max(0, _originX - 1);
				int oy = Math.Max(0, _originY - 1);
				int ow = Math.Min(_rows, pixels.Width - _rows - ox);
				int oh = Math.Min(_columns, pixels.Height - _columns - oy);

				var frame = pixels.GetFrame(0);

				// calculate length of output buffer
				var count = (_rows * _columns) / 8;
				if (((_rows * _columns) % 8) != 0)
					count++;
				if ((count & 1) != 0)
					count++;

				var bytes = new byte[count];
				var bits = new BitArray(bytes);
				int mask = 1 << _bitPosition;

				if (pixels.BitsAllocated == 8) {
					var data = ByteBufferEnumerator<byte>.Create(frame).ToArray();

					for (int y = oy; y < oh; y++) {
						int n = (y * pixels.Width) + ox;
						int i = (y - oy) * _columns;
						for (int x = ox; x < ow; x++) {
							if ((data[n] & mask) != 0)
								bits[i] = true;
							n++;
							i++;
						}
					}
				} else if (pixels.BitsAllocated == 16) {
					// we don't really care if the pixel data is signed or not
					var data = ByteBufferEnumerator<ushort>.Create(frame).ToArray();

					for (int y = oy; y < oh; y++) {
						int n = (y * pixels.Width) + ox;
						int i = (y - oy) * _columns;
						for (int x = ox; x < ow; x++) {
							if ((data[n] & mask) != 0)
								bits[i] = true;
							n++;
							i++;
						}
					}
				} else {
					throw new DicomImagingException("Unable to extract embedded overlay from pixel data with bits stored greater than 16.");
				}

				_data = new MemoryByteBuffer(bytes);
			}

			_description = ds.Get<string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
			_subtype = ds.Get<string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
			_label = ds.Get<string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

			_frames = ds.Get<int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
			_frameOrigin = ds.Get<ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

			//TODO: include ROI
		}
Exemplo n.º 6
0
        private void Load(DicomDataset ds)
        {
            _rows    = ds.Get <ushort>(OverlayTag(DicomTag.OverlayRows));
            _columns = ds.Get <ushort>(OverlayTag(DicomTag.OverlayColumns));

            var type = ds.Get <string>(OverlayTag(DicomTag.OverlayType), "Unknown");

            if (type.StartsWith("R"))
            {
                _type = DicomOverlayType.ROI;
            }
            else
            {
                _type = DicomOverlayType.Graphics;
            }

            DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);

            if (ds.Contains(tag))
            {
                _originX = ds.Get <short>(tag, 0, 1);
                _originY = ds.Get <short>(tag, 1, 1);
            }

            _bitsAllocated = ds.Get <ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
            _bitPosition   = ds.Get <ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

            tag = OverlayTag(DicomTag.OverlayData);
            if (ds.Contains(tag))
            {
                var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
                _data = elem.Buffer;
            }
            else
            {
                // overlay embedded in high bits of pixel data
                if (ds.InternalTransferSyntax.IsEncapsulated)
                {
                    throw new DicomImagingException("Attempted to extract embedded overlay from compressed pixel data. Decompress pixel data before attempting this operation.");
                }

                var pixels = DicomPixelData.Create(ds);

                // (1,1) indicates top left pixel of image
                int ox = Math.Max(0, _originX - 1);
                int oy = Math.Max(0, _originY - 1);
                int ow = _rows - (pixels.Width - _rows - ox);
                int oh = _columns - (pixels.Height - _columns - oy);

                var frame = pixels.GetFrame(0);

                // calculate length of output buffer
                var count = (_rows * _columns) / 8;
                if (((_rows * _columns) % 8) != 0)
                {
                    count++;
                }
                if ((count & 1) != 0)
                {
                    count++;
                }

                var bytes = new byte[count];
                var bits  = new BitArray(bytes);
                int mask  = 1 << _bitPosition;

                if (pixels.BitsAllocated == 8)
                {
                    var data = ByteBufferEnumerator <byte> .Create(frame).ToArray();

                    for (int y = oy; y < oh; y++)
                    {
                        int n = (y * pixels.Width) + ox;
                        int i = (y - oy) * _columns;
                        for (int x = ox; x < ow; x++)
                        {
                            if ((data[n] & mask) != 0)
                            {
                                bits[i] = true;
                            }
                            n++;
                            i++;
                        }
                    }
                }
                else if (pixels.BitsAllocated == 16)
                {
                    // we don't really care if the pixel data is signed or not
                    var data = ByteBufferEnumerator <ushort> .Create(frame).ToArray();

                    for (int y = oy; y < oh; y++)
                    {
                        int n = (y * pixels.Width) + ox;
                        int i = (y - oy) * _columns;
                        for (int x = ox; x < ow; x++)
                        {
                            if ((data[n] & mask) != 0)
                            {
                                bits[i] = true;
                            }
                            n++;
                            i++;
                        }
                    }
                }
                else
                {
                    throw new DicomImagingException("Unable to extract embedded overlay from pixel data with bits stored greater than 16.");
                }

                _data = new MemoryByteBuffer(bytes);
            }

            _description = ds.Get <string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
            _subtype     = ds.Get <string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
            _label       = ds.Get <string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

            _frames      = ds.Get <int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
            _frameOrigin = ds.Get <ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

            //TODO: include ROI
        }
Exemplo n.º 7
0
        private void Load(DicomDataset ds)
        {
            _rows = ds.Get<ushort>(OverlayTag(DicomTag.OverlayRows));
            _columns = ds.Get<ushort>(OverlayTag(DicomTag.OverlayColumns));
            _type = ds.Get<string>(OverlayTag(DicomTag.OverlayType), "Unknown");

            DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);
            if (ds.Contains(tag)) {
                short[] xy = ds.Get<short[]>(tag);
                if (xy != null && xy.Length == 2) {
                    _originX = xy[0];
                    _originY = xy[1];
                }
            }

            _bitsAllocated = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
            _bitPosition = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

            tag = OverlayTag(DicomTag.OverlayData);
            if (ds.Contains(tag)) {
                var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
                _data = elem.Buffer;
            }

            _description = ds.Get<string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
            _subtype = ds.Get<string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
            _label = ds.Get<string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

            _frames = ds.Get<int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
            _frameOrigin = ds.Get<ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

            //TODO: include ROI
        }