public void TestPipelineSigned12()
        {
            var composer = new LutComposer(12, true);

            composer.ModalityLut = new ModalityLutLinear(12, true, 1, 0);
            var voiLUT = new BasicVoiLutLinear(4096, 0);

            composer.VoiLut = voiLUT;

            Assert.AreEqual(-2048, voiLUT[-2048], _tolerance);
            Assert.AreEqual(0, voiLUT[0], _tolerance);
            Assert.AreEqual(2047, voiLUT[2047], _tolerance);

            var output = composer.GetOutputLut(0, byte.MaxValue);

            Assert.AreEqual(0, output[-2048]);
            Assert.AreEqual(128, output[0]);
            Assert.AreEqual(255, output[2047]);

            //10-bit display
            output = composer.GetOutputLut(0, 1023);
            Assert.AreEqual(0, output[-2048]);
            Assert.AreEqual(512, output[0]);
            Assert.AreEqual(1023, output[2047]);

            //Theoretical 12-bit display with signed output
            output = composer.GetOutputLut(-2048, 2047);
            Assert.AreEqual(-2048, output[-2048]);
            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(2047, output[2047]);
        }
예제 #2
0
        public void TestEquivalentLuts()
        {
            var composer1 = new LutComposer
            {
                ModalityLut = new ModalityLutLinear(16, true, 1, 0),
                VoiLut      = new IdentityVoiLinearLut(16, true)
            };
            var composer2 = new LutComposer
            {
                ModalityLut = new ModalityLutLinear(16, false, 1, -32768),
                VoiLut      = new IdentityVoiLinearLut(16, false)
            };

            //Compare 2 composed LUTs whose output should be the same.
            var output1 = composer1.GetOutputLut(0, 255);
            var output2 = composer2.GetOutputLut(0, 255);

            Assert.AreEqual(0, output1[-32768]);
            Assert.AreEqual(128, output1[0]);
            Assert.AreEqual(255, output1[32767]);

            Assert.AreEqual(0, output2[0]);
            Assert.AreEqual(128, output2[32768]);
            Assert.AreEqual(255, output2[65535]);

            Assert.AreEqual(output1.Data.Length, output2.Data.Length);
            for (int i = 0; i < output1.Data.Length; ++i)
            {
                Assert.AreEqual(output1.Data[i], output2.Data[i]);
            }
        }
예제 #3
0
        public void NoLutsAdded()
        {
            LutComposer lutComposer = new LutComposer();
            var         output      = lutComposer.GetOutputLut(0, 255);

            Assert.IsNull(output);
        }
예제 #4
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]);
        }
        public void TestPipelineUnsigned16()
        {
            var composer = new LutComposer(16, false);

            composer.ModalityLut = new ModalityLutLinear(16, false, 1, 0);
            var voiLUT = new BasicVoiLutLinear(65536, 32768);

            composer.VoiLut = voiLUT;

            Assert.AreEqual(0, voiLUT[0], _tolerance);
            Assert.AreEqual(32768, voiLUT[32768], _tolerance);
            Assert.AreEqual(65535, voiLUT[65535], _tolerance);

            Assert.AreEqual(0, voiLUT[-1], _tolerance);
            Assert.AreEqual(65535, voiLUT[65536], _tolerance);

            var output = composer.GetOutputLut(0, byte.MaxValue);

            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(128, output[32768]);
            Assert.AreEqual(255, output[65535]);

            //Make sure the output of the grayscale color map works with all the different "display" output ranges.
            var colorMap = LutFactory.Create().GetGrayscaleColorMap();

            colorMap.MinInputValue = output.MinOutputValue;
            colorMap.MaxInputValue = output.MaxOutputValue;
            Assert.AreEqual(0, 0x000000FF & colorMap[output[0]]);
            Assert.AreEqual(128, 0x000000FF & colorMap[output[32768]]);
            Assert.AreEqual(255, 0x000000FF & colorMap[output[65535]]);

            //10-bit display
            output = composer.GetOutputLut(0, 1023);
            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(512, output[32768]);
            Assert.AreEqual(1023, output[65535]);

            colorMap.MinInputValue = output.MinOutputValue;
            colorMap.MaxInputValue = output.MaxOutputValue;
            Assert.AreEqual(0, 0x000000FF & colorMap[output[0]]);
            Assert.AreEqual(128, 0x000000FF & colorMap[output[32768]]);
            Assert.AreEqual(255, 0x000000FF & colorMap[output[65535]]);

            //Theoretical 12-bit display with signed output
            output = composer.GetOutputLut(-2048, 2047);
            Assert.AreEqual(-2048, output[0]);
            Assert.AreEqual(0, output[32768]);
            Assert.AreEqual(2047, output[65535]);

            colorMap.MinInputValue = output.MinOutputValue;
            colorMap.MaxInputValue = output.MaxOutputValue;
            Assert.AreEqual(0, 0x000000FF & colorMap[output[0]]);
            Assert.AreEqual(128, 0x000000FF & colorMap[output[32768]]);
            Assert.AreEqual(255, 0x000000FF & colorMap[output[65535]]);
        }
