]> git.sesse.net Git - movit/blob - deconvolution_sharpen_effect_test.cpp
Oops, forgot to actually add deconvolution_sharpen_effect_test.cpp.
[movit] / deconvolution_sharpen_effect_test.cpp
1 // Unit tests for DeconvolutionSharpenEffect.
2
3 #include "test_util.h"
4 #include "gtest/gtest.h"
5 #include "deconvolution_sharpen_effect.h"
6
7 TEST(DeconvolutionSharpenEffect, DeconvolvesCircularBlur) {
8         const int size = 13;
9
10         // Matches exactly a circular blur kernel with radius 2.0.
11         float data[size * size] = {
12                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
13                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
14                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
15                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
16                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.017016, 0.038115, 0.017016, 0.000000, 0.0, 0.0, 0.0, 0.0, 
17                 0.0, 0.0, 0.0, 0.0, 0.017016, 0.078381, 0.079577, 0.078381, 0.017016, 0.0, 0.0, 0.0, 0.0, 
18                 0.0, 0.0, 0.0, 0.0, 0.038115, 0.079577, 0.079577, 0.079577, 0.038115, 0.0, 0.0, 0.0, 0.0, 
19                 0.0, 0.0, 0.0, 0.0, 0.017016, 0.078381, 0.079577, 0.078381, 0.017016, 0.0, 0.0, 0.0, 0.0, 
20                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.017016, 0.038115, 0.017016, 0.000000, 0.0, 0.0, 0.0, 0.0, 
21                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
22                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
23                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
24                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
25         };
26         float expected_data[size * size] = {
27                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
28                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
29                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
30                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
31                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
32                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
33                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
34                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
35                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
36                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
37                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
38                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
39                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
40         };
41         float out_data[size * size];
42
43         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
44         Effect *deconvolution_effect = tester.get_chain()->add_effect(new DeconvolutionSharpenEffect());
45         ASSERT_TRUE(deconvolution_effect->set_int("matrix_size", 5));
46         ASSERT_TRUE(deconvolution_effect->set_float("circle_radius", 2.0f));
47         ASSERT_TRUE(deconvolution_effect->set_float("gaussian_radius", 0.0f));
48         ASSERT_TRUE(deconvolution_effect->set_float("correlation", 0.0001f));
49         ASSERT_TRUE(deconvolution_effect->set_float("noise", 0.0f));
50         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
51
52         // The limits have to be quite lax; deconvolution is not an exact operation.
53         expect_equal(expected_data, out_data, size, size, 0.15f, 0.005f);
54 }
55
56 TEST(DeconvolutionSharpenEffect, DeconvolvesGaussianBlur) {
57         const int size = 13;
58         const float sigma = 0.5f;
59
60         float data[size * size], out_data[size * size];
61         float expected_data[] = {
62                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
63                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
64                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
65                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
66                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
67                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
68                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
69                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
70                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
71                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
72                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
73                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
74                 0.0, 0.0, 0.0, 0.0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0, 0.0, 0.0, 0.0, 
75         };
76
77         float sum = 0.0f;       
78         for (int y = 0; y < size; ++y) {
79                 for (int x = 0; x < size; ++x) {
80                         float z = hypot(x - 6, y - 6);
81                         data[y * size + x] = exp(-z*z / (2.0 * sigma * sigma)) / (2.0 * M_PI * sigma * sigma);
82                         sum += data[y * size + x];
83                 }
84         }
85         for (int y = 0; y < size; ++y) {
86                 for (int x = 0; x < size; ++x) {
87                         data[y * size + x] /= sum;
88                 }
89         }
90
91         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
92         Effect *deconvolution_effect = tester.get_chain()->add_effect(new DeconvolutionSharpenEffect());
93         ASSERT_TRUE(deconvolution_effect->set_int("matrix_size", 5));
94         ASSERT_TRUE(deconvolution_effect->set_float("circle_radius", 0.0f));
95         ASSERT_TRUE(deconvolution_effect->set_float("gaussian_radius", sigma));
96         ASSERT_TRUE(deconvolution_effect->set_float("correlation", 0.0001f));
97         ASSERT_TRUE(deconvolution_effect->set_float("noise", 0.0f));
98         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
99
100         // We don't actually need to adjust the limits here; deconvolution of
101         // this kernel is pretty much exact.
102         expect_equal(expected_data, out_data, size, size);
103 }
104
105 // TODO: Test no-op (both radii equal to zero).
106 // TODO: Test correlation and noise parameters.