1 /*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
27 /*
28 * numa_reg2.c
29 *
30 * Tests:
31 * * numa windowed stats
32 * * numa extraction from pix on a line
33 * * pixel averages and variances
34 */
35
36 #include <math.h>
37 #ifndef _WIN32
38 #include <unistd.h>
39 #else
40 #include <windows.h> /* for Sleep() */
41 #endif /* _WIN32 */
42 #include "allheaders.h"
43
44 #define DO_ALL 1
45
46
main(int argc,char ** argv)47 int main(int argc,
48 char **argv)
49 {
50 l_int32 i, j;
51 l_int32 w, h, bw, bh, wpls, rval, gval, bval, same;
52 l_uint32 pixel;
53 l_uint32 *lines, *datas;
54 l_float32 sum1, sum2, ave1, ave2, ave3, ave4, diff1, diff2;
55 l_float32 var1, var2, var3;
56 BOX *box1, *box2;
57 NUMA *na, *na1, *na2, *na3, *na4;
58 PIX *pix, *pixs, *pix1, *pix2, *pix3, *pix4, *pix5, *pixg, *pixd;
59 PIXA *pixa;
60 static char mainName[] = "numa2_reg";
61
62 if (argc != 1)
63 return ERROR_INT(" Syntax: numa2_reg", mainName, 1);
64
65 setLeptDebugOK(1);
66 lept_mkdir("lept/numa2");
67
68 /* -------------------------------------------------------------------*
69 * Numa-windowed stats *
70 * -------------------------------------------------------------------*/
71 #if DO_ALL
72 na = numaRead("lyra.5.na");
73 numaWindowedStats(na, 5, &na1, &na2, &na3, &na4);
74 gplotSimple1(na, GPLOT_PNG, "/tmp/lept/numa2/lyra6", "Original");
75 gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/numa2/lyra7", "Mean");
76 gplotSimple1(na2, GPLOT_PNG, "/tmp/lept/numa2/lyra8", "Mean Square");
77 gplotSimple1(na3, GPLOT_PNG, "/tmp/lept/numa2/lyra9", "Variance");
78 gplotSimple1(na4, GPLOT_PNG, "/tmp/lept/numa2/lyra10", "RMS Difference");
79 pixa = pixaCreate(5);
80 pix1 = pixRead("/tmp/lept/numa2/lyra6.png");
81 pix2 = pixRead("/tmp/lept/numa2/lyra7.png");
82 pix3 = pixRead("/tmp/lept/numa2/lyra8.png");
83 pix4 = pixRead("/tmp/lept/numa2/lyra9.png");
84 pix5 = pixRead("/tmp/lept/numa2/lyra10.png");
85 pixaAddPix(pixa, pix1, L_INSERT);
86 pixaAddPix(pixa, pix2, L_INSERT);
87 pixaAddPix(pixa, pix3, L_INSERT);
88 pixaAddPix(pixa, pix4, L_INSERT);
89 pixaAddPix(pixa, pix5, L_INSERT);
90 pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2);
91 pixDisplay(pixd, 100, 0);
92 pixWrite("/tmp/lept/numa2/window.png", pixd, IFF_PNG);
93 pixDestroy(&pixd);
94 pixaDestroy(&pixa);
95 numaDestroy(&na);
96 numaDestroy(&na1);
97 numaDestroy(&na2);
98 numaDestroy(&na3);
99 numaDestroy(&na4);
100 #endif
101
102 /* -------------------------------------------------------------------*
103 * Extraction on a line *
104 * -------------------------------------------------------------------*/
105 #if DO_ALL
106 /* First, make a pretty image */
107 w = h = 200;
108 pixs = pixCreate(w, h, 32);
109 wpls = pixGetWpl(pixs);
110 datas = pixGetData(pixs);
111 for (i = 0; i < 200; i++) {
112 lines = datas + i * wpls;
113 for (j = 0; j < 200; j++) {
114 rval = (l_int32)((255. * j) / w + (255. * i) / h);
115 gval = (l_int32)((255. * 2 * j) / w + (255. * 2 * i) / h) % 255;
116 bval = (l_int32)((255. * 4 * j) / w + (255. * 4 * i) / h) % 255;
117 composeRGBPixel(rval, gval, bval, &pixel);
118 lines[j] = pixel;
119 }
120 }
121 pixg = pixConvertTo8(pixs, 0); /* and a grayscale version */
122 pixWrite("/tmp/lept/numa_pixg.png", pixg, IFF_PNG);
123 pixDisplay(pixg, 450, 100);
124
125 na1 = pixExtractOnLine(pixg, 20, 20, 180, 20, 1);
126 na2 = pixExtractOnLine(pixg, 40, 30, 40, 170, 1);
127 na3 = pixExtractOnLine(pixg, 20, 170, 180, 30, 1);
128 na4 = pixExtractOnLine(pixg, 20, 190, 180, 10, 1);
129 gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/numa2/ext1", "Horizontal");
130 gplotSimple1(na2, GPLOT_PNG, "/tmp/lept/numa2/ext2", "Vertical");
131 gplotSimple1(na3, GPLOT_PNG, "/tmp/lept/numa2/ext3",
132 "Slightly more horizontal than vertical");
133 gplotSimple1(na4, GPLOT_PNG, "/tmp/lept/numa2/ext4",
134 "Slightly more vertical than horizontal");
135 pixa = pixaCreate(4);
136 pix1 = pixRead("/tmp/lept/numa2/ext1.png");
137 pix2 = pixRead("/tmp/lept/numa2/ext2.png");
138 pix3 = pixRead("/tmp/lept/numa2/ext3.png");
139 pix4 = pixRead("/tmp/lept/numa2/ext4.png");
140 pixaAddPix(pixa, pix1, L_INSERT);
141 pixaAddPix(pixa, pix2, L_INSERT);
142 pixaAddPix(pixa, pix3, L_INSERT);
143 pixaAddPix(pixa, pix4, L_INSERT);
144 pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2);
145 pixDisplay(pixd, 100, 450);
146 pixWrite("/tmp/lept/numa2/extract.png", pixd, IFF_PNG);
147 pixDestroy(&pixd);
148 pixaDestroy(&pixa);
149 pixDestroy(&pixg);
150 numaDestroy(&na1);
151 numaDestroy(&na2);
152 numaDestroy(&na3);
153 numaDestroy(&na4);
154 #endif
155
156 /* -------------------------------------------------------------------*
157 * Row and column pixel sums *
158 * -------------------------------------------------------------------*/
159 #if DO_ALL
160 /* Sum by columns in two halves (left and right) */
161 pixs = pixRead("test8.jpg");
162 pixGetDimensions(pixs, &w, &h, NULL);
163 box1 = boxCreate(0, 0, w / 2, h);
164 box2 = boxCreate(w / 2, 0, w - 2 / 2, h);
165 na1 = pixAverageByColumn(pixs, box1, L_BLACK_IS_MAX);
166 na2 = pixAverageByColumn(pixs, box2, L_BLACK_IS_MAX);
167 numaJoin(na1, na2, 0, -1);
168 na3 = pixAverageByColumn(pixs, NULL, L_BLACK_IS_MAX);
169 numaSimilar(na1, na3, 0.0, &same);
170 if (same)
171 fprintf(stderr, "Same for columns\n");
172 else
173 fprintf(stderr, "Error for columns\n");
174 pix = pixConvertTo32(pixs);
175 pixRenderPlotFromNumaGen(&pix, na3, L_HORIZONTAL_LINE, 3, h / 2, 80, 1,
176 0xff000000);
177 pixRenderPlotFromNuma(&pix, na3, L_PLOT_AT_BOT, 3, 80, 0xff000000);
178 boxDestroy(&box1);
179 boxDestroy(&box2);
180 numaDestroy(&na1);
181 numaDestroy(&na2);
182 numaDestroy(&na3);
183
184 /* Sum by rows in two halves (top and bottom) */
185 box1 = boxCreate(0, 0, w, h / 2);
186 box2 = boxCreate(0, h / 2, w, h - h / 2);
187 na1 = pixAverageByRow(pixs, box1, L_WHITE_IS_MAX);
188 na2 = pixAverageByRow(pixs, box2, L_WHITE_IS_MAX);
189 numaJoin(na1, na2, 0, -1);
190 na3 = pixAverageByRow(pixs, NULL, L_WHITE_IS_MAX);
191 numaSimilar(na1, na3, 0.0, &same);
192 if (same)
193 fprintf(stderr, "Same for rows\n");
194 else
195 fprintf(stderr, "Error for rows\n");
196 pixRenderPlotFromNumaGen(&pix, na3, L_VERTICAL_LINE, 3, w / 2, 80, 1,
197 0x00ff0000);
198 pixRenderPlotFromNuma(&pix, na3, L_PLOT_AT_RIGHT, 3, 80, 0x00ff0000);
199 pixDisplay(pix, 500, 200);
200 boxDestroy(&box1);
201 boxDestroy(&box2);
202 numaDestroy(&na1);
203 numaDestroy(&na2);
204 numaDestroy(&na3);
205 pixDestroy(&pix);
206
207 /* Average left by rows; right by columns; compare totals */
208 box1 = boxCreate(0, 0, w / 2, h);
209 box2 = boxCreate(w / 2, 0, w - 2 / 2, h);
210 na1 = pixAverageByRow(pixs, box1, L_WHITE_IS_MAX);
211 na2 = pixAverageByColumn(pixs, box2, L_WHITE_IS_MAX);
212 numaGetSum(na1, &sum1); /* sum of averages of left box */
213 numaGetSum(na2, &sum2); /* sum of averages of right box */
214 ave1 = sum1 / h;
215 ave2 = 2.0 * sum2 / w;
216 ave3 = 0.5 * (ave1 + ave2); /* average over both halves */
217 fprintf(stderr, "ave1 = %8.4f\n", sum1 / h);
218 fprintf(stderr, "ave2 = %8.4f\n", 2.0 * sum2 / w);
219 pixAverageInRect(pixs, NULL, &ave4); /* entire image */
220 diff1 = ave4 - ave3;
221 diff2 = w * h * ave4 - (0.5 * w * sum1 + h * sum2);
222 if (diff1 < 0.001)
223 fprintf(stderr, "Average diffs are correct\n");
224 else
225 fprintf(stderr, "Average diffs are wrong: diff1 = %7.5f\n", diff1);
226 if (diff2 < 20) /* float-to-integer roundoff */
227 fprintf(stderr, "Pixel sums are correct\n");
228 else
229 fprintf(stderr, "Pixel sums are in error: diff = %7.0f\n", diff2);
230
231 /* Variance left and right halves. Variance doesn't average
232 * in a simple way, unlike pixel sums. */
233 pixVarianceInRect(pixs, box1, &var1); /* entire image */
234 pixVarianceInRect(pixs, box2, &var2); /* entire image */
235 pixVarianceInRect(pixs, NULL, &var3); /* entire image */
236 fprintf(stderr, "0.5 * (var1 + var2) = %7.3f, var3 = %7.3f\n",
237 0.5 * (var1 + var2), var3);
238 boxDestroy(&box1);
239 boxDestroy(&box2);
240 numaDestroy(&na1);
241 numaDestroy(&na2);
242 #endif
243
244 /* -------------------------------------------------------------------*
245 * Row and column variances *
246 * -------------------------------------------------------------------*/
247 #if DO_ALL
248
249 /* Display variance by rows and columns */
250 box1 = boxCreate(415, 0, 130, 425);
251 boxGetGeometry(box1, NULL, NULL, &bw, &bh);
252 na1 = pixVarianceByRow(pixs, box1);
253 na2 = pixVarianceByColumn(pixs, box1);
254 pix = pixConvertTo32(pixs);
255 pix1 = pixCopy(NULL, pix);
256 pixRenderPlotFromNumaGen(&pix, na1, L_VERTICAL_LINE, 3, 415, 100, 1,
257 0xff000000);
258 pixRenderPlotFromNumaGen(&pix, na2, L_HORIZONTAL_LINE, 3, bh / 2, 100, 1,
259 0x00ff0000);
260 pixRenderPlotFromNuma(&pix1, na1, L_PLOT_AT_LEFT, 3, 60, 0x00ff0000);
261 pixRenderPlotFromNuma(&pix1, na1, L_PLOT_AT_MID_VERT, 3, 60, 0x0000ff00);
262 pixRenderPlotFromNuma(&pix1, na1, L_PLOT_AT_RIGHT, 3, 60, 0xff000000);
263 pixRenderPlotFromNuma(&pix1, na2, L_PLOT_AT_TOP, 3, 60, 0x0000ff00);
264 pixRenderPlotFromNuma(&pix1, na2, L_PLOT_AT_MID_HORIZ, 3, 60, 0xff000000);
265 pixRenderPlotFromNuma(&pix1, na2, L_PLOT_AT_BOT, 3, 60, 0x00ff0000);
266 pixDisplay(pix, 500, 900);
267 pixDisplay(pix1, 500, 1000);
268 boxDestroy(&box1);
269 numaDestroy(&na1);
270 numaDestroy(&na2);
271 pixDestroy(&pix);
272 pixDestroy(&pix1);
273 pixDestroy(&pixs);
274
275 /* Again on a different image */
276 pix1 = pixRead("boxedpage.jpg");
277 pix2 = pixConvertTo8(pix1, 0);
278 pixGetDimensions(pix2, &w, &h, NULL);
279 na1 = pixVarianceByRow(pix2, NULL);
280 pix3 = pixConvertTo32(pix1);
281 pixRenderPlotFromNumaGen(&pix3, na1, L_VERTICAL_LINE, 3, 0, 70, 1,
282 0xff000000);
283 na2 = pixVarianceByColumn(pix2, NULL);
284 pixRenderPlotFromNumaGen(&pix3, na2, L_HORIZONTAL_LINE, 3, bh - 1, 70, 1,
285 0x00ff0000);
286 pixDisplay(pix3, 1000, 0);
287 numaDestroy(&na1);
288 numaDestroy(&na2);
289 pixDestroy(&pix3);
290
291 /* Again, with an erosion */
292 pix3 = pixErodeGray(pix2, 3, 21);
293 pixDisplay(pix3, 1400, 0);
294 na1 = pixVarianceByRow(pix3, NULL);
295 pix4 = pixConvertTo32(pix1);
296 pixRenderPlotFromNumaGen(&pix4, na1, L_VERTICAL_LINE, 3, 30, 70, 1,
297 0xff000000);
298 na2 = pixVarianceByColumn(pix3, NULL);
299 pixRenderPlotFromNumaGen(&pix4, na2, L_HORIZONTAL_LINE, 3, bh - 1, 70, 1,
300 0x00ff0000);
301 pixDisplay(pix4, 1000, 550);
302 numaDestroy(&na1);
303 numaDestroy(&na2);
304 pixDestroy(&pix1);
305 pixDestroy(&pix2);
306 pixDestroy(&pix3);
307 pixDestroy(&pix4);
308 #endif
309
310 /* -------------------------------------------------------------------*
311 * Windowed variance along a line *
312 * -------------------------------------------------------------------*/
313 #if DO_ALL
314 pix1 = pixRead("boxedpage.jpg");
315 pix2 = pixConvertTo8(pix1, 0);
316 pixGetDimensions(pix2, &w, &h, NULL);
317 pix3 = pixCopy(NULL, pix1);
318
319 /* Plot along horizontal line */
320 pixWindowedVarianceOnLine(pix2, L_HORIZONTAL_LINE, h / 2 - 30, 0,
321 w, 5, &na1);
322 pixRenderPlotFromNumaGen(&pix1, na1, L_HORIZONTAL_LINE, 3, h / 2 - 30,
323 80, 1, 0xff000000);
324 pixRenderPlotFromNuma(&pix3, na1, L_PLOT_AT_TOP, 3, 60, 0x00ff0000);
325 pixRenderPlotFromNuma(&pix3, na1, L_PLOT_AT_BOT, 3, 60, 0x0000ff00);
326
327 /* Plot along vertical line */
328 pixWindowedVarianceOnLine(pix2, L_VERTICAL_LINE, 0.78 * w, 0,
329 h, 5, &na2);
330 pixRenderPlotFromNumaGen(&pix1, na2, L_VERTICAL_LINE, 3, 0.78 * w, 60,
331 1, 0x00ff0000);
332 pixRenderPlotFromNuma(&pix3, na2, L_PLOT_AT_LEFT, 3, 60, 0xff000000);
333 pixRenderPlotFromNuma(&pix3, na2, L_PLOT_AT_RIGHT, 3, 60, 0x00ff0000);
334 pixDisplay(pix1, 1000, 1000);
335 pixDisplay(pix3, 1500, 1000);
336 pixDestroy(&pix1);
337 pixDestroy(&pix2);
338 pixDestroy(&pix3);
339 numaDestroy(&na1);
340 numaDestroy(&na2);
341 #endif
342 return 0;
343 }
344