/// <summary> /// Cloning constructor. /// </summary> protected DicomGrayscalePresentationImage(DicomGrayscalePresentationImage source, ICloningContext context) : base(source, context) { Frame frame = source.Frame; _frameReference = frame.CreateTransientReference(); _dicomVoiLuts = new DicomVoiLuts(this); }
protected void DeserializeSoftcopyVoiLut(SoftcopyVoiLutModuleIod module, T image) { SoftcopyVoiLutModuleIod.SoftcopyVoiLutSequenceItem[] lutSequences = module.SoftcopyVoiLutSequence; if (lutSequences == null) { return; } DicomVoiLuts voiLuts = (DicomVoiLuts)image.DicomVoiLuts; voiLuts.ReinitializePresentationLuts(this.PresentationSopInstanceUid); foreach (SoftcopyVoiLutModuleIod.SoftcopyVoiLutSequenceItem lutSequence in lutSequences) { var dictionary = !DeserializeIgnoreImageRelationship ? new ImageSopInstanceReferenceDictionary(lutSequence.ReferencedImageSequence, true) : null; if (dictionary == null || dictionary.ReferencesFrame(image.ImageSop.SopInstanceUid, image.Frame.FrameNumber)) { if (lutSequence.CountWindows > 0) { double[] widths = lutSequence.WindowWidth; double[] centers = lutSequence.WindowCenter; int countWindows = Math.Min(widths.Length, centers.Length); string[] explanation = lutSequence.WindowCenterWidthExplanation; if (explanation == null || explanation.Length < countWindows) { explanation = new string[countWindows]; } if (lutSequence.VoiLutFunction == VoiLutFunction.Sigmoid) { Platform.Log(LogLevel.Warn, "Sigmoid LUTs are not currently supported."); } else // default is linear { for (int n = 0; n < countWindows; n++) { voiLuts.AddPresentationLinearLut(widths[n], centers[n], explanation[n]); } } } if (lutSequence.CountDataLuts > 0) { foreach (VoiLutSequenceItem item in lutSequence.VoiLutSequence) { DataLutIod dl = DataLutIod.Create(item.DicomSequenceItem, item.DicomAttributeProvider[DicomTags.LutDescriptor] is DicomAttributeSS, false); voiLuts.AddPresentationDataLut(new VoiDataLut(dl.FirstMappedPixelValue, dl.BitsPerEntry, dl.Data, dl.Explanation)); } } } } }
/// <summary> /// Initializes a new instance of <see cref="DicomGrayscalePresentationImage"/>. /// </summary> /// <param name="frameReference">A <see cref="IFrameReference">reference</see> to the frame from which to construct the image.</param> public DicomGrayscalePresentationImage(IFrameReference frameReference) : base(frameReference.Frame.Rows, frameReference.Frame.Columns, frameReference.Frame.BitsAllocated, frameReference.Frame.BitsStored, frameReference.Frame.HighBit, frameReference.Frame.PixelRepresentation != 0, frameReference.Frame.PhotometricInterpretation == PhotometricInterpretation.Monochrome1, frameReference.Frame.RescaleSlope, frameReference.Frame.RescaleIntercept, frameReference.Frame.NormalizedPixelSpacing.Column, frameReference.Frame.NormalizedPixelSpacing.Row, frameReference.Frame.PixelAspectRatio.Column, frameReference.Frame.PixelAspectRatio.Row, frameReference.Frame.GetNormalizedPixelData) { _frameReference = frameReference; _dicomVoiLuts = new DicomVoiLuts(this); base.PresentationState = PresentationState.DicomDefault; if (ImageSop.Modality == "MG") { // use a special image spatial transform for digital mammography CompositeImageGraphic.SpatialTransform = new MammographyImageSpatialTransform(CompositeImageGraphic, Frame.Rows, Frame.Columns, Frame.NormalizedPixelSpacing.Column, Frame.NormalizedPixelSpacing.Row, Frame.PixelAspectRatio.Column, Frame.PixelAspectRatio.Row, Frame.PatientOrientation, ImageSop.ImageLaterality); } if (ImageSop.Modality == "PT" && frameReference.Frame.IsSubnormalRescale) { // some PET images have such a small slope that all stored pixel values map to one single value post-modality LUT // we detect this condition here and apply the inverse of the modality LUT as a normalization function for VOI purposes // http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/8930b159cb2a8e73?pli=1 ImageGraphic.NormalizationLut = new NormalizationLutLinear(frameReference.Frame.RescaleSlope, frameReference.Frame.RescaleIntercept); } Initialize(); }