/* * * Copyright (C) 2017-2019, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by * * OFFIS e.V. * R&D Division Health * Escherweg 2 * D-26121 Oldenburg, Germany * * * Module: dcmiod * * Author: Michael Onken * * Purpose: Tests for dcmiod's color conversion functionalities * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmiod/cielabutil.h" #include "dcmtk/ofstd/ofrand.h" #include "dcmtk/ofstd/oftest.h" OFTEST(dcmiod_tcielabutil) { // Result variables for testing double r1, r2, r3; r1 = r2 = r3 = 0.0; // Test RGB -> CIELab conversion with medium values IODCIELabUtil::rgb2Lab(r1, r2, r3 /* L,a,b */, 0.5, 0.5, 0.5); OFCHECK(fabs(53.388 - r1) < 0.001); OFCHECK(fabs(0.006 - r2) < 0.001); OFCHECK(fabs(-0.010 - r3) < 0.001); // Test RGB -> CIEXYZ conversion with medium values r1 = r2 = r3 = 0; IODCIELabUtil::rgb2Xyz(r1, r2, r3 /* X,Y,Z */, 0.5, 0.5, 0.5); OFCHECK(fabs(0.203 - r1) < 0.001); OFCHECK(fabs(0.214 - r2) < 0.001); OFCHECK(fabs(0.233 - r3) < 0.001); // Test RGB -> CIELab conversion with minimum value r1 = r2 = r3 = 0; IODCIELabUtil::rgb2Lab(r1, r2, r3 /* L,a,b */, 0, 0, 0); OFCHECK(fabs(0 - r1) < 0.001); OFCHECK(fabs(0 - r2) < 0.001); OFCHECK(fabs(0 - r3) < 0.001); // Test RGB -> XYZ conversion with minimum values r1 = r2 = r3 = 0; IODCIELabUtil::rgb2Xyz(r1, r2, r3 /* X,Y,Z */, 0, 0, 0); OFCHECK(fabs(0 - r1) < 0.001); OFCHECK(fabs(0 - r2) < 0.001); OFCHECK(fabs(0 - r3) < 0.001); // Test DICOM CIELab to "normalized" CIELab conversion with maximum values r1 = r2 = r3 = 0; IODCIELabUtil::dicomlab2Lab(r1, r2, r3, 65535, 65535, 65535); OFCHECK(fabs(100 - r1) < 0.001); OFCHECK(fabs(127 - r2) < 0.001); OFCHECK(fabs(127 - r3) < 0.001); // Test DICOM CIELab to "normalized" CIELab conversion with minimum values r1 = r2 = r3 = 0; IODCIELabUtil::dicomlab2Lab(r1, r2, r3, 0, 0, 0); OFCHECK(fabs(0 - r1) < 0.001); OFCHECK(fabs(-128 - r2) < 0.001); OFCHECK(fabs(-128 - r3) < 0.001); // Convert between colorspaces back and forth and check whether deviation after // roundtrip is less than around 1 promille // Initialize random numbers OFRandom rnd; // We do 1000 runs for (size_t numRun = 0; numRun < 1000; numRun++) { // i1, i2, i3: Input for conversion // r1, r2, r3: Results of conversion // o1, o2, o3: Output of inverse conversion (should equal i1, i2, i3) double i1, i2, i3, o1, o2, o3; i1 = i2 = i3 = r1 = r2 = r3 = o1 = o2 = o3 = 0.0; // Roundtrip RGB -> CIELab -> RGB i1 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1); i2 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1); i3 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1); IODCIELabUtil::rgb2Lab(r1, r2, r3, i1, i2, i3); IODCIELabUtil::lab2Rgb(o1, o2, o3, r1, r2, r3); OFCHECK(fabs(i1 - o1) < 0.001); OFCHECK(fabs(i2 - o2) < 0.001); OFCHECK(fabs(i3 - o3) < 0.001); // Roundtrip CIELab -> DICOM CIELab -> CIELab i1 = i2 = i3 = r1 = r2 = r3 = o1 = o2 = o3 = 0.0; i1 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1) * 100.0; i2 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1) * 255.0 - 128; i3 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1) * 255.0 - 128; IODCIELabUtil::lab2DicomLab(r1, r2, r3, i1, i2, i3); IODCIELabUtil::dicomlab2Lab(o1, o2, o3, r1, r2, r3); OFCHECK(fabs(i1 - o1) < 0.001); OFCHECK(fabs(i2 - o2) < 0.001); OFCHECK(fabs(i3 - o3) < 0.001); // Roundtrip RGB -> CIEXYZ -> CIELab -> dicomCIELab -> RGB i1 = i2 = i3 = r1 = r2 = r3 = o1 = o2 = o3 = 0.0; i1 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1); i2 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1); i3 = OFstatic_cast(double, rnd.getRND32()) / OFstatic_cast(Uint32, -1); IODCIELabUtil::rgb2Xyz(r1, r2, r3, i1, i2, i3); IODCIELabUtil::xyz2Lab(o1, o2, o3, r1, r2, r3); IODCIELabUtil::lab2DicomLab(r1, r2, r3, o1, o2, o3); IODCIELabUtil::dicomLab2RGB(o1, o2, o3, r1, r2, r3); OFCHECK(fabs(i1 - o1) < 0.001); OFCHECK(fabs(i2 - o2) < 0.001); OFCHECK(fabs(i3 - o3) < 0.001); } }