예제 #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 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);
		}
예제 #9
0
        public void ComposeSignedSubnormalModalityLut()
        {
            const int    bitsStored       = 15;
            const bool   isSigned         = true;
            const double windowWidth      = 32768;
            const double windowLevel      = 0;
            const double rescaleSlope     = 2.7182818284590452353602874713527e-6;
            const double rescaleIntercept = 0;

            var modalityLut      = _lutFactory.GetModalityLutLinear(bitsStored, isSigned, rescaleSlope, rescaleIntercept);
            var normalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
            var voiLut           = new BasicVoiLutLinear {
                WindowWidth = windowWidth, WindowCenter = windowLevel
            };
            var lutComposer = new LutComposer(bitsStored, isSigned)
            {
                ModalityLut = modalityLut, VoiLut = voiLut, NormalizationLut = normalizationLut
            };

            Assert.AreEqual(-16384, modalityLut.MinInputValue);
            Assert.AreEqual(16383, modalityLut.MaxInputValue);
            Assert.AreEqual(-0.044536329477473, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(0.044533611195644536, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-0.044536329477473, modalityLut[-16384], _tolerance);
            Assert.AreEqual(0.044533611195644536, modalityLut[16383], _tolerance);

            Assert.AreEqual(-0.044536329477473, normalizationLut.MinInputValue, _tolerance);
            Assert.AreEqual(0.044533611195644536, normalizationLut.MaxInputValue, _tolerance);
            Assert.AreEqual(-16384, normalizationLut.MinOutputValue, _tolerance);
            Assert.AreEqual(16383, normalizationLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-16384, normalizationLut[-0.044536329477473], _tolerance);
            Assert.AreEqual(16383, normalizationLut[0.044533611195644536], _tolerance);

            Assert.AreEqual(-16384, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(16383, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(-16384, voiLut.MinOutputValue, _tolerance);
            Assert.AreEqual(16383, voiLut.MaxOutputValue, _tolerance);

            Assert.AreEqual(-13543, voiLut[-13543], _tolerance);
            Assert.AreEqual(12564, voiLut[12564], _tolerance);
            Assert.AreEqual(-4074, voiLut[-4074], _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(-13543, output.Data[-13543 + 16384]);
            Assert.AreEqual(12564, output.Data[12564 + 16384]);
            Assert.AreEqual(-4074, output.Data[-4074 + 16384]);
        }
예제 #10
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]);
        }
예제 #11
0
        public void ComposeUnsignedSubnormalModalityLut()
        {
            const int    bitsStored       = 13;
            const bool   isSigned         = false;
            const double windowWidth      = 8192;
            const double windowLevel      = 4096;
            const double rescaleSlope     = 3.1415926535897932384626433832795e-6;
            const double rescaleIntercept = -10;

            var modalityLut      = _lutFactory.GetModalityLutLinear(bitsStored, isSigned, rescaleSlope, rescaleIntercept);
            var normalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
            var voiLut           = new BasicVoiLutLinear {
                WindowWidth = windowWidth, WindowCenter = windowLevel
            };
            var lutComposer = new LutComposer(bitsStored, isSigned)
            {
                ModalityLut = modalityLut, VoiLut = voiLut, NormalizationLut = normalizationLut
            };

            Assert.AreEqual(0, modalityLut.MinInputValue);
            Assert.AreEqual(8191, modalityLut.MaxInputValue);
            Assert.AreEqual(-10, modalityLut.MinOutputValue, _tolerance);
            Assert.AreEqual(-9.9742672145744464, modalityLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(-10, modalityLut[0], _tolerance);
            Assert.AreEqual(-9.9742672145744464, modalityLut[8191], _tolerance);

            Assert.AreEqual(-10, normalizationLut.MinInputValue, _tolerance);
            Assert.AreEqual(-9.9742672145744464, normalizationLut.MaxInputValue, _tolerance);
            Assert.AreEqual(0, normalizationLut.MinOutputValue, _tolerance);
            Assert.AreEqual(8191, normalizationLut.MaxOutputValue, _tolerance);
            Assert.AreEqual(0, normalizationLut[-10], _tolerance);
            Assert.AreEqual(8191, normalizationLut[-9.9742672145744464], _tolerance);

            Assert.AreEqual(0, voiLut.MinInputValue, _tolerance);
            Assert.AreEqual(8191, voiLut.MaxInputValue, _tolerance);
            Assert.AreEqual(0, voiLut.MinOutputValue, _tolerance);
            Assert.AreEqual(8191, voiLut.MaxOutputValue, _tolerance);

            Assert.AreEqual(1543, voiLut[1543], _tolerance);
            Assert.AreEqual(5164, voiLut[5164], _tolerance);
            Assert.AreEqual(7074, voiLut[7074], _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(1543, output.Data[1543]);
            Assert.AreEqual(5164, output.Data[5164]);
            Assert.AreEqual(7074, output.Data[7074]);
        }
예제 #12
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]]);
        }
예제 #13
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]);
        }
