]> git.sesse.net Git - movit/blob - white_balance_effect_test.cpp
When correcting for white balance, move the D65 normalization into compute_lms_scalin...
[movit] / white_balance_effect_test.cpp
1 // Unit tests for WhiteBalanceEffect.
2
3 #include "test_util.h"
4 #include "gtest/gtest.h"
5 #include "white_balance_effect.h"
6
7 TEST(WhiteBalanceEffectTest, GrayNeutralDoesNothing) {
8         float data[] = {
9                 0.0f, 0.0f, 0.0f, 1.0f,
10                 0.5f, 0.5f, 0.5f, 0.3f,
11                 1.0f, 0.0f, 0.0f, 1.0f,
12                 0.0f, 1.0f, 0.0f, 0.7f,
13                 0.0f, 0.0f, 1.0f, 1.0f,
14         };
15         float neutral[] = {
16                 0.5f, 0.5f, 0.5f
17         };
18
19         float out_data[5 * 4];
20         EffectChainTester tester(data, 1, 5, FORMAT_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
21         Effect *white_balance_effect = tester.get_chain()->add_effect(new WhiteBalanceEffect());
22         ASSERT_TRUE(white_balance_effect->set_vec3("neutral_color", neutral));
23         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
24
25         expect_equal(data, out_data, 4, 5);
26 }
27
28 TEST(WhiteBalanceEffectTest, SettingReddishNeutralColorNeutralizesReddishColor) {
29         float data[] = {
30                 0.0f, 0.0f, 0.0f, 1.0f,
31                 0.6f, 0.5f, 0.5f, 1.0f,
32                 0.5f, 0.5f, 0.5f, 1.0f,
33         };
34         float neutral[] = {
35                 0.6f, 0.5f, 0.5f
36         };
37
38         float out_data[3 * 4];
39         EffectChainTester tester(data, 1, 3, FORMAT_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
40         Effect *white_balance_effect = tester.get_chain()->add_effect(new WhiteBalanceEffect());
41         ASSERT_TRUE(white_balance_effect->set_vec3("neutral_color", neutral));
42         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
43
44         // Black should stay black.
45         EXPECT_FLOAT_EQ(0.0f, out_data[4 * 0 + 0]);
46         EXPECT_FLOAT_EQ(0.0f, out_data[4 * 0 + 1]);
47         EXPECT_FLOAT_EQ(0.0f, out_data[4 * 0 + 2]);
48         EXPECT_FLOAT_EQ(1.0f, out_data[4 * 0 + 3]);
49
50         // The neutral color should now have R=G=B.
51         EXPECT_NEAR(out_data[4 * 1 + 0], out_data[4 * 1 + 1], 0.001);
52         EXPECT_NEAR(out_data[4 * 1 + 0], out_data[4 * 1 + 2], 0.001);
53         EXPECT_FLOAT_EQ(1.0f, out_data[4 * 1 + 3]);
54
55         // It should also have kept its luminance.
56         float old_luminance = 0.2126 * data[4 * 1 + 0] +
57                 0.7152 * data[4 * 1 + 1] +
58                 0.0722 * data[4 * 1 + 2];       
59         float new_luminance = 0.2126 * out_data[4 * 1 + 0] +
60                 0.7152 * out_data[4 * 1 + 1] +
61                 0.0722 * out_data[4 * 1 + 2];
62         EXPECT_NEAR(old_luminance, new_luminance, 0.001);
63
64         // Finally, the old gray should now have significantly less red than green and blue.
65         EXPECT_GT(out_data[4 * 2 + 1] - out_data[4 * 2 + 0], 0.05);
66         EXPECT_GT(out_data[4 * 2 + 2] - out_data[4 * 2 + 0], 0.05);
67 }
68
69 TEST(WhiteBalanceEffectTest, HigherColorTemperatureIncreasesBlue) {
70         float data[] = {
71                 0.0f, 0.0f, 0.0f, 1.0f,
72                 0.5f, 0.5f, 0.5f, 1.0f,
73         };
74
75         float out_data[2 * 4];
76         EffectChainTester tester(data, 1, 2, FORMAT_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
77         Effect *white_balance_effect = tester.get_chain()->add_effect(new WhiteBalanceEffect());
78         ASSERT_TRUE(white_balance_effect->set_float("output_color_temperature", 10000.0f));
79         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
80
81         // Black should stay black.
82         EXPECT_FLOAT_EQ(0.0f, out_data[4 * 0 + 0]);
83         EXPECT_FLOAT_EQ(0.0f, out_data[4 * 0 + 1]);
84         EXPECT_FLOAT_EQ(0.0f, out_data[4 * 0 + 2]);
85         EXPECT_FLOAT_EQ(1.0f, out_data[4 * 0 + 3]);
86
87         // The neutral color should have kept its luminance.
88         float old_luminance = 0.2126 * data[4 * 1 + 0] +
89                 0.7152 * data[4 * 1 + 1] +
90                 0.0722 * data[4 * 1 + 2];       
91         float new_luminance = 0.2126 * out_data[4 * 1 + 0] +
92                 0.7152 * out_data[4 * 1 + 1] +
93                 0.0722 * out_data[4 * 1 + 2];
94         EXPECT_NEAR(old_luminance, new_luminance, 0.001);
95
96         // It should also have significantly more blue then green,
97         // and significantly less red than green.
98         EXPECT_GT(out_data[4 * 1 + 2] - out_data[4 * 1 + 1], 0.05);
99         EXPECT_GT(out_data[4 * 1 + 1] - out_data[4 * 1 + 0], 0.05);
100 }