private static void ComputeNormalizedModalityLut(IEnumerable <IFrameReference> frames, out double slope, out double intercept) { var rangeMin = double.MaxValue; var rangeMax = double.MinValue; foreach (var frameReference in frames) { var bitsStored = frameReference.Frame.BitsStored; var isSigned = frameReference.Frame.PixelRepresentation != 0; var rescaleSlope = frameReference.Frame.RescaleSlope; var rescaleIntercept = frameReference.Frame.RescaleIntercept; rangeMax = Math.Max(rangeMax, DicomPixelData.GetMaxPixelValue(bitsStored, isSigned) * rescaleSlope + rescaleIntercept); rangeMin = Math.Min(rangeMin, DicomPixelData.GetMinPixelValue(bitsStored, isSigned) * rescaleSlope + rescaleIntercept); } intercept = rangeMin; slope = (rangeMax - rangeMin) / 65535; }
private static LutValueRange SyncMinMaxValues(IComposableLut[] luts, int bitsStored, bool isSigned) { var range = new LutValueRange(); luts[0].MinInputValue = range.MinInputValue = DicomPixelData.GetMinPixelValue(bitsStored, isSigned); luts[0].MaxInputValue = range.MaxInputValue = DicomPixelData.GetMaxPixelValue(bitsStored, isSigned); var lutCount = luts.Length; for (var j = 1; j < lutCount; ++j) { luts[j].MinInputValue = luts[j - 1].MinOutputValue; luts[j].MaxInputValue = luts[j - 1].MaxOutputValue; } range.MinOutputValue = (int)Math.Round(luts[lutCount - 1].MinOutputValue); range.MaxOutputValue = (int)Math.Round(luts[lutCount - 1].MaxOutputValue); return(range); }
public void TestGetMinMaxPixelData() { Assert.AreEqual(0, DicomPixelData.GetMinPixelValue(7, false)); Assert.AreEqual(0, DicomPixelData.GetMinPixelValue(8, false)); Assert.AreEqual(0, DicomPixelData.GetMinPixelValue(12, false)); Assert.AreEqual(0, DicomPixelData.GetMinPixelValue(16, false)); Assert.AreEqual(127, DicomPixelData.GetMaxPixelValue(7, false)); Assert.AreEqual(255, DicomPixelData.GetMaxPixelValue(8, false)); Assert.AreEqual(4095, DicomPixelData.GetMaxPixelValue(12, false)); Assert.AreEqual(65535, DicomPixelData.GetMaxPixelValue(16, false)); Assert.AreEqual(-64, DicomPixelData.GetMinPixelValue(7, true)); Assert.AreEqual(-128, DicomPixelData.GetMinPixelValue(8, true)); Assert.AreEqual(-2048, DicomPixelData.GetMinPixelValue(12, true)); Assert.AreEqual(-32768, DicomPixelData.GetMinPixelValue(16, true)); Assert.AreEqual(63, DicomPixelData.GetMaxPixelValue(7, true)); Assert.AreEqual(127, DicomPixelData.GetMaxPixelValue(8, true)); Assert.AreEqual(2047, DicomPixelData.GetMaxPixelValue(12, true)); Assert.AreEqual(32767, DicomPixelData.GetMaxPixelValue(16, true)); }
/// <summary> /// Computes a pixel value suitable for volume padding purposes. /// </summary> /// <remarks> /// This function will try to use the value of either <see cref="DicomTags.PixelPaddingValue"/>, /// <see cref="DicomTags.SmallestPixelValueInSeries"/> or <see cref="DicomTags.SmallestImagePixelValue"/> /// (in order of preference). If none of these attributes exist in the dataset, then a suitable value is /// computed based on <see cref="DicomTags.BitsStored"/>, <see cref="DicomTags.PixelRepresentation"/>, /// and <see cref="DicomTags.PhotometricInterpretation"/>. /// </remarks> private static ushort ComputePixelPaddingValue(IList <IFrameReference> frames, double normalizedSlope, double normalizedIntercept) { var isSigned = frames[0].Frame.PixelRepresentation != 0; var isMonochrome1 = frames[0].Frame.PhotometricInterpretation.Equals(PhotometricInterpretation.Monochrome1); var bitsStored = Math.Max(1, Math.Min(16, frames[0].Frame.BitsStored)); var pixelPaddingValue = isMonochrome1 ? DicomPixelData.GetMaxPixelValue(bitsStored, isSigned) : DicomPixelData.GetMinPixelValue(bitsStored, isSigned); DicomAttribute attribute; var frameAttributeProvider = (IDicomAttributeProvider)frames[0].Frame; if (frameAttributeProvider.TryGetAttribute(DicomTags.PixelPaddingValue, out attribute)) { pixelPaddingValue = attribute.GetInt32(0, pixelPaddingValue); } else if (frameAttributeProvider.TryGetAttribute(DicomTags.SmallestPixelValueInSeries, out attribute)) { pixelPaddingValue = attribute.GetInt32(0, pixelPaddingValue); } else if (frameAttributeProvider.TryGetAttribute(DicomTags.SmallestImagePixelValue, out attribute)) { pixelPaddingValue = attribute.GetInt32(0, pixelPaddingValue); } // these next few lines may look positively stupid, but they are here for a good reason (See Ticket #7026) if (isSigned) { pixelPaddingValue = (short)pixelPaddingValue; } else { pixelPaddingValue = (ushort)pixelPaddingValue; } // since the volume now stores values with original modality LUT and normalizing function applied, we must apply same to this value (#9417) var rescaledPaddingValue = frames[0].Frame.RescaleSlope * pixelPaddingValue + frames[0].Frame.RescaleIntercept; var normalizedPaddingValue = (rescaledPaddingValue - normalizedIntercept) / normalizedSlope; return((ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(normalizedPaddingValue)))); }
internal IdentityVoiLinearLut(int bitsStored, bool signed) { MinInputValue = DicomPixelData.GetMinPixelValue(bitsStored, signed); MaxInputValue = DicomPixelData.GetMaxPixelValue(bitsStored, signed); }