예제 #14
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]);
		}
예제 #15
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]);
        }
예제 #16
0
        /// <summary>
        /// Implementation of the <see cref="IDisposable"/> pattern
        /// </summary>
        /// <param name="disposing">True if this object is being disposed, false if it is being finalized</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_lutFactory != null)
                {
                    _lutFactory.Dispose();
                    _lutFactory = null;
                }

                if (_lutComposer != null)
                {
                    _lutComposer.Dispose();
                    _lutComposer = null;
                }
            }
        }
예제 #17
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]);
        }
예제 #18
0
        public void ComposeSingleLUT()
        {
            double windowWidth = 350;
            double windowLevel = 40;

            BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();

            voiLUT.MinInputValue = 0;
            voiLUT.MaxInputValue = 4095;

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

            LutComposer lutComposer = new LutComposer(0, 4095);

            lutComposer.VoiLut = voiLUT;
            int[] data = lutComposer.Data;
        }
예제 #19
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]);
        }
예제 #20
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]);
        }
		public void TestNormalRescale2()
		{
			const double rescaleSlope = 0.9;
			const double rescaleIntercept = 406;

			const int bitsStored = 12;
			const bool signed = false;

			var composer = new LutComposer(bitsStored, signed);
			composer.ModalityLut = new ModalityLutLinear(bitsStored, signed, rescaleSlope, rescaleIntercept);
			composer.NormalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);

			Assert.AreEqual(0, composer[0]);
			Assert.AreEqual(101, composer[101]);
			Assert.AreEqual(2047, composer[2047]);
			Assert.AreEqual(2048, composer[2048]);
			Assert.AreEqual(3993, composer[3993]);
			Assert.AreEqual(4095, composer[4095]);
		}
예제 #22
0
        public void TestNormalRescale2()
        {
            const double rescaleSlope     = 0.9;
            const double rescaleIntercept = 406;

            const int  bitsStored = 12;
            const bool signed     = false;

            var composer = new LutComposer(bitsStored, signed);

            composer.ModalityLut      = new ModalityLutLinear(bitsStored, signed, rescaleSlope, rescaleIntercept);
            composer.NormalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);

            Assert.AreEqual(0, composer[0]);
            Assert.AreEqual(101, composer[101]);
            Assert.AreEqual(2047, composer[2047]);
            Assert.AreEqual(2048, composer[2048]);
            Assert.AreEqual(3993, composer[3993]);
            Assert.AreEqual(4095, composer[4095]);
        }
		public void TestTrivialRescale()
		{
			const double rescaleSlope = 1;
			const double rescaleIntercept = 0;

			const int bitsStored = 12;
			const bool signed = false;

			var composer = new LutComposer(bitsStored, signed);
			composer.ModalityLut = new ModalityLutLinear(bitsStored, signed, rescaleSlope, rescaleIntercept);
			composer.NormalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
			//The composed LUT outputs "Presentation Values", so just trick it into being "identity".
			var output = composer.GetOutputLut(0, 4095);
			Assert.AreEqual(0, output[0]);
			Assert.AreEqual(101, output[101]);
			Assert.AreEqual(2047, output[2047]);
			Assert.AreEqual(2048, output[2048]);
			Assert.AreEqual(3993, output[3993]);
			Assert.AreEqual(4095, output[4095]);
		}
		public void TestNormalRescale1()
		{
			const double rescaleSlope = 1.9;
			const double rescaleIntercept = 0;

			const int bitsStored = 12;
			const bool signed = false;

			var composer = new LutComposer(bitsStored, signed);
			composer.ModalityLut = new ModalityLutLinear(bitsStored, signed, rescaleSlope, rescaleIntercept);
			composer.NormalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
			var output = composer.GetOutputLut(0, 4095);

			Assert.AreEqual(0, output[0]);
			Assert.AreEqual(101, output[101]);
			Assert.AreEqual(2047, output[2047]);
			Assert.AreEqual(2048, output[2048]);
			Assert.AreEqual(3993, output[3993]);
			Assert.AreEqual(4095, output[4095]);
		}
예제 #25
0
        public void ComposeSingleLut()
        {
            const double windowWidth = 350;
            const double windowLevel = 40;

            BasicVoiLutLinear voiLut = new BasicVoiLutLinear();

            voiLut.MinInputValue = 0;
            voiLut.MaxInputValue = 4095;

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

            LutComposer lutComposer = new LutComposer(0, 4095);

            lutComposer.VoiLut = voiLut;

            var output = lutComposer.GetOutputLut(0, 255);

            Assert.IsNotNull(output);
        }
예제 #26
0
        public void TestNormalRescale1()
        {
            const double rescaleSlope     = 1.9;
            const double rescaleIntercept = 0;

            const int  bitsStored = 12;
            const bool signed     = false;

            var composer = new LutComposer(bitsStored, signed);

            composer.ModalityLut      = new ModalityLutLinear(bitsStored, signed, rescaleSlope, rescaleIntercept);
            composer.NormalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
            var output = composer.GetOutputLut(0, 4095);

            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(101, output[101]);
            Assert.AreEqual(2047, output[2047]);
            Assert.AreEqual(2048, output[2048]);
            Assert.AreEqual(3993, output[3993]);
            Assert.AreEqual(4095, output[4095]);
        }
