示例#1
0
		/// <summary>
		/// Constructs a new region of interest, specifying an <see cref="IPresentationImage"/> as the source of the pixel data.
		/// </summary>
		/// <param name="presentationImage">The image containing the source pixel data.</param>
		protected Roi(IPresentationImage presentationImage)
		{
			IImageGraphicProvider provider = presentationImage as IImageGraphicProvider;
			if (provider == null)
				return;

			_imageRows = provider.ImageGraphic.Rows;
			_imageColumns = provider.ImageGraphic.Columns;
			_presentationImage = presentationImage;

			_pixelData = provider.ImageGraphic.PixelData;
			if (presentationImage is IModalityLutProvider)
				_modalityLut = ((IModalityLutProvider) presentationImage).ModalityLut;

			if (presentationImage is IImageSopProvider)
			{
				Frame frame = ((IImageSopProvider) presentationImage).Frame;
				_normalizedPixelSpacing = frame.NormalizedPixelSpacing;
				_pixelAspectRatio = frame.PixelAspectRatio;
				_modality = frame.ParentImageSop.Modality;
				_modalityLutUnits = frame.RescaleUnits;
				_subnormalModalityLut = frame.IsSubnormalRescale;
			}
			else
			{
				_normalizedPixelSpacing = new PixelSpacing(0, 0);
				_pixelAspectRatio = new PixelAspectRatio(0, 0);
				_modalityLutUnits = RescaleUnits.None;
				_subnormalModalityLut = false;
			}
		}
示例#2
0
        private void InitializeNecessaryLuts(Luts luts)
        {
            if (luts >= Luts.Modality && LutComposer.ModalityLut == null)
            {
                IModalityLut modalityLut =
                    this.LutFactory.GetModalityLutLinear(this.BitsStored, this.IsSigned, _rescaleSlope, _rescaleIntercept);

                this.LutComposer.ModalityLut = modalityLut;
            }

            if (luts >= Luts.Voi && LutComposer.VoiLut == null)
            {
                IVoiLut lut = null;

                if (_voiLutFactory != null)
                {
                    lut = _voiLutFactory.CreateVoiLut(this);
                }

                if (lut == null)
                {
                    lut = new IdentityVoiLinearLut();
                }

                (this as IVoiLutInstaller).InstallVoiLut(lut);
            }
        }
