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 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]); } }
public void NoLutsAdded() { LutComposer lutComposer = new LutComposer(); var output = lutComposer.GetOutputLut(0, 255); Assert.IsNull(output); }
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]]); }
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); }
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]); }
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); }
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]); }
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]); }
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]); }
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]]); }
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]); }
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> /// 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; } } }
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]); }
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; }
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]); }
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]); }
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]); }
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); }
/// <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; } } }
/// <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 NoLUTsAdded() { LutComposer lutComposer = new LutComposer(); var output = lutComposer.GetOutputLut(0, 255); }
/// <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)); }
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]); }
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]]); }
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]); }
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]); }
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 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]); }
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]]); }
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]); }
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; }