예제 #27
0
        /// <summary>
        /// Implementation of the <see cref="IDisposable"/> pattern
        /// </summary>
        /// <param name="disposing">True if this object is being disposed, false if it is being finalized</param>
        protected virtual void Dispose(bool disposing)
        {
            _disposed = true;

            if (disposing)
            {
                _vtkData = null;

                if (_lutFactory != null)
                {
                    _lutFactory.Dispose();
                    _lutFactory = null;
                }

                if (_lutComposer != null)
                {
                    _lutComposer.LutChanged -= OnLutComposerChanged;
                    _lutComposer.Dispose();
                    _lutComposer = null;
                }
            }
        }
예제 #28
0
        public void TestTrivialRescale()
        {
            const double rescaleSlope     = 1;
            const double rescaleIntercept = 0;

            const int  bitsStored = 12;
            const bool signed     = false;

            var composer = new LutComposer(bitsStored, signed);

            composer.ModalityLut      = new ModalityLutLinear(bitsStored, signed, rescaleSlope, rescaleIntercept);
            composer.NormalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
            //The composed LUT outputs "Presentation Values", so just trick it into being "identity".
            var output = composer.GetOutputLut(0, 4095);

            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(101, output[101]);
            Assert.AreEqual(2047, output[2047]);
            Assert.AreEqual(2048, output[2048]);
            Assert.AreEqual(3993, output[3993]);
            Assert.AreEqual(4095, output[4095]);
        }
예제 #29
0
 /// <summary>
 /// The output lut composed of both the Modality and Voi Luts.
 /// </summary>
 private IComposedLut GetOutputLut()
 {
     InitializeNecessaryLuts(Luts.Voi);
     return(LutComposer.GetOutputLut(0, byte.MaxValue));
 }
        public void TestPipelineSigned12()
        {
            var composer = new LutComposer(12, true);
            composer.ModalityLut = new ModalityLutLinear(12, true, 1, 0);
            var voiLUT = new BasicVoiLutLinear(4096, 0);
            composer.VoiLut = voiLUT;

            Assert.AreEqual(-2048, voiLUT[-2048], _tolerance);
            Assert.AreEqual(0, voiLUT[0], _tolerance);
            Assert.AreEqual(2047, voiLUT[2047], _tolerance);

            var output = composer.GetOutputLut(0, byte.MaxValue);
            Assert.AreEqual(0, output[-2048]);
            Assert.AreEqual(128, output[0]);
            Assert.AreEqual(255, output[2047]);

            //10-bit display
            output = composer.GetOutputLut(0, 1023);
            Assert.AreEqual(0, output[-2048]);
            Assert.AreEqual(512, output[0]);
            Assert.AreEqual(1023, output[2047]);

            //Theoretical 12-bit display with signed output
            output = composer.GetOutputLut(-2048, 2047);
            Assert.AreEqual(-2048, output[-2048]);
            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(2047, output[2047]);
        }
        public void TestPipelineUnsigned16()
        {
            var composer = new LutComposer(16, false);
            composer.ModalityLut = new ModalityLutLinear(16, false, 1, 0);
            var voiLUT = new BasicVoiLutLinear(65536, 32768);
            composer.VoiLut = voiLUT;

            Assert.AreEqual(0, voiLUT[0], _tolerance);
            Assert.AreEqual(32768, voiLUT[32768], _tolerance);
            Assert.AreEqual(65535, voiLUT[65535], _tolerance);

            Assert.AreEqual(0, voiLUT[-1], _tolerance);
            Assert.AreEqual(65535, voiLUT[65536], _tolerance);

            var output = composer.GetOutputLut(0, byte.MaxValue);
            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(128, output[32768]);
            Assert.AreEqual(255, output[65535]);

            //Make sure the output of the grayscale color map works with all the different "display" output ranges.
            var colorMap = LutFactory.Create().GetGrayscaleColorMap();
            colorMap.MinInputValue = output.MinOutputValue;
            colorMap.MaxInputValue = output.MaxOutputValue;
            Assert.AreEqual(0, 0x000000FF & colorMap[output[0]]);
            Assert.AreEqual(128, 0x000000FF & colorMap[output[32768]]);
            Assert.AreEqual(255, 0x000000FF & colorMap[output[65535]]);

            //10-bit display
            output = composer.GetOutputLut(0, 1023);
            Assert.AreEqual(0, output[0]);
            Assert.AreEqual(512, output[32768]);
            Assert.AreEqual(1023, output[65535]);

            colorMap.MinInputValue = output.MinOutputValue;
            colorMap.MaxInputValue = output.MaxOutputValue;
            Assert.AreEqual(0, 0x000000FF & colorMap[output[0]]);
            Assert.AreEqual(128, 0x000000FF & colorMap[output[32768]]);
            Assert.AreEqual(255, 0x000000FF & colorMap[output[65535]]);

            //Theoretical 12-bit display with signed output
            output = composer.GetOutputLut(-2048, 2047);
            Assert.AreEqual(-2048, output[0]);
            Assert.AreEqual(0, output[32768]);
            Assert.AreEqual(2047, output[65535]);

            colorMap.MinInputValue = output.MinOutputValue;
            colorMap.MaxInputValue = output.MaxOutputValue;
            Assert.AreEqual(0, 0x000000FF & colorMap[output[0]]);
            Assert.AreEqual(128, 0x000000FF & colorMap[output[32768]]);
            Assert.AreEqual(255, 0x000000FF & colorMap[output[65535]]);
        }