示例#3
0
        public void ComposeUnsigned16()
        {
            const int    bitsStored       = 16;
            const bool   isSigned         = false;
            const double windowWidth      = 350;
            const double windowLevel      = 40;
            const double rescaleSlope     = 1;
            const double rescaleIntercept = -1024;

            IModalityLut modalityLut = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(0, modalityLut.MinInputValue);
            Assert.AreEqual(65535, modalityLut.MaxInputValue);
            Assert.AreEqual(-1024, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(64511, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-1024, modalityLut[0], _tolerance);
            Assert.AreEqual(64511, modalityLut[65535], _tolerance);

            BasicVoiLutLinear voiLut = new BasicVoiLutLinear(
                modalityLut.MinOutputValue,
                modalityLut.MaxOutputValue);

            voiLut.WindowWidth  = windowWidth;
            voiLut.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLut;
            lutComposer.VoiLut      = voiLut;

            Assert.AreEqual(-1024, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(64511, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(-1024, voiLut.MinOutputValue, _tolerance);
            Assert.AreEqual(64511, voiLut.MaxOutputValue, _tolerance);

            // Left Window
            Assert.AreEqual(-1024, voiLut[-135], _tolerance);

            // Right Window
            Assert.AreEqual(64511, voiLut[215], _tolerance);

            // Window center
            // 31837 is correct according to DICOM: See PS 3.3 C.11.2.1.2 for the calculation.
            // Although you might think it should be 31744 (65535/2 - 1024), it is not.
            Assert.AreEqual(31837.38968, voiLut[40], _tolerance);

            //For this, we want the output range to be the same as the VOI.
            var output = lutComposer.GetOutputLut((int)Math.Round(voiLut.MinOutputValue), (int)Math.Round(voiLut.MaxOutputValue));

            Assert.AreEqual(-1024, output.Data[0]);
            Assert.AreEqual(64511, output.Data[65535]);
            Assert.AreEqual(31837, output.Data[1064]);
        }
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="pixelData">The pixel data the algorithm will be run on.</param>
		/// <param name="modalityLut">The modality lut to use for calculating <see cref="WindowWidth"/> and <see cref="WindowCenter"/>, if applicable.</param>
		protected AlgorithmCalculatedVoiLutLinear(GrayscalePixelData pixelData, IModalityLut modalityLut)
		{
			Platform.CheckForNullReference(pixelData, "pixelData");

			_pixelData = pixelData;
			_modalityLut = modalityLut;

			_windowWidth = double.NaN;
			_windowCenter = double.NaN;
		}
示例#5
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="pixelData">The pixel data the algorithm will be run on.</param>
        /// <param name="modalityLut">The modality lut to use for calculating <see cref="WindowWidth"/> and <see cref="WindowCenter"/>, if applicable.</param>
        protected AlgorithmCalculatedVoiLutLinear(GrayscalePixelData pixelData, IModalityLut modalityLut)
        {
            Platform.CheckForNullReference(pixelData, "pixelData");

            _pixelData   = pixelData;
            _modalityLut = modalityLut;

            _windowWidth  = double.NaN;
            _windowCenter = double.NaN;
        }
示例#6
0
        public void ComposeUnsigned8()
        {
            const int    bitsStored       = 8;
            const bool   isSigned         = false;
            const double windowWidth      = 128;
            const double windowLevel      = 74;
            const double rescaleSlope     = 0.5;
            const double rescaleIntercept = 10;

            IModalityLut modalityLut = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(0, modalityLut.MinInputValue);
            Assert.AreEqual(255, modalityLut.MaxInputValue);
            Assert.AreEqual(10, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(137.5, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(10, modalityLut[0], _tolerance);
            Assert.AreEqual(137.5, modalityLut[255], _tolerance);

            BasicVoiLutLinear voiLut = new BasicVoiLutLinear();

            voiLut.WindowWidth  = windowWidth;
            voiLut.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLut;
            lutComposer.VoiLut      = voiLut;

            Assert.AreEqual(10, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(137.5, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(10, voiLut.MinOutputValue);
            Assert.AreEqual(137.5, voiLut.MaxOutputValue);
            Assert.AreEqual(10, voiLut[10], _tolerance);
            Assert.AreEqual(137.5, voiLut[138], _tolerance);
            Assert.AreEqual(73.24803, voiLut[73], _tolerance);

            Assert.AreEqual(0, lutComposer.MinInputValue);
            Assert.AreEqual(255, lutComposer.MaxInputValue);

            //For this, we want the output range to be the same as the VOI.
            var output = lutComposer.GetOutputLut((int)Math.Round(voiLut.MinOutputValue), (int)Math.Round(voiLut.MaxOutputValue));

            Assert.AreEqual(10, output.MinOutputValue);
            Assert.AreEqual(138, output.MaxOutputValue);

            Assert.AreEqual(10, output[0], _tolerance);
            Assert.AreEqual(138, output[255], _tolerance);
            Assert.AreEqual(74, output[127], _tolerance);
        }
示例#7
0
        public void ComposeUnsigned16()
        {
            int    bitsStored       = 16;
            bool   isSigned         = false;
            double windowWidth      = 350;
            double windowLevel      = 40;
            double rescaleSlope     = 1;
            double rescaleIntercept = -1024;

            IModalityLut modalityLUT = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(0, modalityLUT.MinInputValue);
            Assert.AreEqual(65535, modalityLUT.MaxInputValue);
            Assert.AreEqual(-1024, modalityLUT.MinOutputValue, _tolerance);
            Assert.AreEqual(64511, modalityLUT.MaxOutputValue, _tolerance);
            Assert.AreEqual(-1024, modalityLUT[0], _tolerance);
            Assert.AreEqual(64511, modalityLUT[65535], _tolerance);

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear(
                modalityLUT.MinOutputValue,
                modalityLUT.MaxOutputValue);

            voiLUT.WindowWidth  = windowWidth;
            voiLUT.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLUT;
            lutComposer.VoiLut      = voiLUT;

            Assert.AreEqual(-1024, voiLUT.MinInputValue, _tolerance);
            Assert.AreEqual(64511, voiLUT.MaxInputValue, _tolerance);
            Assert.AreEqual(-1024, voiLUT.MinOutputValue);
            Assert.AreEqual(64511, voiLUT.MaxOutputValue);

            // Left Window
            Assert.AreEqual(-1024, voiLUT[-135]);
            // Right Window
            Assert.AreEqual(64511, voiLUT[215]);
            // Window center
            // 31837 is correct according to DICOM: See PS 3.3 C.11.2.1.2 for the calculation.
            // Although you might think it should be 31744 (65535/2 - 1024), it is not.
            Assert.AreEqual(31837, voiLUT[40]);

            Assert.AreEqual(-1024, lutComposer.Data[0]);
            Assert.AreEqual(64511, lutComposer.Data[65535]);
            Assert.AreEqual(31837, lutComposer.Data[1064]);
        }
示例#8
0
        public void ComposeSigned12()
        {
            int    bitsStored       = 12;
            bool   isSigned         = true;
            double windowWidth      = 16384;
            double windowLevel      = 4096;
            double rescaleSlope     = 1.0;
            double rescaleIntercept = 0;

            IModalityLut modalityLUT = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(-2048, modalityLUT.MinInputValue);
            Assert.AreEqual(2047, modalityLUT.MaxInputValue);
            Assert.AreEqual(-2048, modalityLUT.MinOutputValue, _tolerance);
            Assert.AreEqual(2047, modalityLUT.MaxOutputValue, _tolerance);
            Assert.AreEqual(-2048, modalityLUT[-2048], _tolerance);
            Assert.AreEqual(2047, modalityLUT[2047], _tolerance);

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();

            voiLUT.WindowWidth  = windowWidth;
            voiLUT.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLUT;
            lutComposer.VoiLut      = voiLUT;

            Assert.AreEqual(-2048, voiLUT.MinInputValue, _tolerance);
            Assert.AreEqual(2047, voiLUT.MaxInputValue, _tolerance);
            Assert.AreEqual(-2048, voiLUT.MinOutputValue);
            Assert.AreEqual(2047, voiLUT.MaxOutputValue);
            Assert.AreEqual(-1536, voiLUT[-2047]);
            Assert.AreEqual(-1024, voiLUT[0]);
            Assert.AreEqual(-513, voiLUT[2047]);

            //This test is a little different from the others, it tests the output using a grayscale color map.
            var colorMap = _lutFactory.GetGrayscaleColorMap();

            colorMap.MaxInputValue = lutComposer.MaxOutputValue;
            colorMap.MinInputValue = lutComposer.MinOutputValue;
            Assert.AreEqual(31, 0x000000ff & colorMap[lutComposer.Data[0]]);
            Assert.AreEqual(63, 0x000000ff & colorMap[lutComposer.Data[2048]]);
            Assert.AreEqual(95, 0x000000ff & colorMap[lutComposer.Data[4095]]);
        }
示例#9
0
        public void ComposeUnsigned8()
        {
            int    bitsStored       = 8;
            bool   isSigned         = false;
            double windowWidth      = 128;
            double windowLevel      = 74;
            double rescaleSlope     = 0.5;
            double rescaleIntercept = 10;

            IModalityLut modalityLUT = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(0, modalityLUT.MinInputValue);
            Assert.AreEqual(255, modalityLUT.MaxInputValue);
            Assert.AreEqual(10, modalityLUT.MinOutputValue, _tolerance);
            Assert.AreEqual(137.5, modalityLUT.MaxOutputValue, _tolerance);
            Assert.AreEqual(10, modalityLUT[0], _tolerance);
            Assert.AreEqual(137.5, modalityLUT[255], _tolerance);

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();

            voiLUT.WindowWidth  = windowWidth;
            voiLUT.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLUT;
            lutComposer.VoiLut      = voiLUT;

            Assert.AreEqual(10, voiLUT.MinInputValue, _tolerance);
            Assert.AreEqual(137.5, voiLUT.MaxInputValue, _tolerance);
            Assert.AreEqual(10, voiLUT.MinOutputValue);
            Assert.AreEqual(138, voiLUT.MaxOutputValue);
            Assert.AreEqual(10, voiLUT[10]);
            Assert.AreEqual(138, voiLUT[138]);
            Assert.AreEqual(73, voiLUT[73]);

            Assert.AreEqual(0, lutComposer.MinInputValue);
            Assert.AreEqual(255, lutComposer.MaxInputValue);
            Assert.AreEqual(10, lutComposer.MinOutputValue);
            Assert.AreEqual(138, lutComposer.MaxOutputValue);

            Assert.AreEqual(10, lutComposer[0]);
            Assert.AreEqual(138, lutComposer[255]);
            Assert.AreEqual(74, lutComposer[127]);
        }
示例#10
0
        public void ComposeSigned8()
        {
            // Use case:  Window width is 1
            const int    bitsStored       = 8;
            const bool   isSigned         = true;
            const double windowWidth      = 1;
            const double windowLevel      = 0;
            const double rescaleSlope     = 0.5;
            const double rescaleIntercept = 10;

            IModalityLut modalityLut = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(-128, modalityLut.MinInputValue);
            Assert.AreEqual(127, modalityLut.MaxInputValue);
            Assert.AreEqual(-54, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(73.5, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-54, modalityLut[-128], _tolerance);
            Assert.AreEqual(73.5, modalityLut[127], _tolerance);

            BasicVoiLutLinear voiLut = new BasicVoiLutLinear();

            voiLut.WindowWidth  = windowWidth;
            voiLut.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLut;
            lutComposer.VoiLut      = voiLut;

            Assert.AreEqual(-54, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(73.5, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(-54, voiLut.MinOutputValue, _tolerance);
            Assert.AreEqual(73.5, voiLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-54, voiLut[-1], _tolerance);
            Assert.AreEqual(73.5, voiLut[0], _tolerance);

            //For this, we want the output range to be the same as the VOI.
            var output = lutComposer.GetOutputLut((int)Math.Round(voiLut.MinOutputValue), (int)Math.Round(voiLut.MaxOutputValue));

            Assert.AreEqual(-54, output.Data[0]);
            Assert.AreEqual(-54, output.Data[106]);
            Assert.AreEqual(-54, output.Data[107]);             // stored pixel -21 which, if you don't round off the modality LUT, is actually -0.5 and therefore has a VOI value of -54
            Assert.AreEqual(74, output.Data[108]);
        }
示例#11
0
        public void ComposeUnsigned12()
        {
            const int    bitsStored       = 12;
            const bool   isSigned         = false;
            const double windowWidth      = 2800;
            const double windowLevel      = 1600;
            const double rescaleSlope     = 0.683760684;
            const double rescaleIntercept = 200;

            IModalityLut modalityLut = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(0, modalityLut.MinInputValue);
            Assert.AreEqual(4095, modalityLut.MaxInputValue);
            Assert.AreEqual(200, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(3000, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(200, modalityLut[0], _tolerance);
            Assert.AreEqual(3000, modalityLut[4095], _tolerance);

            BasicVoiLutLinear voiLut = new BasicVoiLutLinear();

            voiLut.WindowWidth  = windowWidth;
            voiLut.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLut;
            lutComposer.VoiLut      = voiLut;

            Assert.AreEqual(200, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(3000, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(200, voiLut.MinOutputValue, _tolerance);
            Assert.AreEqual(3000, voiLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(200, voiLut[200], _tolerance);
            Assert.AreEqual(3000, voiLut[3000], _tolerance);
            Assert.AreEqual(1600.50018, voiLut[1600], _tolerance);

            //For this, we want the output range to be the same as the VOI.
            var output = lutComposer.GetOutputLut((int)Math.Round(voiLut.MinOutputValue), (int)Math.Round(voiLut.MaxOutputValue));

            Assert.AreEqual(200, output.Data[0]);
            Assert.AreEqual(3000, output.Data[4095]);
            Assert.AreEqual(1601, output.Data[2048]);
        }
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="minPixelValue">The minimum raw pixel value in the pixel data.</param>
		/// <param name="maxPixelValue">The maximum raw pixel value in the pixel data.</param>
		/// <param name="modalityLut">The modality LUT to use for calculating <see cref="AlgorithmCalculatedVoiLutLinear.WindowWidth"/>
		/// and <see cref="AlgorithmCalculatedVoiLutLinear.WindowCenter"/>, if applicable.</param>
		public MinMaxPixelLinearLut(int minPixelValue, int maxPixelValue, IModalityLut modalityLut)
		{
			double windowStart = minPixelValue;
			double windowEnd = maxPixelValue;

			if (modalityLut != null)
			{
				windowStart = modalityLut[windowStart];
				windowEnd = modalityLut[windowEnd];
			}

			// round the window to one decimal place so it's not ridiculous
			// value is calculated anyway and thus has no significance outside of display
			var windowWidth = Math.Max(windowEnd - windowStart + 1, 1);
			_windowWidth = Math.Round(windowWidth, 1);
			_windowCenter = Math.Round(windowStart + windowWidth/2, 1);
		}
示例#13
0
        public void ComposeSigned8()
        {
            // Use case:  Window width is 1
            int    bitsStored       = 8;
            bool   isSigned         = true;
            double windowWidth      = 1;
            double windowLevel      = 0;
            double rescaleSlope     = 0.5;
            double rescaleIntercept = 10;

            IModalityLut modalityLUT = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(-128, modalityLUT.MinInputValue);
            Assert.AreEqual(127, modalityLUT.MaxInputValue);
            Assert.AreEqual(-54, modalityLUT.MinOutputValue, _tolerance);
            Assert.AreEqual(73.5, modalityLUT.MaxOutputValue, _tolerance);
            Assert.AreEqual(-54, modalityLUT[-128], _tolerance);
            Assert.AreEqual(73.5, modalityLUT[127], _tolerance);

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();

            voiLUT.WindowWidth  = windowWidth;
            voiLUT.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLUT;
            lutComposer.VoiLut      = voiLUT;

            Assert.AreEqual(-54, voiLUT.MinInputValue, _tolerance);
            Assert.AreEqual(73.5, voiLUT.MaxInputValue, _tolerance);
            Assert.AreEqual(-54, voiLUT.MinOutputValue);
            Assert.AreEqual(74, voiLUT.MaxOutputValue);
            Assert.AreEqual(-54, voiLUT[-1]);
            Assert.AreEqual(74, voiLUT[0]);

            Assert.AreEqual(-54, lutComposer.Data[0]);
            Assert.AreEqual(-54, lutComposer.Data[106]);
            Assert.AreEqual(-54, lutComposer.Data[107]);             // stored pixel -21 which, if you don't round off the modality LUT, is actually -0.5 and therefore has a VOI value of -54
            Assert.AreEqual(74, lutComposer.Data[108]);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="minPixelValue">The minimum raw pixel value in the pixel data.</param>
        /// <param name="maxPixelValue">The maximum raw pixel value in the pixel data.</param>
        /// <param name="modalityLut">The modality LUT to use for calculating <see cref="AlgorithmCalculatedVoiLutLinear.WindowWidth"/>
        /// and <see cref="AlgorithmCalculatedVoiLutLinear.WindowCenter"/>, if applicable.</param>
        public MinMaxPixelLinearLut(int minPixelValue, int maxPixelValue, IModalityLut modalityLut)
        {
            double windowStart = minPixelValue;
            double windowEnd   = maxPixelValue;

            if (modalityLut != null)
            {
                windowStart = modalityLut[windowStart];
                windowEnd   = modalityLut[windowEnd];
            }

            // round the window to one decimal place so it's not ridiculous
            // value is calculated anyway and thus has no significance outside of display
            var windowWidth = Math.Max(windowEnd - windowStart + 1, 1);

            _windowWidth  = Math.Round(windowWidth, 1);
            _windowCenter = Math.Round(windowStart + windowWidth / 2, 1);
        }
示例#15
0
        public void ComposeSigned16()
        {
            int    bitsStored       = 16;
            bool   isSigned         = true;
            double windowWidth      = 350;
            double windowLevel      = 40;
            double rescaleSlope     = 1;
            double rescaleIntercept = -1024;

            IModalityLut modalityLUT = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(-32768, modalityLUT.MinInputValue);
            Assert.AreEqual(32767, modalityLUT.MaxInputValue);
            Assert.AreEqual(-33792, modalityLUT.MinOutputValue, _tolerance);
            Assert.AreEqual(31743, modalityLUT.MaxOutputValue, _tolerance);
            Assert.AreEqual(-33792, modalityLUT[-32768], _tolerance);
            Assert.AreEqual(31743, modalityLUT[32767], _tolerance);

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();

            voiLUT.WindowWidth  = windowWidth;
            voiLUT.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLUT;
            lutComposer.VoiLut      = voiLUT;

            Assert.AreEqual(-33792, voiLUT.MinInputValue, _tolerance);
            Assert.AreEqual(31743, voiLUT.MaxInputValue, _tolerance);
            Assert.AreEqual(-33792, voiLUT.MinOutputValue);
            Assert.AreEqual(31743, voiLUT.MaxOutputValue);

            // Left Window
            Assert.AreEqual(-33792, voiLUT[-135]);
            // Right Window
            Assert.AreEqual(31743, voiLUT[215]);
            // Window center
            Assert.AreEqual(-931, voiLUT[40]);
        }
示例#16
0
        public void ComposeUnsigned12()
        {
            int    bitsStored       = 12;
            bool   isSigned         = false;
            double windowWidth      = 2800;
            double windowLevel      = 1600;
            double rescaleSlope     = 0.683760684;
            double rescaleIntercept = 200;

            IModalityLut modalityLUT = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(0, modalityLUT.MinInputValue);
            Assert.AreEqual(4095, modalityLUT.MaxInputValue);
            Assert.AreEqual(200, modalityLUT.MinOutputValue, _tolerance);
            Assert.AreEqual(3000, modalityLUT.MaxOutputValue, _tolerance);
            Assert.AreEqual(200, modalityLUT[0], _tolerance);
            Assert.AreEqual(3000, modalityLUT[4095], _tolerance);

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();

            voiLUT.WindowWidth  = windowWidth;
            voiLUT.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLUT;
            lutComposer.VoiLut      = voiLUT;

            Assert.AreEqual(200, voiLUT.MinInputValue, _tolerance);
            Assert.AreEqual(3000, voiLUT.MaxInputValue, _tolerance);
            Assert.AreEqual(200, voiLUT.MinOutputValue);
            Assert.AreEqual(3000, voiLUT.MaxOutputValue);
            Assert.AreEqual(200, voiLUT[200]);
            Assert.AreEqual(3000, voiLUT[3000]);
            Assert.AreEqual(1601, voiLUT[1600]);

            Assert.AreEqual(200, lutComposer.Data[0]);
            Assert.AreEqual(3000, lutComposer.Data[4095]);
            Assert.AreEqual(1601, lutComposer.Data[2048]);
        }
        private static double CalculateMean
        (
            RectangleF roiBoundingBox,
            GrayscalePixelData pixelData,
            IModalityLut modalityLut,
            IsPointInRoiDelegate isPointInRoi
        )
        {
            double sum        = 0;
            int    pixelCount = 0;

            var boundingBox = RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox));

            pixelData.ForEachPixel(
                boundingBox.Left,
                boundingBox.Top,
                boundingBox.Right,
                boundingBox.Bottom,
                delegate(int i, int x, int y, int pixelIndex)
            {
                if (isPointInRoi(x, y))
                {
                    ++pixelCount;
                    // Make sure we run the raw pixel through the modality LUT
                    // when doing the calculation. Note that the modality LUT
                    // can be something other than a rescale intercept, so we can't
                    // just run the mean through the LUT.
                    int storedValue  = pixelData.GetPixel(pixelIndex);
                    double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue;
                    sum += realValue;
                }
            });

            if (pixelCount == 0)
            {
                return(0);
            }

            return(sum / pixelCount);
        }
        private static double CalculateStandardDeviation
        (
            double mean,
            RectangleF roiBoundingBox,
            GrayscalePixelData pixelData,
            IModalityLut modalityLut,
            IsPointInRoiDelegate isPointInRoi
        )
        {
            double sum        = 0;
            int    pixelCount = 0;

            var boundingBox = RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox));

            pixelData.ForEachPixel(
                boundingBox.Left,
                boundingBox.Top,
                boundingBox.Right,
                boundingBox.Bottom,
                delegate(int i, int x, int y, int pixelIndex)
            {
                if (isPointInRoi(x, y))
                {
                    ++pixelCount;
                    int storedValue  = pixelData.GetPixel(pixelIndex);
                    double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue;

                    double deviation = realValue - mean;
                    sum += deviation * deviation;
                }
            });

            if (pixelCount == 0)
            {
                return(0);
            }

            return(Math.Sqrt(sum / pixelCount));
        }
示例#19
0
        public void ComposeSigned12()
        {
            const int    bitsStored       = 12;
            const bool   isSigned         = true;
            const double windowWidth      = 16384;
            const double windowLevel      = 4096;
            const double rescaleSlope     = 1.0;
            const double rescaleIntercept = 0;

            IModalityLut modalityLut = _lutFactory.GetModalityLutLinear(
                bitsStored,
                isSigned,
                rescaleSlope,
                rescaleIntercept);

            Assert.AreEqual(-2048, modalityLut.MinInputValue);
            Assert.AreEqual(2047, modalityLut.MaxInputValue);
            Assert.AreEqual(-2048, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(2047, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-2048, modalityLut[-2048], _tolerance);
            Assert.AreEqual(2047, modalityLut[2047], _tolerance);

            BasicVoiLutLinear voiLut = new BasicVoiLutLinear();

            voiLut.WindowWidth  = windowWidth;
            voiLut.WindowCenter = windowLevel;

            LutComposer lutComposer = new LutComposer(bitsStored, isSigned);

            lutComposer.ModalityLut = modalityLut;
            lutComposer.VoiLut      = voiLut;

            Assert.AreEqual(-2048, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(2047, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(-2048, voiLut.MinOutputValue);
            Assert.AreEqual(2047, voiLut.MaxOutputValue);

            Assert.AreEqual(-1535.84380, voiLut[-2047], _tolerance);
            Assert.AreEqual(-1024.18751, voiLut[0], _tolerance);
            Assert.AreEqual(-512.53122, voiLut[2047], _tolerance);

            //For this, we want the output range to be the same as the VOI.
            var output = lutComposer.GetOutputLut((int)Math.Round(voiLut.MinOutputValue), (int)Math.Round(voiLut.MaxOutputValue));

            Assert.AreEqual(-1536, output[-2047]);
            Assert.AreEqual(-1024, output[0]);
            Assert.AreEqual(-513, output[2047]);

            Assert.AreEqual(voiLut.MinOutputValue, output.MinInputValue);
            Assert.AreEqual(voiLut.MaxOutputValue, output.MaxInputValue);
            Assert.AreEqual(voiLut.MinOutputValue, output.MinOutputValue);
            Assert.AreEqual(voiLut.MaxOutputValue, output.MaxOutputValue);

            //This test is a little different from the others, it tests the output using a grayscale color map.
            var colorMap = _lutFactory.GetGrayscaleColorMap();

            colorMap.MaxInputValue = output.MaxOutputValue;
            colorMap.MinInputValue = output.MinOutputValue;

            Assert.AreEqual(32, 0x000000ff & colorMap[output.Data[0]]);
            Assert.AreEqual(64, 0x000000ff & colorMap[output.Data[2048]]);
            Assert.AreEqual(96, 0x000000ff & colorMap[output.Data[4095]]);
        }
            private static void CopyFrameData(byte[] frameData, int frameBytesPerPixel, bool frameIsSigned, IModalityLut frameModalityLut, ushort[] volumeData, int volumeStart, double normalizedSlope, double normalizedIntercept, out int minFramePixel, out int maxFramePixel)
            {
                var pixelCount = frameData.Length / frameBytesPerPixel;

                unsafe
                {
                    var min = int.MaxValue;
                    var max = int.MinValue;

                    fixed(byte *pFrameData = frameData)
                    fixed(ushort *pVolumeData = volumeData)
                    {
                        if (frameBytesPerPixel == 2)
                        {
                            var pFrameData16 = (short *)pFrameData;
                            for (var i = 0; i < pixelCount; ++i)
                            {
                                /// TODO (CR Nov 2011): Although perhaps less pretty, it's a bit more efficient
                                /// to break this out into 2 loops.
                                var frameValue  = frameModalityLut[frameIsSigned ? (int)pFrameData16[i] : (ushort)pFrameData16[i]];
                                var volumeValue = (frameValue - normalizedIntercept) / normalizedSlope;
                                var volumePixel = (ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                /// TODO (CR Nov 2011): Writes are volatile, so slightly more efficient to only do the assignment when necessary
                                min = Math.Min(min, volumePixel);
                                max = Math.Max(max, volumePixel);
                                pVolumeData[volumeStart + i] = volumePixel;
                            }
                        }
                        else if (frameBytesPerPixel == 1)
                        {
                            for (var i = 0; i < pixelCount; ++i)
                            {
                                /// TODO (CR Nov 2011): Although perhaps less pretty, it's a bit more efficient
                                /// to break this out into 2 loops.
                                var frameValue  = frameModalityLut[frameIsSigned ? (int)(sbyte)pFrameData[i] : pFrameData[i]];
                                var volumeValue = (frameValue - normalizedIntercept) / normalizedSlope;
                                var volumePixel = (ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                /// TODO (CR Nov 2011): Writes are volatile, so slightly more efficient to only do the assignment when necessary
                                min = Math.Min(min, volumePixel);
                                max = Math.Max(max, volumePixel);
                                pVolumeData[volumeStart + i] = volumePixel;
                            }
                        }
                    }

                    minFramePixel = min;
                    maxFramePixel = max;
                }
            }
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <remarks>
		/// The input <see cref="IVoiLut"/> object can be null.
		/// </remarks>
		/// <param name="pixelData">The pixel data the algorithm will be run on.</param>
		/// <param name="modalityLut">The modality lut to use for calculating <see cref="AlgorithmCalculatedVoiLutLinear.WindowWidth"/> 
		/// and <see cref="AlgorithmCalculatedVoiLutLinear.WindowCenter"/>, if applicable.</param>
		public MinMaxPixelCalculatedLinearLut(GrayscalePixelData pixelData, IModalityLut modalityLut)
			: base(pixelData, modalityLut)
		{
		}
		private static double CalculateMean
			(
			RectangleF roiBoundingBox,
			GrayscalePixelData pixelData,
			IModalityLut modalityLut,
			IsPointInRoiDelegate isPointInRoi
			)
		{
			double sum = 0;
			int pixelCount = 0;

            var boundingBox = RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox));
			pixelData.ForEachPixel(
                boundingBox.Left,
                boundingBox.Top,
                boundingBox.Right,
                boundingBox.Bottom,
				delegate(int i, int x, int y, int pixelIndex)
					{
						if (isPointInRoi(x, y))
						{
							++pixelCount;
							// Make sure we run the raw pixel through the modality LUT
							// when doing the calculation. Note that the modality LUT
							// can be something other than a rescale intercept, so we can't
							// just run the mean through the LUT.
							int storedValue = pixelData.GetPixel(pixelIndex);
							double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue;
							sum += realValue;
						}
					});

			if (pixelCount == 0)
				return 0;

			return sum/pixelCount;
		}
示例#23
0
			private static unsafe void CopyFrameData(byte[] frameData, int frameBytesPerPixel, bool frameIsSigned, IModalityLut frameModalityLut, ushort[] volumeData, int volumeStart, double normalizedSlope, double normalizedIntercept, out int minFramePixel, out int maxFramePixel)
			{
				var pixelCount = frameData.Length/frameBytesPerPixel;
				var min = int.MaxValue;
				var max = int.MinValue;

				fixed (byte* pFrameData = frameData)
				fixed (ushort* pVolumeData = volumeData)
				{
					var pVolumeFrame = pVolumeData + volumeStart;
					if (frameBytesPerPixel == 2)
					{
						if (frameIsSigned)
						{
							var pFrameDataS16 = (short*) pFrameData;
							for (var i = 0; i < pixelCount; ++i)
							{
								var frameValue = frameModalityLut[*pFrameDataS16++];
								var volumeValue = (frameValue - normalizedIntercept)/normalizedSlope;
								var volumePixel = (ushort) Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
								if (volumePixel < min) min = volumePixel;
								if (volumePixel > max) max = volumePixel;
								*pVolumeFrame++ = volumePixel;
							}
						}
						else
						{
							var pFrameDataU16 = (ushort*) pFrameData;
							for (var i = 0; i < pixelCount; ++i)
							{
								var frameValue = frameModalityLut[*pFrameDataU16++];
								var volumeValue = (frameValue - normalizedIntercept)/normalizedSlope;
								var volumePixel = (ushort) Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
								if (volumePixel < min) min = volumePixel;
								if (volumePixel > max) max = volumePixel;
								*pVolumeFrame++ = volumePixel;
							}
						}
					}
					else if (frameBytesPerPixel == 1)
					{
						if (frameIsSigned)
						{
							var pFrameDataS8 = (sbyte*) pFrameData;
							for (var i = 0; i < pixelCount; ++i)
							{
								var frameValue = frameModalityLut[*pFrameDataS8++];
								var volumeValue = (frameValue - normalizedIntercept)/normalizedSlope;
								var volumePixel = (ushort) Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
								if (volumePixel < min) min = volumePixel;
								if (volumePixel > max) max = volumePixel;
								*pVolumeFrame++ = volumePixel;
							}
						}
						else
						{
							var pFrameDataU8 = pFrameData;
							for (var i = 0; i < pixelCount; ++i)
							{
								var frameValue = frameModalityLut[*pFrameDataU8++];
								var volumeValue = (frameValue - normalizedIntercept)/normalizedSlope;
								var volumePixel = (ushort) Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
								if (volumePixel < min) min = volumePixel;
								if (volumePixel > max) max = volumePixel;
								*pVolumeFrame++ = volumePixel;
							}
						}
					}
					else
					{
						throw new ArgumentOutOfRangeException("frameBytesPerPixel");
					}
				}

				minFramePixel = min;
				maxFramePixel = max;
			}
示例#24
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <remarks>
 /// The input <see cref="IVoiLut"/> object can be null.
 /// </remarks>
 /// <param name="pixelData">The pixel data the algorithm will be run on.</param>
 /// <param name="modalityLut">The modality lut to use for calculating <see cref="AlgorithmCalculatedVoiLutLinear.WindowWidth"/>
 /// and <see cref="AlgorithmCalculatedVoiLutLinear.WindowCenter"/>, if applicable.</param>
 public MinMaxPixelCalculatedLinearLut(GrayscalePixelData pixelData, IModalityLut modalityLut)
     : base(pixelData, modalityLut)
 {
 }
		private static double CalculateStandardDeviation
			(
			double mean,
			RectangleF roiBoundingBox,
			GrayscalePixelData pixelData,
			IModalityLut modalityLut,
			IsPointInRoiDelegate isPointInRoi
			)
		{
			double sum = 0;
			int pixelCount = 0;

            var boundingBox = RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox));
            pixelData.ForEachPixel(
                boundingBox.Left,
                boundingBox.Top,
                boundingBox.Right,
                boundingBox.Bottom,
                delegate(int i, int x, int y, int pixelIndex)
                {
					if (isPointInRoi(x, y)) {
						++pixelCount;
						int storedValue = pixelData.GetPixel(pixelIndex);
						double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue;

						double deviation = realValue - mean;
						sum += deviation*deviation;
					}
				});

			if (pixelCount == 0)
				return 0;

			return Math.Sqrt(sum/pixelCount);
		}
        internal static double CalculateMeanForStack(List <ImageCalculationInfo> imageCalculationInfoStack)
        {
            double sum        = 0;
            int    pixelCount = 0;

            for (int imageCount = 0; imageCount < imageCalculationInfoStack.Count; imageCount++)
            {
                PixelData            pixelData            = imageCalculationInfoStack[imageCount].PixelData;
                SegFrameImageGraphic segFrameImageGraphic = imageCalculationInfoStack[imageCount].SegFrameImageGraphic;
                RectangleF           roiBoundingBox       = imageCalculationInfoStack[imageCount].RoiBoundingBox;
                IModalityLut         modalityLut          = imageCalculationInfoStack[imageCount].ModalityLut;

                Rectangle boundingBox =
                    RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox));

                int left = boundingBox.Left;
                if (left < 0)
                {
                    left = 0;
                }
                if (left >= segFrameImageGraphic.Columns)
                {
                    left = segFrameImageGraphic.Columns - 1;
                }
                int right = boundingBox.Right;
                if (right < 0)
                {
                    right = 0;
                }
                if (right >= segFrameImageGraphic.Columns)
                {
                    right = segFrameImageGraphic.Columns - 1;
                }
                int top = boundingBox.Top;
                if (top < 0)
                {
                    top = 0;
                }
                if (top >= segFrameImageGraphic.Rows)
                {
                    top = segFrameImageGraphic.Rows - 1;
                }
                int bottom = boundingBox.Bottom;
                if (bottom < 0)
                {
                    bottom = 0;
                }
                if (bottom >= segFrameImageGraphic.Rows)
                {
                    bottom = segFrameImageGraphic.Rows - 1;
                }

                pixelData.ForEachPixel(
                    left,
                    top,
                    right,
                    bottom,
                    delegate(int i, int x, int y, int pixelIndex)
                {
                    //if (x >= 0 && x < segFrameImageGraphic.Columns && y >= 0 && y < segFrameImageGraphic.Rows)
                    if (segFrameImageGraphic[x, y])
                    {
                        ++pixelCount;
                        // Make sure we run the raw pixel through the modality LUT
                        // when doing the calculation. Note that the modality LUT
                        // can be something other than a rescale intercept, so we can't
                        // just run the mean through the LUT.
                        int storedValue  = pixelData.GetPixel(pixelIndex);
                        double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue;
                        sum += realValue;
                    }
                });
            }

            if (pixelCount == 0)
            {
                return(0);
            }

            return(sum / pixelCount);
        }
示例#27
0
			private static void CopyFrameData(byte[] frameData, int frameBytesPerPixel, bool frameIsSigned, IModalityLut frameModalityLut, ushort[] volumeData, int volumeStart, double normalizedSlope, double normalizedIntercept, out int minFramePixel, out int maxFramePixel)
			{
				var pixelCount = frameData.Length/frameBytesPerPixel;
				unsafe
				{
					var min = int.MaxValue;
					var max = int.MinValue;

					fixed (byte* pFrameData = frameData)
					fixed (ushort* pVolumeData = volumeData)
					{
						if (frameBytesPerPixel == 2)
						{
							var pFrameData16 = (short*) pFrameData;
							for (var i = 0; i < pixelCount; ++i)
							{
							    /// TODO (CR Nov 2011): Although perhaps less pretty, it's a bit more efficient
							    /// to break this out into 2 loops.
								var frameValue = frameModalityLut[frameIsSigned ? (int) pFrameData16[i] : (ushort) pFrameData16[i]];
								var volumeValue = (frameValue - normalizedIntercept)/normalizedSlope;
								var volumePixel = (ushort) Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                /// TODO (CR Nov 2011): Writes are volatile, so slightly more efficient to only do the assignment when necessary
                                min = Math.Min(min, volumePixel);
								max = Math.Max(max, volumePixel);
								pVolumeData[volumeStart + i] = volumePixel;
							}
						}
						else if (frameBytesPerPixel == 1)
						{
							for (var i = 0; i < pixelCount; ++i)
							{
                                /// TODO (CR Nov 2011): Although perhaps less pretty, it's a bit more efficient
                                /// to break this out into 2 loops.
                                var frameValue = frameModalityLut[frameIsSigned ? (int)(sbyte)pFrameData[i] : pFrameData[i]];
								var volumeValue = (frameValue - normalizedIntercept)/normalizedSlope;
								var volumePixel = (ushort) Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
							    /// TODO (CR Nov 2011): Writes are volatile, so slightly more efficient to only do the assignment when necessary
                                min = Math.Min(min, volumePixel);
								max = Math.Max(max, volumePixel);
								pVolumeData[volumeStart + i] = volumePixel;
							}
						}
					}

					minFramePixel = min;
					maxFramePixel = max;
				}
			}
        internal static double CalculateStandardDeviationForStack(double mean,
                                                                  List <ImageCalculationInfo> imageCalculationInfoStack)
        {
            double sum        = 0;
            int    pixelCount = 0;

            for (int imageCount = 0; imageCount < imageCalculationInfoStack.Count; imageCount++)
            {
                PixelData            pixelData            = imageCalculationInfoStack[imageCount].PixelData;
                SegFrameImageGraphic segFrameImageGraphic = imageCalculationInfoStack[imageCount].SegFrameImageGraphic;
                RectangleF           roiBoundingBox       = imageCalculationInfoStack[imageCount].RoiBoundingBox;
                IModalityLut         modalityLut          = imageCalculationInfoStack[imageCount].ModalityLut;

                Rectangle boundingBox =
                    RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox));

                int left = boundingBox.Left;
                if (left < 0)
                {
                    left = 0;
                }
                if (left >= segFrameImageGraphic.Columns)
                {
                    left = segFrameImageGraphic.Columns - 1;
                }
                int right = boundingBox.Right;
                if (right < 0)
                {
                    right = 0;
                }
                if (right >= segFrameImageGraphic.Columns)
                {
                    right = segFrameImageGraphic.Columns - 1;
                }
                int top = boundingBox.Top;
                if (top < 0)
                {
                    top = 0;
                }
                if (top >= segFrameImageGraphic.Rows)
                {
                    top = segFrameImageGraphic.Rows - 1;
                }
                int bottom = boundingBox.Bottom;
                if (bottom < 0)
                {
                    bottom = 0;
                }
                if (bottom >= segFrameImageGraphic.Rows)
                {
                    bottom = segFrameImageGraphic.Rows - 1;
                }

                pixelData.ForEachPixel(
                    left,
                    top,
                    right,
                    bottom,
                    delegate(int i, int x, int y, int pixelIndex)
                {
                    if (segFrameImageGraphic[x, y])
                    {
                        ++pixelCount;
                        int storedValue  = pixelData.GetPixel(pixelIndex);
                        double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue;

                        double deviation = realValue - mean;
                        sum += deviation * deviation;
                    }
                });
            }

            if (pixelCount == 0)
            {
                return(0);
            }

            return(Math.Sqrt(sum / pixelCount));
        }
示例#29
0
            private static unsafe void CopyFrameData(byte[] frameData, int frameBytesPerPixel, bool frameIsSigned, IModalityLut frameModalityLut, ushort[] volumeData, int volumeStart, double normalizedSlope, double normalizedIntercept, out int minFramePixel, out int maxFramePixel)
            {
                var pixelCount = frameData.Length / frameBytesPerPixel;
                var min        = int.MaxValue;
                var max        = int.MinValue;

                fixed(byte *pFrameData = frameData)
                fixed(ushort *pVolumeData = volumeData)
                {
                    var pVolumeFrame = pVolumeData + volumeStart;

                    if (frameBytesPerPixel == 2)
                    {
                        if (frameIsSigned)
                        {
                            var pFrameDataS16 = (short *)pFrameData;
                            for (var i = 0; i < pixelCount; ++i)
                            {
                                var frameValue  = frameModalityLut[*pFrameDataS16++];
                                var volumeValue = (frameValue - normalizedIntercept) / normalizedSlope;
                                var volumePixel = (ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                if (volumePixel < min)
                                {
                                    min = volumePixel;
                                }
                                if (volumePixel > max)
                                {
                                    max = volumePixel;
                                }
                                *pVolumeFrame++ = volumePixel;
                            }
                        }
                        else
                        {
                            var pFrameDataU16 = (ushort *)pFrameData;
                            for (var i = 0; i < pixelCount; ++i)
                            {
                                var frameValue  = frameModalityLut[*pFrameDataU16++];
                                var volumeValue = (frameValue - normalizedIntercept) / normalizedSlope;
                                var volumePixel = (ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                if (volumePixel < min)
                                {
                                    min = volumePixel;
                                }
                                if (volumePixel > max)
                                {
                                    max = volumePixel;
                                }
                                *pVolumeFrame++ = volumePixel;
                            }
                        }
                    }
                    else if (frameBytesPerPixel == 1)
                    {
                        if (frameIsSigned)
                        {
                            var pFrameDataS8 = (sbyte *)pFrameData;
                            for (var i = 0; i < pixelCount; ++i)
                            {
                                var frameValue  = frameModalityLut[*pFrameDataS8++];
                                var volumeValue = (frameValue - normalizedIntercept) / normalizedSlope;
                                var volumePixel = (ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                if (volumePixel < min)
                                {
                                    min = volumePixel;
                                }
                                if (volumePixel > max)
                                {
                                    max = volumePixel;
                                }
                                *pVolumeFrame++ = volumePixel;
                            }
                        }
                        else
                        {
                            var pFrameDataU8 = pFrameData;
                            for (var i = 0; i < pixelCount; ++i)
                            {
                                var frameValue  = frameModalityLut[*pFrameDataU8++];
                                var volumeValue = (frameValue - normalizedIntercept) / normalizedSlope;
                                var volumePixel = (ushort)Math.Max(ushort.MinValue, Math.Min(ushort.MaxValue, Math.Round(volumeValue)));
                                if (volumePixel < min)
                                {
                                    min = volumePixel;
                                }
                                if (volumePixel > max)
                                {
                                    max = volumePixel;
                                }
                                *pVolumeFrame++ = volumePixel;
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("frameBytesPerPixel");
                    }
                }

                minFramePixel = min;
                maxFramePixel = max;
            }