1 #include <string>
2 #include <limits>
3 #include <map>
4 #include <cmath>
5
6 #include "lensfun.h"
7 #include "../libs/lensfun/lensfunprv.h"
8
9
10 typedef struct
11 {
12 lfDatabase *db;
13 size_t img_height;
14 size_t img_width;
15 } lfFixture;
16
17 // setup a standard lens
mod_setup(lfFixture * lfFix,gconstpointer data)18 void mod_setup (lfFixture *lfFix, gconstpointer data)
19 {
20
21 lfFix->db = new lfDatabase ();
22 lfFix->db->LoadDirectory("data/db");
23
24 lfFix->img_height = 1000;
25 lfFix->img_width = 1500;
26 }
27
mod_teardown(lfFixture * lfFix,gconstpointer data)28 void mod_teardown (lfFixture *lfFix, gconstpointer data)
29 {
30 lfFix->db->Destroy();
31 }
32
test_verify_dist_poly3(lfFixture * lfFix,gconstpointer data)33 void test_verify_dist_poly3 (lfFixture *lfFix, gconstpointer data)
34 {
35 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "pEntax 50-200 ED");
36 g_assert_nonnull(lenses);
37 g_assert_cmpstr(lenses[0]->Model, ==, "smc Pentax-DA 50-200mm f/4-5.6 DA ED");
38
39 lfModifier* mod = lfModifier::Create (lenses[0], 1.534f, lfFix->img_width, lfFix->img_height);
40
41 mod->Initialize(lenses[0], LF_PF_F32, 80.89f, 5.6f, 1000.0f, 1.0f, LF_RECTILINEAR,
42 LF_MODIFY_DISTORTION, false);
43
44 float x[] = {0, 751, 810, 1270};
45 float y[] = {0, 497, 937, 100};
46
47 float expected_x[] = {-14.03764153, 751.00000000, 810.27246094, 1275.17346191};
48 float expected_y[] = {-9.35532570, 497.00000000, 938.97027588, 96.02919769};
49
50 float coords [2];
51 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
52 {
53 g_assert_true(mod->ApplyGeometryDistortion (x[i], y[i], 1, 1, coords));
54 //g_print("\n%.8f, %.8f\n", coords[0], coords[1]);
55 g_assert_cmpfloat (fabs (coords [0] - expected_x [i]), <=, 1e-3);
56 g_assert_cmpfloat (fabs (coords [1] - expected_y [i]), <=, 1e-3);
57 }
58
59 mod->Destroy();
60 lf_free (lenses);
61 }
62
test_verify_dist_poly5(lfFixture * lfFix,gconstpointer data)63 void test_verify_dist_poly5 (lfFixture *lfFix, gconstpointer data)
64 {
65 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "Canon PowerShot G12");
66 g_assert_nonnull(lenses);
67 g_assert_cmpstr(lenses[0]->Model, ==, "Canon PowerShot G12 & compatibles (Standard)");
68
69 g_print(lenses[0]->Model);
70
71 lfModifier* mod = lfModifier::Create (lenses[0], 4.6f, lfFix->img_width, lfFix->img_height);
72
73 mod->Initialize(lenses[0], LF_PF_F32, 10.89f, 5.6f, 1000.0f, 1.0f, LF_RECTILINEAR,
74 LF_MODIFY_DISTORTION, false);
75
76 float x[] = {0, 751, 810, 1270};
77 float y[] = {0, 497, 937, 100};
78
79 float expected_x[] = {28.85699272, 751.00000000, 809.50451660, 1260.12316895};
80 float expected_y[] = {19.23155594, 497.00000000, 933.41711426, 107.58076477};
81
82 float coords [2];
83 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
84 {
85 g_assert_true(mod->ApplyGeometryDistortion (x[i], y[i], 1, 1, coords));
86 //g_print("\n%.8f, %.8f\n", coords[0], coords[1]);
87 g_assert_cmpfloat (fabs (coords [0] - expected_x [i]), <=, 1e-3);
88 g_assert_cmpfloat (fabs (coords [1] - expected_y [i]), <=, 1e-3);
89 }
90
91 mod->Destroy();
92 lf_free (lenses);
93 }
94
test_verify_dist_ptlens(lfFixture * lfFix,gconstpointer data)95 void test_verify_dist_ptlens (lfFixture *lfFix, gconstpointer data)
96 {
97 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "PENTAX-F 28-80mm");
98 g_assert_nonnull(lenses);
99 g_assert_cmpstr(lenses[0]->Model, ==, "Pentax-F 28-80mm f/3.5-4.5");
100
101 lfModifier* mod = lfModifier::Create (lenses[0], 1.534f, lfFix->img_width, lfFix->img_height);
102
103 mod->Initialize(lenses[0], LF_PF_F32, 30.89f, 5.6f, 1000.0f, 1.0f, LF_RECTILINEAR,
104 LF_MODIFY_DISTORTION, false);
105
106 float x[] = {0, 751, 810, 1270};
107 float y[] = {0, 497, 937, 100};
108
109 float expected_x[] = {29.04440117, 750.99969482, 808.74157715, 1255.12915039};
110 float expected_y[] = {19.35648155, 497.00045776, 927.89971924, 111.41387939};
111
112 float coords [2];
113 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
114 {
115 g_assert_true(mod->ApplyGeometryDistortion (x[i], y[i], 1, 1, coords));
116 //g_print("\n%.8f, %.8f\n", coords[0], coords[1]);
117 g_assert_cmpfloat (fabs (coords [0] - expected_x [i]), <=, 1e-3);
118 g_assert_cmpfloat (fabs (coords [1] - expected_y [i]), <=, 1e-3);
119 }
120
121 mod->Destroy();
122 lf_free (lenses);
123 }
124
test_verify_vignetting_pa(lfFixture * lfFix,gconstpointer data)125 void test_verify_vignetting_pa (lfFixture *lfFix, gconstpointer data)
126 {
127 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "Olympus ED 14-42mm");
128 g_assert_nonnull(lenses);
129 g_assert_cmpstr(lenses[0]->Model, ==, "Olympus Zuiko Digital ED 14-42mm f/3.5-5.6");
130
131 lfModifier* mod = lfModifier::Create (lenses[0], 2.0f, lfFix->img_width, lfFix->img_height);
132
133 mod->Initialize(lenses[0], LF_PF_U16, 17.89f, 5.0f, 1000.0f, 1.0f, LF_RECTILINEAR,
134 LF_MODIFY_VIGNETTING, false);
135
136 float x[] = {0, 751, 810, 1270};
137 float y[] = {0, 497, 937, 100};
138
139 lf_u16 expected[] = {22422, 22422, 24174, 28848};
140
141 lf_u16 coords [3] = {16000, 16000, 16000};
142 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
143 {
144 g_assert_true(mod->ApplyColorModification(&coords[0], x[i], y[i], 1, 1, LF_CR_3(RED,GREEN,BLUE), 0));
145 //g_print("\n%d, %d, %d\n", coords[0], coords[1], coords[2]);
146 g_assert_cmpfloat (fabs (coords [0] - expected [i]), <=, 1e-3);
147 g_assert_cmpfloat (fabs (coords [1] - expected [i]), <=, 1e-3);
148 g_assert_cmpfloat (fabs (coords [2] - expected [i]), <=, 1e-3);
149 }
150
151 mod->Destroy();
152 lf_free (lenses);
153 }
154
test_verify_subpix_linear(lfFixture * lfFix,gconstpointer data)155 void test_verify_subpix_linear (lfFixture *lfFix, gconstpointer data)
156 {
157 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "Olympus ED 14-42mm");
158 g_assert_nonnull(lenses);
159 g_assert_cmpstr(lenses[0]->Model, ==, "Olympus Zuiko Digital ED 14-42mm f/3.5-5.6");
160
161 lfModifier* mod = lfModifier::Create (lenses[0], 2.0f, lfFix->img_width, lfFix->img_height);
162
163 mod->Initialize(lenses[0], LF_PF_U16, 17.89f, 5.0f, 1000.0f, 1.0f, LF_RECTILINEAR,
164 LF_MODIFY_TCA, false);
165
166 float x[] = {0, 751, 810, 1270};
167 float y[] = {0, 497, 937, 100};
168
169 float expected[][6] = {
170 {-0.08681729, -0.05789410, 0.00002450, -0.00001032, -0.02400517, -0.01601936},
171 {751.00061035, 496.99899292, 751.00000000, 497.00000000, 751.00000000, 497.00000000},
172 {810.01995850, 937.14440918, 810.00000000, 937.00000000, 810.00042725, 937.00305176},
173 {1270.12915039, 99.90086365, 1270.00000000, 100.00000763, 1270.00854492, 99.99343872}
174 };
175
176 float coords [6];
177 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
178 {
179 g_assert_true(mod->ApplySubpixelDistortion(x[i], y[i], 1, 1, coords));
180 //g_print("{%.8f, %.8f, %.8f, %.8f, %.8f, %.8f},\n", coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
181 for (int j = 0; j < 6; j++)
182 g_assert_cmpfloat (fabs (coords [j] - expected [i][j]), <=, 1e-3);
183 }
184
185 mod->Destroy();
186 lf_free (lenses);
187 }
188
test_verify_subpix_poly3(lfFixture * lfFix,gconstpointer data)189 void test_verify_subpix_poly3 (lfFixture *lfFix, gconstpointer data)
190 {
191 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "Olympus ED 14-42mm");
192 g_assert_nonnull(lenses);
193 g_assert_cmpstr(lenses[0]->Model, ==, "Olympus Zuiko Digital ED 14-42mm f/3.5-5.6");
194
195 lfModifier* mod = lfModifier::Create (lenses[0], 2.0f, lfFix->img_width, lfFix->img_height);
196
197 mod->Initialize(lenses[0], LF_PF_U16, 26.89f, 5.0f, 1000.0f, 1.0f, LF_RECTILINEAR,
198 LF_MODIFY_TCA, false);
199
200 float x[] = {0, 751, 810, 1270};
201 float y[] = {0, 497, 937, 100};
202
203 float expected[][6] = {
204 {-0.05537901, -0.03692452, 0.00002450, -0.00001032, 0.01445518, 0.00962087},
205 {751.00061035, 496.99902344, 751.00000000, 497.00000000, 750.99981689, 497.00030518},
206 {810.01898193, 937.13732910, 810.00000000, 937.00000000, 809.99389648, 936.95599365},
207 {1270.11572266, 99.91123199, 1270.00000000, 100.00000763, 1269.96374512, 100.02780914}
208 };
209
210 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
211 {
212 float coords [6];
213 g_assert_true(mod->ApplySubpixelDistortion (x[i], y[i], 1, 1, coords));
214 //g_print("{%.8f, %.8f, %.8f, %.8f, %.8f, %.8f},\n", coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
215 for (int j = 0; j < 6; j++)
216 g_assert_cmpfloat (fabs (coords [j] - expected [i][j]), <=, 1e-3);
217 }
218
219 mod->Destroy();
220 lf_free (lenses);
221 }
222
test_verify_geom_fisheye_rectlinear(lfFixture * lfFix,gconstpointer data)223 void test_verify_geom_fisheye_rectlinear (lfFixture *lfFix, gconstpointer data)
224 {
225 // select a lens from database
226 const lfLens** lenses = lfFix->db->FindLenses (NULL, NULL, "M.Zuiko Digital ED 8mm f/1.8 Fisheye");
227 g_assert_nonnull(lenses);
228 g_assert_cmpstr(lenses[0]->Model, ==, "Olympus M.Zuiko Digital ED 8mm f/1.8 Fisheye Pro");
229
230 lfModifier* mod = lfModifier::Create (lenses[0], 2.0f, lfFix->img_width, lfFix->img_height);
231
232 mod->Initialize(lenses[0], LF_PF_U16, 8.0f, 5.0f, 1000.0f, 1.0f, LF_RECTILINEAR,
233 LF_MODIFY_GEOMETRY, false);
234
235 float x[] = {0, 751, 810, 1270};
236 float y[] = {0, 497, 937, 100};
237
238 float expected_x[] = {248.98896790, 751.00000000, 802.23010254, 1151.07922363};
239 float expected_y[] = {165.93727112, 497.00000000, 880.81262207, 191.27542114};
240
241 float coords [2];
242 for (int i = 0; i < sizeof(x) / sizeof(float); i++)
243 {
244 g_assert_true(mod->ApplyGeometryDistortion (x[i], y[i], 1, 1, coords));
245 //g_print("\n%.8f, %.8f\n", coords[0], coords[1]);
246 g_assert_cmpfloat (fabs (coords [0] - expected_x [i]), <=, 1e-1);
247 g_assert_cmpfloat (fabs (coords [1] - expected_y [i]), <=, 1e-1);
248 }
249
250 mod->Destroy();
251 lf_free (lenses);
252 }
253
main(int argc,char ** argv)254 int main (int argc, char **argv)
255 {
256 setlocale (LC_ALL, "");
257 setlocale(LC_NUMERIC, "C");
258
259 g_test_init (&argc, &argv, NULL);
260
261 g_test_add ("/modifier/coord/dist/verify_poly3", lfFixture, NULL,
262 mod_setup, test_verify_dist_poly3, mod_teardown);
263
264 g_test_add ("/modifier/coord/dist/verify_ptlens", lfFixture, NULL,
265 mod_setup, test_verify_dist_ptlens, mod_teardown);
266
267 g_test_add ("/modifier/coord/dist/verify_poly5", lfFixture, NULL,
268 mod_setup, test_verify_dist_poly5, mod_teardown);
269
270 g_test_add ("/modifier/coord/geom/verify_equisolid_linrect", lfFixture, NULL,
271 mod_setup, test_verify_geom_fisheye_rectlinear, mod_teardown);
272
273 g_test_add ("/modifier/color/vignetting/verify_pa", lfFixture, NULL,
274 mod_setup, test_verify_vignetting_pa, mod_teardown);
275
276 g_test_add ("/modifier/subpix/TCA/verify_linear", lfFixture, NULL,
277 mod_setup, test_verify_subpix_linear, mod_teardown);
278
279 g_test_add ("/modifier/subpix/TCA/verify_poly3", lfFixture, NULL,
280 mod_setup, test_verify_subpix_poly3, mod_teardown);
281
282 return g_test_run();
283 }
284