예제 #32
0
 public void NoLUTsAdded()
 {
     LutComposer lutComposer = new LutComposer();
     var         output      = lutComposer.GetOutputLut(0, 255);
 }
예제 #33
0
 /// <summary>
 /// Gets the output lut composed of both the Modality and Voi Luts,
 /// properly rescaled/normalized for the given output display range.
 /// </summary>
 public IComposedLut GetOutputLut(int minDisplayValue, int maxDisplayValue)
 {
     InitializeNecessaryLuts(Luts.Voi);
     return(LutComposer.GetOutputLut(minDisplayValue, maxDisplayValue));
 }
예제 #34
0
		/// <summary>
		/// Implementation of the <see cref="IDisposable"/> pattern
		/// </summary>
		/// <param name="disposing">True if this object is being disposed, false if it is being finalized</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (_lutFactory != null)
				{
					_lutFactory.Dispose();
					_lutFactory = null;
				}

				if (_lutComposer != null)
				{
					_lutComposer.Dispose();
					_lutComposer = null;
				}
			}
		}
예제 #35
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]);
		}
예제 #36
0
		public void NoLUTsAdded()
		{
			LutComposer lutComposer = new LutComposer();
            var output = lutComposer.GetOutputLut(0, 255);
        }
예제 #37
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]);
		}
예제 #38
0
        public void TestEquivalentLuts()
        {
            var composer1 = new LutComposer
                                        {
                                            ModalityLut = new ModalityLutLinear(16, true, 1, 0), 
                                            VoiLut = new IdentityVoiLinearLut(16, true)
                                        };
            var composer2 = new LutComposer
            {
                ModalityLut = new ModalityLutLinear(16, false, 1, -32768),
                VoiLut = new IdentityVoiLinearLut(16, false)
            };

            //Compare 2 composed LUTs whose output should be the same.
            var output1 = composer1.GetOutputLut(0, 255);
            var output2 = composer2.GetOutputLut(0, 255);

            Assert.AreEqual(0, output1[-32768]);
            Assert.AreEqual(128, output1[0]);
            Assert.AreEqual(255, output1[32767]);

            Assert.AreEqual(0, output2[0]);
            Assert.AreEqual(128, output2[32768]);
            Assert.AreEqual(255, output2[65535]);

            Assert.AreEqual(output1.Data.Length, output2.Data.Length);
            for(int i = 0; i < output1.Data.Length; ++i)
                Assert.AreEqual(output1.Data[i], output2.Data[i]);
        }
예제 #39
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(-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]]);
		}
예제 #40
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, _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]);
		}
예제 #41
0
		public void NoLutsAdded()
		{
			LutComposer lutComposer = new LutComposer();
			var output = lutComposer.GetOutputLut(0, 255);
			Assert.IsNull(output);
		}
예제 #42
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]);
		}
예제 #43
0
		public void ComposeSingleLut()
		{
			const double windowWidth = 350;
			const double windowLevel = 40;

			BasicVoiLutLinear voiLut = new BasicVoiLutLinear();
			voiLut.MinInputValue = 0;
			voiLut.MaxInputValue = 4095;

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

			LutComposer lutComposer = new LutComposer(0, 4095);
			lutComposer.VoiLut = voiLut;

			var output = lutComposer.GetOutputLut(0, 255);
			Assert.IsNotNull(output);
		}
예제 #44
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]]);
		}
예제 #45
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]);
		}
예제 #46
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]);
		}
예제 #47
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]);
		}
예제 #48
0
		public void ComposeSignedSubnormalModalityLut()
		{
			const int bitsStored = 15;
			const bool isSigned = true;
			const double windowWidth = 32768;
			const double windowLevel = 0;
			const double rescaleSlope = 2.7182818284590452353602874713527e-6;
			const double rescaleIntercept = 0;

			var modalityLut = _lutFactory.GetModalityLutLinear(bitsStored, isSigned, rescaleSlope, rescaleIntercept);
			var normalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
			var voiLut = new BasicVoiLutLinear {WindowWidth = windowWidth, WindowCenter = windowLevel};
			var lutComposer = new LutComposer(bitsStored, isSigned) {ModalityLut = modalityLut, VoiLut = voiLut, NormalizationLut = normalizationLut};

			Assert.AreEqual(-16384, modalityLut.MinInputValue);
			Assert.AreEqual(16383, modalityLut.MaxInputValue);
			Assert.AreEqual(-0.044536329477473, modalityLut.MinOutputValue, _tolerance);
			Assert.AreEqual(0.044533611195644536, modalityLut.MaxOutputValue, _tolerance);
			Assert.AreEqual(-0.044536329477473, modalityLut[-16384], _tolerance);
			Assert.AreEqual(0.044533611195644536, modalityLut[16383], _tolerance);

			Assert.AreEqual(-0.044536329477473, normalizationLut.MinInputValue, _tolerance);
			Assert.AreEqual(0.044533611195644536, normalizationLut.MaxInputValue, _tolerance);
			Assert.AreEqual(-16384, normalizationLut.MinOutputValue, _tolerance);
			Assert.AreEqual(16383, normalizationLut.MaxOutputValue, _tolerance);
			Assert.AreEqual(-16384, normalizationLut[-0.044536329477473], _tolerance);
			Assert.AreEqual(16383, normalizationLut[0.044533611195644536], _tolerance);

			Assert.AreEqual(-16384, voiLut.MinInputValue, _tolerance);
			Assert.AreEqual(16383, voiLut.MaxInputValue, _tolerance);
			Assert.AreEqual(-16384, voiLut.MinOutputValue);
			Assert.AreEqual(16383, voiLut.MaxOutputValue);

			Assert.AreEqual(-13543, voiLut[-13543]);
			Assert.AreEqual(12564, voiLut[12564]);
			Assert.AreEqual(-4074, voiLut[-4074]);

			Assert.AreEqual(-13543, lutComposer.Data[-13543 + 16384]);
			Assert.AreEqual(12564, lutComposer.Data[12564 + 16384]);
			Assert.AreEqual(-4074, lutComposer.Data[-4074 + 16384]);
		}
예제 #49
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]]);
        }
예제 #50
0
		public void ComposeUnsignedSubnormalModalityLut()
		{
			const int bitsStored = 13;
			const bool isSigned = false;
			const double windowWidth = 8192;
			const double windowLevel = 4096;
			const double rescaleSlope = 3.1415926535897932384626433832795e-6;
			const double rescaleIntercept = -10;

			var modalityLut = _lutFactory.GetModalityLutLinear(bitsStored, isSigned, rescaleSlope, rescaleIntercept);
			var normalizationLut = new NormalizationLutLinear(rescaleSlope, rescaleIntercept);
			var voiLut = new BasicVoiLutLinear {WindowWidth = windowWidth, WindowCenter = windowLevel};
			var lutComposer = new LutComposer(bitsStored, isSigned) {ModalityLut = modalityLut, VoiLut = voiLut, NormalizationLut = normalizationLut};

			Assert.AreEqual(0, modalityLut.MinInputValue);
			Assert.AreEqual(8191, modalityLut.MaxInputValue);
			Assert.AreEqual(-10, modalityLut.MinOutputValue, _tolerance);
			Assert.AreEqual(-9.9742672145744464, modalityLut.MaxOutputValue, _tolerance);
			Assert.AreEqual(-10, modalityLut[0], _tolerance);
			Assert.AreEqual(-9.9742672145744464, modalityLut[8191], _tolerance);

			Assert.AreEqual(-10, normalizationLut.MinInputValue, _tolerance);
			Assert.AreEqual(-9.9742672145744464, normalizationLut.MaxInputValue, _tolerance);
			Assert.AreEqual(0, normalizationLut.MinOutputValue, _tolerance);
			Assert.AreEqual(8191, normalizationLut.MaxOutputValue, _tolerance);
			Assert.AreEqual(0, normalizationLut[-10], _tolerance);
			Assert.AreEqual(8191, normalizationLut[-9.9742672145744464], _tolerance);

			Assert.AreEqual(0, voiLut.MinInputValue, _tolerance);
			Assert.AreEqual(8191, voiLut.MaxInputValue, _tolerance);
			Assert.AreEqual(0, voiLut.MinOutputValue);
			Assert.AreEqual(8191, voiLut.MaxOutputValue);

			Assert.AreEqual(1543, voiLut[1543]);
			Assert.AreEqual(5164, voiLut[5164]);
			Assert.AreEqual(7074, voiLut[7074]);

			Assert.AreEqual(1543, lutComposer.Data[1543]);
			Assert.AreEqual(5164, lutComposer.Data[5164]);
			Assert.AreEqual(7074, lutComposer.Data[7074]);
		}
		/// <summary>
		/// Implementation of the <see cref="IDisposable"/> pattern
		/// </summary>
		/// <param name="disposing">True if this object is being disposed, false if it is being finalized</param>
		protected virtual void Dispose(bool disposing)
		{
			_disposed = true;

			if (disposing)
			{
				_vtkData = null;

				if (_lutFactory != null)
				{
					_lutFactory.Dispose();
					_lutFactory = null;
				}

				if (_lutComposer != null)
				{
					_lutComposer.LutChanged -= OnLutComposerChanged;
					_lutComposer.Dispose();
					_lutComposer = null;
				}
			}
		}
예제 #52
0
		public void ComposeSingleLUT()
		{
			double windowWidth = 350;
			double windowLevel = 40;

			BasicVoiLutLinear voiLUT = new BasicVoiLutLinear();
			voiLUT.MinInputValue = 0;
			voiLUT.MaxInputValue = 4095;

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

			LutComposer lutComposer = new LutComposer(0, 4095);
			lutComposer.VoiLut = voiLUT;
			int[] data = lutComposer.Data;
		}
예제 #53
0
        public void NoLUTsAdded()
        {
            LutComposer lutComposer = new LutComposer();

            int[] data = lutComposer.Data;
        }
예제 #54
0
		public void NoLUTsAdded()
		{
			LutComposer lutComposer = new LutComposer();
			int[] data = lutComposer.Data;
		}
        private byte PerformBilinearInterpolationAt(PointF srcPoint00)
        {
            if (srcPoint00.Y < 0)
            {
                srcPoint00.Y = 0;
            }
            if (srcPoint00.X < 0)
            {
                srcPoint00.X = 0;
            }

            if (srcPoint00.X > (_srcWidth - 1.001F))
            {
                srcPoint00.X = (_srcWidth - 1.001F);
            }
            if (srcPoint00.Y > (_srcHeight - 1.001F))
            {
                srcPoint00.Y = (_srcHeight - 1.001F);
            }

            Point srcPointInt00 = new Point((int)srcPoint00.X, (int)srcPoint00.Y);

            float[,] arrayOfValues = new float[2, 2] {
                { 0, 0 }, { 0, 0 }
            };

            if (IsColor())
            {
                //Just test the R value, the calculation is done in exactly the same way
                //for G & B, so if it's OK for the R channel it's OK for them too.

                //Get the 4 neighbour pixels for performing bilinear interpolation.
                arrayOfValues[0, 0] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X, srcPointInt00.Y).R;
                arrayOfValues[0, 1] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X, srcPointInt00.Y + 1).R;
                arrayOfValues[1, 0] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X + 1, srcPointInt00.Y).R;
                arrayOfValues[1, 1] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X + 1, srcPointInt00.Y + 1).R;
            }
            else
            {
                if (_image.BitsPerPixel == 16)
                {
                    //Get the 4 neighbour pixels for performing bilinear interpolation.
                    arrayOfValues[0, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y);
                    arrayOfValues[0, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y + 1);
                    arrayOfValues[1, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y);
                    arrayOfValues[1, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y + 1);
                }
                else if (_image.BitsPerPixel == 8)
                {
                    //Get the 4 neighbour pixels for performing bilinear interpolation.
                    arrayOfValues[0, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y);
                    arrayOfValues[0, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y + 1);
                    arrayOfValues[1, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y);
                    arrayOfValues[1, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y + 1);
                }
            }

            //TraceLine(String.Format("Pt: ({0}, {1})", srcPoint00.X, srcPoint00.Y));
            //TraceLine(String.Format("Values:\n{0}  {1}\n{2}  {3}", arrayOfValues[0, 0], arrayOfValues[1, 0], arrayOfValues[0, 1], arrayOfValues[1, 1]));

            //this actually performs the bilinear interpolation within the source image using 4 neighbour pixels.
            float dx = srcPoint00.X - (float)srcPointInt00.X;
            float dy = srcPoint00.Y - (float)srcPointInt00.Y;

            int dyFixed = (int)(dy * _fixedScale);
            int dxFixed = (int)(dx * _fixedScale);

            int yInterpolated1 = (((int)(arrayOfValues[0, 0])) << _fixedPrecision) + ((dyFixed * ((int)((arrayOfValues[0, 1] - arrayOfValues[0, 0])) << _fixedPrecision)) >> _fixedPrecision);
            int yInterpolated2 = (((int)(arrayOfValues[1, 0])) << _fixedPrecision) + ((dyFixed * ((int)((arrayOfValues[1, 1] - arrayOfValues[1, 0])) << _fixedPrecision)) >> _fixedPrecision);
            int interpolated   = (yInterpolated1 + (((dxFixed) * (yInterpolated2 - yInterpolated1)) >> _fixedPrecision)) >> _fixedPrecision;

            //TraceLine(String.Format("Pt: ({0}, {1})", srcPoint00.X, srcPoint00.Y));
            //TraceLine(String.Format("Values:\n{0}  {1}\n{2}  {3}", arrayOfValues[0, 0], arrayOfValues[1, 0], arrayOfValues[0, 1], arrayOfValues[1, 1]));
            //TraceLine(String.Format("dx, dy = {0}, {1}", dx, dy));
            //TraceLine(String.Format("interpolated = {0}", interpolated));

            if (IsColor())
            {
                return((byte)interpolated);
            }

            //The image's LutComposer is private, so we just replicate it here and recalculate.
            GrayscaleImageGraphic graphic  = (GrayscaleImageGraphic)_image;
            LutComposer           composer = new LutComposer(graphic.BitsStored, graphic.IsSigned);

            composer.ModalityLut = graphic.ModalityLut;
            composer.VoiLut      = graphic.VoiLut;
            var colorMap = new GrayscaleColorMap();

            colorMap.MaxInputValue = composer.MaxOutputValue;
            colorMap.MinInputValue = composer.MinOutputValue;
            return(Color.FromArgb(colorMap[composer[interpolated]]).R);
        }
		private byte PerformBilinearInterpolationAt(PointF srcPoint00)
		{
			if (srcPoint00.Y < 0)
				srcPoint00.Y = 0;
			if (srcPoint00.X < 0)
				srcPoint00.X = 0;

			if (srcPoint00.X > (_srcWidth - 1.001F))
				srcPoint00.X = (_srcWidth - 1.001F);
			if (srcPoint00.Y > (_srcHeight - 1.001F))
				srcPoint00.Y = (_srcHeight - 1.001F);

			Point srcPointInt00 = new Point((int)srcPoint00.X, (int)srcPoint00.Y);

			float[,] arrayOfValues = new float[2, 2] { { 0, 0 }, { 0, 0 } };

			if (IsColor())
			{
				//Just test the R value, the calculation is done in exactly the same way 
				//for G & B, so if it's OK for the R channel it's OK for them too.

				//Get the 4 neighbour pixels for performing bilinear interpolation.
				arrayOfValues[0, 0] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X, srcPointInt00.Y).R;
				arrayOfValues[0, 1] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X, srcPointInt00.Y + 1).R;
				arrayOfValues[1, 0] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X + 1, srcPointInt00.Y).R;
				arrayOfValues[1, 1] = (float)ColorPixelData().GetPixelAsColor(srcPointInt00.X + 1, srcPointInt00.Y + 1).R;
			}
			else
			{
				if (_image.BitsPerPixel == 16)
				{
					//Get the 4 neighbour pixels for performing bilinear interpolation.
					arrayOfValues[0, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y);
					arrayOfValues[0, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y + 1);
					arrayOfValues[1, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y);
					arrayOfValues[1, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y + 1);
				}
				else if (_image.BitsPerPixel == 8)
				{
					//Get the 4 neighbour pixels for performing bilinear interpolation.
					arrayOfValues[0, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y);
					arrayOfValues[0, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X, srcPointInt00.Y + 1);
					arrayOfValues[1, 0] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y);
					arrayOfValues[1, 1] = (float)GrayscalePixelData().GetPixel(srcPointInt00.X + 1, srcPointInt00.Y + 1);
				}
			}

			//TraceLine(String.Format("Pt: ({0}, {1})", srcPoint00.X, srcPoint00.Y));
			//TraceLine(String.Format("Values:\n{0}  {1}\n{2}  {3}", arrayOfValues[0, 0], arrayOfValues[1, 0], arrayOfValues[0, 1], arrayOfValues[1, 1]));

			//this actually performs the bilinear interpolation within the source image using 4 neighbour pixels.
			float dx = srcPoint00.X - (float)srcPointInt00.X;
			float dy = srcPoint00.Y - (float)srcPointInt00.Y;
			
			int dyFixed = (int)(dy * _fixedScale);
			int dxFixed = (int)(dx * _fixedScale);

			int yInterpolated1 = (((int)(arrayOfValues[0, 0])) << _fixedPrecision) + ((dyFixed * ((int)((arrayOfValues[0, 1] - arrayOfValues[0, 0])) << _fixedPrecision)) >> _fixedPrecision);
			int yInterpolated2 = (((int)(arrayOfValues[1, 0])) << _fixedPrecision) + ((dyFixed * ((int)((arrayOfValues[1, 1] - arrayOfValues[1, 0])) << _fixedPrecision)) >> _fixedPrecision);
			int interpolated = (yInterpolated1 + (((dxFixed) * (yInterpolated2 - yInterpolated1)) >> _fixedPrecision)) >> _fixedPrecision;

			//TraceLine(String.Format("Pt: ({0}, {1})", srcPoint00.X, srcPoint00.Y));
			//TraceLine(String.Format("Values:\n{0}  {1}\n{2}  {3}", arrayOfValues[0, 0], arrayOfValues[1, 0], arrayOfValues[0, 1], arrayOfValues[1, 1]));
			//TraceLine(String.Format("dx, dy = {0}, {1}", dx, dy));
			//TraceLine(String.Format("interpolated = {0}", interpolated));

			if (IsColor())
				return (byte)interpolated;

			//The image's LutComposer is private, so we just replicate it here and recalculate.
			GrayscaleImageGraphic graphic = (GrayscaleImageGraphic) _image;
			LutComposer composer = new LutComposer(graphic.BitsStored, graphic.IsSigned);
			composer.ModalityLut = graphic.ModalityLut;
			composer.VoiLut = graphic.VoiLut;
			var colorMap = new GrayscaleColorMap();
			colorMap.MaxInputValue = composer.MaxOutputValue;
			colorMap.MinInputValue = composer.MinOutputValue;
			return Color.FromArgb(colorMap[composer[interpolated]]).R;
		}