tabula-extractor 0.7.2-java → 0.7.4-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +4 -8
  4. data/bin/tabula +3 -3
  5. data/lib/tabula.rb +9 -5
  6. data/lib/tabula/entities.rb +1 -0
  7. data/lib/tabula/entities/cell.rb +6 -4
  8. data/lib/tabula/entities/has_cells.rb +22 -78
  9. data/lib/tabula/entities/line.rb +52 -6
  10. data/lib/tabula/entities/page.rb +43 -50
  11. data/lib/tabula/entities/ruling.rb +83 -105
  12. data/lib/tabula/entities/spreadsheet.rb +74 -11
  13. data/lib/tabula/entities/table.rb +55 -37
  14. data/lib/tabula/entities/tabular.rb +42 -0
  15. data/lib/tabula/entities/text_chunk.rb +55 -52
  16. data/lib/tabula/entities/text_element.rb +129 -62
  17. data/lib/tabula/entities/zone_entity.rb +15 -6
  18. data/lib/tabula/extraction.rb +114 -49
  19. data/lib/tabula/line_segment_detector.rb +0 -5
  20. data/lib/tabula/table_extractor.rb +32 -37
  21. data/lib/tabula/version.rb +1 -1
  22. data/tabula-extractor.gemspec +2 -5
  23. metadata +13 -95
  24. data/ext/COPYING +0 -661
  25. data/ext/Makefile.OSX +0 -18
  26. data/ext/Makefile.defaults +0 -9
  27. data/ext/Makefile.linux32 +0 -11
  28. data/ext/Makefile.linux64 +0 -12
  29. data/ext/Makefile.mingw +0 -10
  30. data/ext/Makefile.mingw64 +0 -10
  31. data/ext/liblsd-linux32.so +0 -0
  32. data/ext/liblsd-linux64.so +0 -0
  33. data/ext/liblsd.def +0 -3
  34. data/ext/liblsd.dll +0 -0
  35. data/ext/liblsd.dylib +0 -0
  36. data/ext/liblsd64.dll +0 -0
  37. data/ext/lsd.c +0 -2270
  38. data/ext/lsd.h +0 -283
  39. data/test/data/47008204D_USA.page4.pdf +0 -0
  40. data/test/data/560015757GV_China.page1.pdf +0 -0
  41. data/test/data/ClinicalResearchDisclosureReport2012Q2.pdf +0 -0
  42. data/test/data/GSK_2012_Q4.page437.pdf +0 -0
  43. data/test/data/S2MNCEbirdisland.pdf +0 -0
  44. data/test/data/argentina_diputados_voting_record.pdf +0 -0
  45. data/test/data/bo_page24.pdf +0 -0
  46. data/test/data/campaign_donors.pdf +0 -0
  47. data/test/data/frx_2012_disclosure.pdf +0 -0
  48. data/test/data/frx_2012_disclosure.tsv +0 -88
  49. data/test/data/gre.pdf +0 -0
  50. data/test/data/no_tables.pdf +0 -0
  51. data/test/data/nyc_2013fiscalreporttables.pdf +0 -0
  52. data/test/data/puertos1.pdf +0 -0
  53. data/test/data/spanning_cells.csv +0 -21
  54. data/test/data/spanning_cells.pdf +0 -0
  55. data/test/data/strongschools.pdf +0 -0
  56. data/test/data/sydney_disclosure_contract.pdf +0 -0
  57. data/test/data/tabla_subsidios.pdf +0 -0
  58. data/test/data/vertical_rulings_bug.pdf +0 -0
  59. data/test/data/vietnam3.pdf +0 -0
  60. data/test/data/wc2012.pdf +0 -0
  61. data/test/heuristic-test-set/original/560015757GV_China.page1.pdf +0 -0
  62. data/test/heuristic-test-set/original/S2MNCEbirdisland.pdf +0 -0
  63. data/test/heuristic-test-set/original/bo_page24.pdf +0 -0
  64. data/test/heuristic-test-set/original/campaign_donors.pdf +0 -0
  65. data/test/heuristic-test-set/original/cs076pct.pdf +0 -0
  66. data/test/heuristic-test-set/spreadsheet/47008204D_USA.page4.pdf +0 -0
  67. data/test/heuristic-test-set/spreadsheet/GSK_2012_Q4.page437.pdf +0 -0
  68. data/test/heuristic-test-set/spreadsheet/strongschools.pdf +0 -0
  69. data/test/heuristic-test-set/spreadsheet/tabla_subsidios.pdf +0 -0
  70. data/test/heuristic.rb +0 -50
  71. data/test/test_bin_tabula.sh +0 -7
  72. data/test/tests.rb +0 -603
data/ext/Makefile.OSX DELETED
@@ -1,18 +0,0 @@
1
- include Makefile.defaults
2
-
3
-
4
- CFLAGS := -arch i386 -arch x86_64 -fPIC -O3 -g -Wall -Werror
5
-
6
- lib: lib$(NAME).$(VERSION).dylib
7
-
8
- lib$(NAME).$(VERSION).dylib: $(NAME).o
9
- $(CC) -arch i386 -arch x86_64 -dynamiclib -lm -o lib$(NAME).dylib $^
10
-
11
- clean:
12
- $(RM) *.o
13
-
14
- $(NAME)_test: lib$(NAME).$(VERSION).dylib
15
- $(CC) lsd_call_example.c -o $@ -L. -l$(NAME)
16
-
17
- test: $(NAME)_test
18
- LD_LIBRARY_PATH=. ./$(NAME)_test
@@ -1,9 +0,0 @@
1
- CFLAGS := -fPIC -O3 -g -Wall -Werror
2
- CC := gcc
3
- MAJOR := 1
4
- MINOR := 0
5
- NAME := lsd
6
- VERSION := $(MAJOR).$(MINOR)
7
-
8
- clean:
9
- $(RM) *.o *.so* *.dylib
data/ext/Makefile.linux32 DELETED
@@ -1,11 +0,0 @@
1
- include Makefile.defaults
2
-
3
- # link statically with musl-libc
4
- CC = /home/manuel/tabula-build/musl-32/bin/musl-gcc
5
- CFLAGS := -fPIC -Wall -Werror
6
-
7
- lib: lib$(NAME).$(VERSION).so
8
-
9
- lib$(NAME).$(VERSION).so: $(NAME).o
10
- $(CC) -shared -static -o lib$(NAME)-linux32.so $^
11
-
data/ext/Makefile.linux64 DELETED
@@ -1,12 +0,0 @@
1
- # to compile a x86_64 lib in an ubuntu i386 box
2
- include Makefile.defaults
3
-
4
- # link statically with musl-libc
5
- CC = /home/manuel/tabula-build/musl-64/bin/musl-gcc
6
- CFLAGS := -fPIC -Wall -Werror -m64
7
-
8
- lib: lib$(NAME).$(VERSION).so
9
-
10
- lib$(NAME).$(VERSION).so: $(NAME).o
11
- @LDEMULATION=elf_x86_64 $(CC) -m64 -shared -static -o lib$(NAME)-linux64.so $^
12
-
data/ext/Makefile.mingw DELETED
@@ -1,10 +0,0 @@
1
- include Makefile.defaults
2
-
3
- #CC = /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin/i586-mingw32-gcc
4
- CC = /usr/bin/i686-w64-mingw32-gcc-4.6
5
- CFLAGS := -Wall -Werror
6
-
7
- lib: lib$(NAME).$(VERSION).dll
8
-
9
- lib$(NAME).$(VERSION).dll: $(NAME).o
10
- $(CC) -shared -o lib$(NAME).dll liblsd.def $^
data/ext/Makefile.mingw64 DELETED
@@ -1,10 +0,0 @@
1
- include Makefile.defaults
2
-
3
- #CC = /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin/i586-mingw32-gcc
4
- CC = /usr/bin/x86_64-w64-mingw32-gcc
5
- CFLAGS := -Wall -Werror
6
-
7
- lib: lib$(NAME).$(VERSION).dll
8
-
9
- lib$(NAME).$(VERSION).dll: $(NAME).o
10
- $(CC) -shared -o lib$(NAME)64.dll liblsd.def $^
Binary file
Binary file
data/ext/liblsd.def DELETED
@@ -1,3 +0,0 @@
1
- EXPORTS
2
- lsd
3
- free_values
data/ext/liblsd.dll DELETED
Binary file
data/ext/liblsd.dylib DELETED
Binary file
data/ext/liblsd64.dll DELETED
Binary file
data/ext/lsd.c DELETED
@@ -1,2270 +0,0 @@
1
- /*----------------------------------------------------------------------------
2
-
3
- LSD - Line Segment Detector on digital images
4
-
5
- This code is part of the following publication and was subject
6
- to peer review:
7
-
8
- "LSD: a Line Segment Detector" by Rafael Grompone von Gioi,
9
- Jeremie Jakubowicz, Jean-Michel Morel, and Gregory Randall,
10
- Image Processing On Line, 2012. DOI:10.5201/ipol.2012.gjmr-lsd
11
- http://dx.doi.org/10.5201/ipol.2012.gjmr-lsd
12
-
13
- Copyright (c) 2007-2011 rafael grompone von gioi <grompone@gmail.com>
14
-
15
- This program is free software: you can redistribute it and/or modify
16
- it under the terms of the GNU Affero General Public License as
17
- published by the Free Software Foundation, either version 3 of the
18
- License, or (at your option) any later version.
19
-
20
- This program is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU Affero General Public License for more details.
24
-
25
- You should have received a copy of the GNU Affero General Public License
26
- along with this program. If not, see <http://www.gnu.org/licenses/>.
27
-
28
- Additional permission under GNU GPL version 3 section 7
29
-
30
- If you modify this Program, or any covered work, by linking or
31
- combining it with Tabula (or a modified version of that library),
32
- containing parts covered by the terms of "MIT License", the
33
- licensors of this Program grant you additional permission to convey
34
- the resulting work. Corresponding Source for a non-source form of
35
- such a combination shall include the source code for the parts of
36
- Tabula used as well as that of the covered work.
37
-
38
-
39
- ----------------------------------------------------------------------------*/
40
-
41
- /*----------------------------------------------------------------------------*/
42
- /** @file lsd.c
43
- LSD module code
44
- @author rafael grompone von gioi <grompone@gmail.com>
45
- */
46
- /*----------------------------------------------------------------------------*/
47
-
48
- /*----------------------------------------------------------------------------*/
49
- /** @mainpage LSD code documentation
50
-
51
- This is an implementation of the Line Segment Detector described
52
- in the paper:
53
-
54
- "LSD: A Fast Line Segment Detector with a False Detection Control"
55
- by Rafael Grompone von Gioi, Jeremie Jakubowicz, Jean-Michel Morel,
56
- and Gregory Randall, IEEE Transactions on Pattern Analysis and
57
- Machine Intelligence, vol. 32, no. 4, pp. 722-732, April, 2010.
58
-
59
- and in more details in the CMLA Technical Report:
60
-
61
- "LSD: A Line Segment Detector, Technical Report",
62
- by Rafael Grompone von Gioi, Jeremie Jakubowicz, Jean-Michel Morel,
63
- Gregory Randall, CMLA, ENS Cachan, 2010.
64
-
65
- The version implemented here includes some further improvements
66
- described in the following publication, of which this code is part:
67
-
68
- "LSD: a Line Segment Detector" by Rafael Grompone von Gioi,
69
- Jeremie Jakubowicz, Jean-Michel Morel, and Gregory Randall,
70
- Image Processing On Line, 2012. DOI:10.5201/ipol.2012.gjmr-lsd
71
- http://dx.doi.org/10.5201/ipol.2012.gjmr-lsd
72
-
73
- The module's main function is lsd().
74
-
75
- The source code is contained in two files: lsd.h and lsd.c.
76
-
77
- HISTORY:
78
- - version 1.6 - nov 2011:
79
- - changes in the interface,
80
- - max_grad parameter removed,
81
- - the factor 11 was added to the number of test
82
- to consider the different precision values
83
- tested,
84
- - a minor bug corrected in the gradient sorting
85
- code,
86
- - the algorithm now also returns p and log_nfa
87
- for each detection,
88
- - a minor bug was corrected in the image scaling,
89
- - the angle comparison in "isaligned" changed
90
- from < to <=,
91
- - "eps" variable renamed "log_eps",
92
- - "lsd_scale_region" interface was added,
93
- - minor changes to comments.
94
- - version 1.5 - dec 2010: Changes in 'refine', -W option added,
95
- and more comments added.
96
- - version 1.4 - jul 2010: lsd_scale interface added and doxygen doc.
97
- - version 1.3 - feb 2010: Multiple bug correction and improved code.
98
- - version 1.2 - dec 2009: First full Ansi C Language version.
99
- - version 1.1 - sep 2009: Systematic subsampling to scale 0.8 and
100
- correction to partially handle "angle problem".
101
- - version 1.0 - jan 2009: First complete Megawave2 and Ansi C Language
102
- version.
103
-
104
- @author rafael grompone von gioi <grompone@gmail.com>
105
- */
106
- /*----------------------------------------------------------------------------*/
107
-
108
- #include <stdio.h>
109
- #include <stdlib.h>
110
- #include <math.h>
111
- #include <limits.h>
112
- #include <float.h>
113
- #include "lsd.h"
114
-
115
- /** ln(10) */
116
- #ifndef M_LN10
117
- #define M_LN10 2.30258509299404568402
118
- #endif /* !M_LN10 */
119
-
120
- /** PI */
121
- #ifndef M_PI
122
- #define M_PI 3.14159265358979323846
123
- #endif /* !M_PI */
124
-
125
- #ifndef FALSE
126
- #define FALSE 0
127
- #endif /* !FALSE */
128
-
129
- #ifndef TRUE
130
- #define TRUE 1
131
- #endif /* !TRUE */
132
-
133
- /** Label for pixels with undefined gradient. */
134
- #define NOTDEF -1024.0
135
-
136
- /** 3/2 pi */
137
- #define M_3_2_PI 4.71238898038
138
-
139
- /** 2 pi */
140
- #define M_2__PI 6.28318530718
141
-
142
- /** Label for pixels not used in yet. */
143
- #define NOTUSED 0
144
-
145
- /** Label for pixels already used in detection. */
146
- #define USED 1
147
-
148
- /*----------------------------------------------------------------------------*/
149
- /** Chained list of coordinates.
150
- */
151
- struct coorlist
152
- {
153
- int x,y;
154
- struct coorlist * next;
155
- };
156
-
157
- /*----------------------------------------------------------------------------*/
158
- /** A point (or pixel).
159
- */
160
- struct point {int x,y;};
161
-
162
-
163
- /*----------------------------------------------------------------------------*/
164
- /*------------------------- Miscellaneous functions --------------------------*/
165
- /*----------------------------------------------------------------------------*/
166
-
167
- /*----------------------------------------------------------------------------*/
168
- /** Fatal error, print a message to standard-error output and exit.
169
- */
170
- static void error(char * msg)
171
- {
172
- fprintf(stderr,"LSD Error: %s\n",msg);
173
- exit(EXIT_FAILURE);
174
- }
175
-
176
- /*----------------------------------------------------------------------------*/
177
- /** Doubles relative error factor
178
- */
179
- #define RELATIVE_ERROR_FACTOR 100.0
180
-
181
- /*----------------------------------------------------------------------------*/
182
- /** Compare doubles by relative error.
183
-
184
- The resulting rounding error after floating point computations
185
- depend on the specific operations done. The same number computed by
186
- different algorithms could present different rounding errors. For a
187
- useful comparison, an estimation of the relative rounding error
188
- should be considered and compared to a factor times EPS. The factor
189
- should be related to the cumulated rounding error in the chain of
190
- computation. Here, as a simplification, a fixed factor is used.
191
- */
192
- static int double_equal(float a, float b)
193
- {
194
- float abs_diff,aa,bb,abs_max;
195
-
196
- /* trivial case */
197
- if( a == b ) return TRUE;
198
-
199
- abs_diff = fabs(a-b);
200
- aa = fabs(a);
201
- bb = fabs(b);
202
- abs_max = aa > bb ? aa : bb;
203
-
204
- /* DBL_MIN is the smallest normalized number, thus, the smallest
205
- number whose relative error is bounded by DBL_EPSILON. For
206
- smaller numbers, the same quantization steps as for DBL_MIN
207
- are used. Then, for smaller numbers, a meaningful "relative"
208
- error should be computed by dividing the difference by DBL_MIN. */
209
- if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
210
-
211
- /* equal if relative error <= factor x eps */
212
- return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
213
- }
214
-
215
- /*----------------------------------------------------------------------------*/
216
- /** Computes Euclidean distance between point (x1,y1) and point (x2,y2).
217
- */
218
- static float dist(float x1, float y1, float x2, float y2)
219
- {
220
- return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
221
- }
222
-
223
-
224
- /*----------------------------------------------------------------------------*/
225
- /*----------------------- 'list of n-tuple' data type ------------------------*/
226
- /*----------------------------------------------------------------------------*/
227
-
228
- /*----------------------------------------------------------------------------*/
229
- /** 'list of n-tuple' data type
230
-
231
- The i-th component of the j-th n-tuple of an n-tuple list 'ntl'
232
- is accessed with:
233
-
234
- ntl->values[ i + j * ntl->dim ]
235
-
236
- The dimension of the n-tuple (n) is:
237
-
238
- ntl->dim
239
-
240
- The number of n-tuples in the list is:
241
-
242
- ntl->size
243
-
244
- The maximum number of n-tuples that can be stored in the
245
- list with the allocated memory at a given time is given by:
246
-
247
- ntl->max_size
248
- */
249
- typedef struct ntuple_list_s
250
- {
251
- unsigned int size;
252
- unsigned int max_size;
253
- unsigned int dim;
254
- float * values;
255
- } * ntuple_list;
256
-
257
- /*----------------------------------------------------------------------------*/
258
- /** Free memory used in n-tuple 'in'.
259
- */
260
- static void free_ntuple_list(ntuple_list in)
261
- {
262
- if( in == NULL || in->values == NULL )
263
- error("free_ntuple_list: invalid n-tuple input.");
264
- free( (void *) in->values );
265
- free( (void *) in );
266
- }
267
-
268
- /*----------------------------------------------------------------------------*/
269
- /** Create an n-tuple list and allocate memory for one element.
270
- @param dim the dimension (n) of the n-tuple.
271
- */
272
- static ntuple_list new_ntuple_list(unsigned int dim)
273
- {
274
- ntuple_list n_tuple;
275
-
276
- /* check parameters */
277
- if( dim == 0 ) error("new_ntuple_list: 'dim' must be positive.");
278
-
279
- /* get memory for list structure */
280
- n_tuple = (ntuple_list) malloc( sizeof(struct ntuple_list_s) );
281
- if( n_tuple == NULL ) error("not enough memory.");
282
-
283
- /* initialize list */
284
- n_tuple->size = 0;
285
- n_tuple->max_size = 1;
286
- n_tuple->dim = dim;
287
-
288
- /* get memory for tuples */
289
- n_tuple->values = (float *) malloc( dim*n_tuple->max_size * sizeof(float) );
290
- if( n_tuple->values == NULL ) error("not enough memory.");
291
-
292
- return n_tuple;
293
- }
294
-
295
- /*----------------------------------------------------------------------------*/
296
- /** Enlarge the allocated memory of an n-tuple list.
297
- */
298
- static void enlarge_ntuple_list(ntuple_list n_tuple)
299
- {
300
- /* check parameters */
301
- if( n_tuple == NULL || n_tuple->values == NULL || n_tuple->max_size == 0 )
302
- error("enlarge_ntuple_list: invalid n-tuple.");
303
-
304
- /* duplicate number of tuples */
305
- n_tuple->max_size *= 2;
306
-
307
- /* realloc memory */
308
- n_tuple->values = (float *) realloc( (void *) n_tuple->values,
309
- n_tuple->dim * n_tuple->max_size * sizeof(float) );
310
- if( n_tuple->values == NULL ) error("not enough memory.");
311
- }
312
-
313
- /*----------------------------------------------------------------------------*/
314
- /** Add a 7-tuple to an n-tuple list.
315
- */
316
- static void add_7tuple( ntuple_list out, float v1, float v2, float v3,
317
- float v4, float v5, float v6, float v7 )
318
- {
319
- /* check parameters */
320
- if( out == NULL ) error("add_7tuple: invalid n-tuple input.");
321
- if( out->dim != 7 ) error("add_7tuple: the n-tuple must be a 7-tuple.");
322
-
323
- /* if needed, alloc more tuples to 'out' */
324
- if( out->size == out->max_size ) enlarge_ntuple_list(out);
325
- if( out->values == NULL ) error("add_7tuple: invalid n-tuple input.");
326
-
327
- /* add new 7-tuple */
328
- out->values[ out->size * out->dim + 0 ] = v1;
329
- out->values[ out->size * out->dim + 1 ] = v2;
330
- out->values[ out->size * out->dim + 2 ] = v3;
331
- out->values[ out->size * out->dim + 3 ] = v4;
332
- out->values[ out->size * out->dim + 4 ] = v5;
333
- out->values[ out->size * out->dim + 5 ] = v6;
334
- out->values[ out->size * out->dim + 6 ] = v7;
335
-
336
- /* update number of tuples counter */
337
- out->size++;
338
- }
339
-
340
-
341
- /*----------------------------------------------------------------------------*/
342
- /*----------------------------- Image Data Types -----------------------------*/
343
- /*----------------------------------------------------------------------------*/
344
-
345
- /*----------------------------------------------------------------------------*/
346
- /** char image data type
347
-
348
- The pixel value at (x,y) is accessed by:
349
-
350
- image->data[ x + y * image->xsize ]
351
-
352
- with x and y integer.
353
- */
354
- typedef struct image_char_s
355
- {
356
- unsigned char * data;
357
- unsigned int xsize,ysize;
358
- } * image_char;
359
-
360
- /*----------------------------------------------------------------------------*/
361
- /** Free memory used in image_char 'i'.
362
- */
363
- static void free_image_char(image_char i)
364
- {
365
- if( i == NULL || i->data == NULL )
366
- error("free_image_char: invalid input image.");
367
- free( (void *) i->data );
368
- free( (void *) i );
369
- }
370
-
371
- /*----------------------------------------------------------------------------*/
372
- /** Create a new image_char of size 'xsize' times 'ysize'.
373
- */
374
- static image_char new_image_char(unsigned int xsize, unsigned int ysize)
375
- {
376
- image_char image;
377
-
378
- /* check parameters */
379
- if( xsize == 0 || ysize == 0 ) error("new_image_char: invalid image size.");
380
-
381
- /* get memory */
382
- image = (image_char) malloc( sizeof(struct image_char_s) );
383
- if( image == NULL ) error("not enough memory.");
384
- image->data = (unsigned char *) calloc( (size_t) (xsize*ysize),
385
- sizeof(unsigned char) );
386
- if( image->data == NULL ) error("not enough memory.");
387
-
388
- /* set image size */
389
- image->xsize = xsize;
390
- image->ysize = ysize;
391
-
392
- return image;
393
- }
394
-
395
- /*----------------------------------------------------------------------------*/
396
- /** Create a new image_char of size 'xsize' times 'ysize',
397
- initialized to the value 'fill_value'.
398
- */
399
- static image_char new_image_char_ini( unsigned int xsize, unsigned int ysize,
400
- unsigned char fill_value )
401
- {
402
- image_char image = new_image_char(xsize,ysize); /* create image */
403
- unsigned int N = xsize*ysize;
404
- unsigned int i;
405
-
406
- /* check parameters */
407
- if( image == NULL || image->data == NULL )
408
- error("new_image_char_ini: invalid image.");
409
-
410
- /* initialize */
411
- for(i=0; i<N; i++) image->data[i] = fill_value;
412
-
413
- return image;
414
- }
415
-
416
- /*----------------------------------------------------------------------------*/
417
- /** int image data type
418
-
419
- The pixel value at (x,y) is accessed by:
420
-
421
- image->data[ x + y * image->xsize ]
422
-
423
- with x and y integer.
424
- */
425
- typedef struct image_int_s
426
- {
427
- int * data;
428
- unsigned int xsize,ysize;
429
- } * image_int;
430
-
431
- /*----------------------------------------------------------------------------*/
432
- /** Create a new image_int of size 'xsize' times 'ysize'.
433
- */
434
- static image_int new_image_int(unsigned int xsize, unsigned int ysize)
435
- {
436
- image_int image;
437
-
438
- /* check parameters */
439
- if( xsize == 0 || ysize == 0 ) error("new_image_int: invalid image size.");
440
-
441
- /* get memory */
442
- image = (image_int) malloc( sizeof(struct image_int_s) );
443
- if( image == NULL ) error("not enough memory.");
444
- image->data = (int *) calloc( (size_t) (xsize*ysize), sizeof(int) );
445
- if( image->data == NULL ) error("not enough memory.");
446
-
447
- /* set image size */
448
- image->xsize = xsize;
449
- image->ysize = ysize;
450
-
451
- return image;
452
- }
453
-
454
- /*----------------------------------------------------------------------------*/
455
- /** Create a new image_int of size 'xsize' times 'ysize',
456
- initialized to the value 'fill_value'.
457
- */
458
- static image_int new_image_int_ini( unsigned int xsize, unsigned int ysize,
459
- int fill_value )
460
- {
461
- image_int image = new_image_int(xsize,ysize); /* create image */
462
- unsigned int N = xsize*ysize;
463
- unsigned int i;
464
-
465
- /* initialize */
466
- for(i=0; i<N; i++) image->data[i] = fill_value;
467
-
468
- return image;
469
- }
470
-
471
- /*----------------------------------------------------------------------------*/
472
- /** double image data type
473
-
474
- The pixel value at (x,y) is accessed by:
475
-
476
- image->data[ x + y * image->xsize ]
477
-
478
- with x and y integer.
479
- */
480
- typedef struct image_double_s
481
- {
482
- float * data;
483
- unsigned int xsize,ysize;
484
- } * image_double;
485
-
486
- /*----------------------------------------------------------------------------*/
487
- /** Free memory used in image_double 'i'.
488
- */
489
- static void free_image_double(image_double i)
490
- {
491
- if( i == NULL || i->data == NULL )
492
- error("free_image_double: invalid input image.");
493
- free( (void *) i->data );
494
- free( (void *) i );
495
- }
496
-
497
- /*----------------------------------------------------------------------------*/
498
- /** Create a new image_double of size 'xsize' times 'ysize'.
499
- */
500
- static image_double new_image_double(unsigned int xsize, unsigned int ysize)
501
- {
502
- image_double image;
503
-
504
- /* check parameters */
505
- if( xsize == 0 || ysize == 0 ) error("new_image_double: invalid image size.");
506
-
507
- /* get memory */
508
- image = (image_double) malloc( sizeof(struct image_double_s) );
509
- if( image == NULL ) error("not enough memory.");
510
- image->data = (float *) calloc( (size_t) (xsize*ysize), sizeof(float) );
511
- if( image->data == NULL ) error("not enough memory.");
512
-
513
- /* set image size */
514
- image->xsize = xsize;
515
- image->ysize = ysize;
516
-
517
- return image;
518
- }
519
-
520
- /*----------------------------------------------------------------------------*/
521
- /** Create a new image_double of size 'xsize' times 'ysize'
522
- with the data pointed by 'data'.
523
- */
524
- static image_double new_image_double_ptr( unsigned int xsize,
525
- unsigned int ysize, float * data )
526
- {
527
- image_double image;
528
-
529
- /* check parameters */
530
- if( xsize == 0 || ysize == 0 )
531
- error("new_image_double_ptr: invalid image size.");
532
- if( data == NULL ) error("new_image_double_ptr: NULL data pointer.");
533
-
534
- /* get memory */
535
- image = (image_double) malloc( sizeof(struct image_double_s) );
536
- if( image == NULL ) error("not enough memory.");
537
-
538
- /* set image */
539
- image->xsize = xsize;
540
- image->ysize = ysize;
541
- image->data = data;
542
-
543
- return image;
544
- }
545
-
546
-
547
- /*----------------------------------------------------------------------------*/
548
- /*----------------------------- Gaussian filter ------------------------------*/
549
- /*----------------------------------------------------------------------------*/
550
-
551
- /*----------------------------------------------------------------------------*/
552
- /** Compute a Gaussian kernel of length 'kernel->dim',
553
- standard deviation 'sigma', and centered at value 'mean'.
554
-
555
- For example, if mean=0.5, the Gaussian will be centered
556
- in the middle point between values 'kernel->values[0]'
557
- and 'kernel->values[1]'.
558
- */
559
- static void gaussian_kernel(ntuple_list kernel, float sigma, float mean)
560
- {
561
- float sum = 0.0;
562
- float val;
563
- unsigned int i;
564
-
565
- /* check parameters */
566
- if( kernel == NULL || kernel->values == NULL )
567
- error("gaussian_kernel: invalid n-tuple 'kernel'.");
568
- if( sigma <= 0.0 ) error("gaussian_kernel: 'sigma' must be positive.");
569
-
570
- /* compute Gaussian kernel */
571
- if( kernel->max_size < 1 ) enlarge_ntuple_list(kernel);
572
- kernel->size = 1;
573
- for(i=0;i<kernel->dim;i++)
574
- {
575
- val = ( (float) i - mean ) / sigma;
576
- kernel->values[i] = exp( -0.5 * val * val );
577
- sum += kernel->values[i];
578
- }
579
-
580
- /* normalization */
581
- if( sum >= 0.0 ) for(i=0;i<kernel->dim;i++) kernel->values[i] /= sum;
582
- }
583
-
584
- /*----------------------------------------------------------------------------*/
585
- /** Scale the input image 'in' by a factor 'scale' by Gaussian sub-sampling.
586
-
587
- For example, scale=0.8 will give a result at 80% of the original size.
588
-
589
- The image is convolved with a Gaussian kernel
590
- @f[
591
- G(x,y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2+y^2}{2\sigma^2}}
592
- @f]
593
- before the sub-sampling to prevent aliasing.
594
-
595
- The standard deviation sigma given by:
596
- - sigma = sigma_scale / scale, if scale < 1.0
597
- - sigma = sigma_scale, if scale >= 1.0
598
-
599
- To be able to sub-sample at non-integer steps, some interpolation
600
- is needed. In this implementation, the interpolation is done by
601
- the Gaussian kernel, so both operations (filtering and sampling)
602
- are done at the same time. The Gaussian kernel is computed
603
- centered on the coordinates of the required sample. In this way,
604
- when applied, it gives directly the result of convolving the image
605
- with the kernel and interpolated to that particular position.
606
-
607
- A fast algorithm is done using the separability of the Gaussian
608
- kernel. Applying the 2D Gaussian kernel is equivalent to applying
609
- first a horizontal 1D Gaussian kernel and then a vertical 1D
610
- Gaussian kernel (or the other way round). The reason is that
611
- @f[
612
- G(x,y) = G(x) * G(y)
613
- @f]
614
- where
615
- @f[
616
- G(x) = \frac{1}{\sqrt{2\pi}\sigma} e^{-\frac{x^2}{2\sigma^2}}.
617
- @f]
618
- The algorithm first applies a combined Gaussian kernel and sampling
619
- in the x axis, and then the combined Gaussian kernel and sampling
620
- in the y axis.
621
- */
622
- static image_double gaussian_sampler( image_double in, float scale,
623
- float sigma_scale )
624
- {
625
- image_double aux,out;
626
- ntuple_list kernel;
627
- unsigned int N,M,h,n,x,y,i;
628
- int xc,yc,j,double_x_size,double_y_size;
629
- float sigma,xx,yy,sum,prec;
630
-
631
- /* check parameters */
632
- if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
633
- error("gaussian_sampler: invalid image.");
634
- if( scale <= 0.0 ) error("gaussian_sampler: 'scale' must be positive.");
635
- if( sigma_scale <= 0.0 )
636
- error("gaussian_sampler: 'sigma_scale' must be positive.");
637
-
638
- /* compute new image size and get memory for images */
639
- if( in->xsize * scale > (float) UINT_MAX ||
640
- in->ysize * scale > (float) UINT_MAX )
641
- error("gaussian_sampler: the output image size exceeds the handled size.");
642
- N = (unsigned int) ceil( in->xsize * scale );
643
- M = (unsigned int) ceil( in->ysize * scale );
644
- aux = new_image_double(N,in->ysize);
645
- out = new_image_double(N,M);
646
-
647
- /* sigma, kernel size and memory for the kernel */
648
- sigma = scale < 1.0 ? sigma_scale / scale : sigma_scale;
649
- /*
650
- The size of the kernel is selected to guarantee that the
651
- the first discarded term is at least 10^prec times smaller
652
- than the central value. For that, h should be larger than x, with
653
- e^(-x^2/2sigma^2) = 1/10^prec.
654
- Then,
655
- x = sigma * sqrt( 2 * prec * ln(10) ).
656
- */
657
- prec = 3.0;
658
- h = (unsigned int) ceil( sigma * sqrt( 2.0 * prec * log(10.0) ) );
659
- n = 1+2*h; /* kernel size */
660
- kernel = new_ntuple_list(n);
661
-
662
- /* auxiliary double image size variables */
663
- double_x_size = (int) (2 * in->xsize);
664
- double_y_size = (int) (2 * in->ysize);
665
-
666
- /* First subsampling: x axis */
667
- for(x=0;x<aux->xsize;x++)
668
- {
669
- /*
670
- x is the coordinate in the new image.
671
- xx is the corresponding x-value in the original size image.
672
- xc is the integer value, the pixel coordinate of xx.
673
- */
674
- xx = (float) x / scale;
675
- /* coordinate (0.0,0.0) is in the center of pixel (0,0),
676
- so the pixel with xc=0 get the values of xx from -0.5 to 0.5 */
677
- xc = (int) floor( xx + 0.5 );
678
- gaussian_kernel( kernel, sigma, (float) h + xx - (float) xc );
679
- /* the kernel must be computed for each x because the fine
680
- offset xx-xc is different in each case */
681
-
682
- for(y=0;y<aux->ysize;y++)
683
- {
684
- sum = 0.0;
685
- for(i=0;i<kernel->dim;i++)
686
- {
687
- j = xc - h + i;
688
-
689
- /* symmetry boundary condition */
690
- while( j < 0 ) j += double_x_size;
691
- while( j >= double_x_size ) j -= double_x_size;
692
- if( j >= (int) in->xsize ) j = double_x_size-1-j;
693
-
694
- sum += in->data[ j + y * in->xsize ] * kernel->values[i];
695
- }
696
- aux->data[ x + y * aux->xsize ] = sum;
697
- }
698
- }
699
-
700
- /* Second subsampling: y axis */
701
- for(y=0;y<out->ysize;y++)
702
- {
703
- /*
704
- y is the coordinate in the new image.
705
- yy is the corresponding x-value in the original size image.
706
- yc is the integer value, the pixel coordinate of xx.
707
- */
708
- yy = (float) y / scale;
709
- /* coordinate (0.0,0.0) is in the center of pixel (0,0),
710
- so the pixel with yc=0 get the values of yy from -0.5 to 0.5 */
711
- yc = (int) floor( yy + 0.5 );
712
- gaussian_kernel( kernel, sigma, (float) h + yy - (float) yc );
713
- /* the kernel must be computed for each y because the fine
714
- offset yy-yc is different in each case */
715
-
716
- for(x=0;x<out->xsize;x++)
717
- {
718
- sum = 0.0;
719
- for(i=0;i<kernel->dim;i++)
720
- {
721
- j = yc - h + i;
722
-
723
- /* symmetry boundary condition */
724
- while( j < 0 ) j += double_y_size;
725
- while( j >= double_y_size ) j -= double_y_size;
726
- if( j >= (int) in->ysize ) j = double_y_size-1-j;
727
-
728
- sum += aux->data[ x + j * aux->xsize ] * kernel->values[i];
729
- }
730
- out->data[ x + y * out->xsize ] = sum;
731
- }
732
- }
733
-
734
- /* free memory */
735
- free_ntuple_list(kernel);
736
- free_image_double(aux);
737
-
738
- return out;
739
- }
740
-
741
-
742
- /*----------------------------------------------------------------------------*/
743
- /*--------------------------------- Gradient ---------------------------------*/
744
- /*----------------------------------------------------------------------------*/
745
-
746
- /*----------------------------------------------------------------------------*/
747
- /** Computes the direction of the level line of 'in' at each point.
748
-
749
- The result is:
750
- - an image_double with the angle at each pixel, or NOTDEF if not defined.
751
- - the image_double 'modgrad' (a pointer is passed as argument)
752
- with the gradient magnitude at each point.
753
- - a list of pixels 'list_p' roughly ordered by decreasing
754
- gradient magnitude. (The order is made by classifying points
755
- into bins by gradient magnitude. The parameters 'n_bins' and
756
- 'max_grad' specify the number of bins and the gradient modulus
757
- at the highest bin. The pixels in the list would be in
758
- decreasing gradient magnitude, up to a precision of the size of
759
- the bins.)
760
- - a pointer 'mem_p' to the memory used by 'list_p' to be able to
761
- free the memory when it is not used anymore.
762
- */
763
- static image_double ll_angle( image_double in, float threshold,
764
- struct coorlist ** list_p, void ** mem_p,
765
- image_double * modgrad, unsigned int n_bins )
766
- {
767
- image_double g;
768
- unsigned int n,p,x,y,adr,i;
769
- float com1,com2,gx,gy,norm,norm2;
770
- /* the rest of the variables are used for pseudo-ordering
771
- the gradient magnitude values */
772
- int list_count = 0;
773
- struct coorlist * list;
774
- struct coorlist ** range_l_s; /* array of pointers to start of bin list */
775
- struct coorlist ** range_l_e; /* array of pointers to end of bin list */
776
- struct coorlist * start;
777
- struct coorlist * end;
778
- float max_grad = 0.0;
779
-
780
- /* check parameters */
781
- if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
782
- error("ll_angle: invalid image.");
783
- if( threshold < 0.0 ) error("ll_angle: 'threshold' must be positive.");
784
- if( list_p == NULL ) error("ll_angle: NULL pointer 'list_p'.");
785
- if( mem_p == NULL ) error("ll_angle: NULL pointer 'mem_p'.");
786
- if( modgrad == NULL ) error("ll_angle: NULL pointer 'modgrad'.");
787
- if( n_bins == 0 ) error("ll_angle: 'n_bins' must be positive.");
788
-
789
- /* image size shortcuts */
790
- n = in->ysize;
791
- p = in->xsize;
792
-
793
- /* allocate output image */
794
- g = new_image_double(in->xsize,in->ysize);
795
-
796
- /* get memory for the image of gradient modulus */
797
- *modgrad = new_image_double(in->xsize,in->ysize);
798
-
799
- /* get memory for "ordered" list of pixels */
800
- list = (struct coorlist *) calloc( (size_t) (n*p), sizeof(struct coorlist) );
801
- *mem_p = (void *) list;
802
- range_l_s = (struct coorlist **) calloc( (size_t) n_bins,
803
- sizeof(struct coorlist *) );
804
- range_l_e = (struct coorlist **) calloc( (size_t) n_bins,
805
- sizeof(struct coorlist *) );
806
- if( list == NULL || range_l_s == NULL || range_l_e == NULL )
807
- error("not enough memory.");
808
- for(i=0;i<n_bins;i++) range_l_s[i] = range_l_e[i] = NULL;
809
-
810
- /* 'undefined' on the down and right boundaries */
811
- for(x=0;x<p;x++) g->data[(n-1)*p+x] = NOTDEF;
812
- for(y=0;y<n;y++) g->data[p*y+p-1] = NOTDEF;
813
-
814
- /* compute gradient on the remaining pixels */
815
- for(x=0;x<p-1;x++)
816
- for(y=0;y<n-1;y++)
817
- {
818
- adr = y*p+x;
819
-
820
- /*
821
- Norm 2 computation using 2x2 pixel window:
822
- A B
823
- C D
824
- and
825
- com1 = D-A, com2 = B-C.
826
- Then
827
- gx = B+D - (A+C) horizontal difference
828
- gy = C+D - (A+B) vertical difference
829
- com1 and com2 are just to avoid 2 additions.
830
- */
831
- // fprintf(stderr, "pixelvalue %d: %f\n", adr, in->data[adr]);
832
- com1 = in->data[adr+p+1] - in->data[adr];
833
- com2 = in->data[adr+1] - in->data[adr+p];
834
-
835
- gx = com1+com2; /* gradient x component */
836
- gy = com1-com2; /* gradient y component */
837
- norm2 = gx*gx+gy*gy;
838
- norm = sqrt( norm2 / 4.0 ); /* gradient norm */
839
-
840
- (*modgrad)->data[adr] = norm; /* store gradient norm */
841
-
842
- if( norm <= threshold ) /* norm too small, gradient no defined */
843
- g->data[adr] = NOTDEF; /* gradient angle not defined */
844
- else
845
- {
846
- /* gradient angle computation */
847
- g->data[adr] = atan2(gx,-gy);
848
-
849
- /* look for the maximum of the gradient */
850
- if( norm > max_grad ) max_grad = norm;
851
- }
852
- }
853
-
854
- /* compute histogram of gradient values */
855
- for(x=0;x<p-1;x++)
856
- for(y=0;y<n-1;y++)
857
- {
858
- norm = (*modgrad)->data[y*p+x];
859
-
860
- /* store the point in the right bin according to its norm */
861
- i = (unsigned int) (norm * (float) n_bins / max_grad);
862
- if( i >= n_bins ) i = n_bins-1;
863
- if( range_l_e[i] == NULL )
864
- range_l_s[i] = range_l_e[i] = list+list_count++;
865
- else
866
- {
867
- range_l_e[i]->next = list+list_count;
868
- range_l_e[i] = list+list_count++;
869
- }
870
- range_l_e[i]->x = (int) x;
871
- range_l_e[i]->y = (int) y;
872
- range_l_e[i]->next = NULL;
873
- }
874
-
875
- /* Make the list of pixels (almost) ordered by norm value.
876
- It starts by the larger bin, so the list starts by the
877
- pixels with the highest gradient value. Pixels would be ordered
878
- by norm value, up to a precision given by max_grad/n_bins.
879
- */
880
- for(i=n_bins-1; i>0 && range_l_s[i]==NULL; i--);
881
- start = range_l_s[i];
882
- end = range_l_e[i];
883
- if( start != NULL )
884
- while(i>0)
885
- {
886
- --i;
887
- if( range_l_s[i] != NULL )
888
- {
889
- end->next = range_l_s[i];
890
- end = range_l_e[i];
891
- }
892
- }
893
- *list_p = start;
894
-
895
- /* free memory */
896
- free( (void *) range_l_s );
897
- free( (void *) range_l_e );
898
-
899
- return g;
900
- }
901
-
902
- /*----------------------------------------------------------------------------*/
903
- /** Is point (x,y) aligned to angle theta, up to precision 'prec'?
904
- */
905
- static int isaligned( int x, int y, image_double angles, float theta,
906
- float prec )
907
- {
908
- float a;
909
-
910
- /* check parameters */
911
- if( angles == NULL || angles->data == NULL )
912
- error("isaligned: invalid image 'angles'.");
913
- if( x < 0 || y < 0 || x >= (int) angles->xsize || y >= (int) angles->ysize )
914
- error("isaligned: (x,y) out of the image.");
915
- if( prec < 0.0 ) error("isaligned: 'prec' must be positive.");
916
-
917
- /* angle at pixel (x,y) */
918
- a = angles->data[ x + y * angles->xsize ];
919
-
920
- /* pixels whose level-line angle is not defined
921
- are considered as NON-aligned */
922
- if( a == NOTDEF ) return FALSE; /* there is no need to call the function
923
- 'double_equal' here because there is
924
- no risk of problems related to the
925
- comparison doubles, we are only
926
- interested in the exact NOTDEF value */
927
-
928
- /* it is assumed that 'theta' and 'a' are in the range [-pi,pi] */
929
- theta -= a;
930
- if( theta < 0.0 ) theta = -theta;
931
- if( theta > M_3_2_PI )
932
- {
933
- theta -= M_2__PI;
934
- if( theta < 0.0 ) theta = -theta;
935
- }
936
-
937
- return theta <= prec;
938
- }
939
-
940
- /*----------------------------------------------------------------------------*/
941
- /** Absolute value angle difference.
942
- */
943
- static double angle_diff(float a, float b)
944
- {
945
- a -= b;
946
- while( a <= -M_PI ) a += M_2__PI;
947
- while( a > M_PI ) a -= M_2__PI;
948
- if( a < 0.0 ) a = -a;
949
- return a;
950
- }
951
-
952
- /*----------------------------------------------------------------------------*/
953
- /** Signed angle difference.
954
- */
955
- static double angle_diff_signed(float a, float b)
956
- {
957
- a -= b;
958
- while( a <= -M_PI ) a += M_2__PI;
959
- while( a > M_PI ) a -= M_2__PI;
960
- return a;
961
- }
962
-
963
-
964
- /*----------------------------------------------------------------------------*/
965
- /*----------------------------- NFA computation ------------------------------*/
966
- /*----------------------------------------------------------------------------*/
967
-
968
- /*----------------------------------------------------------------------------*/
969
- /** Computes the natural logarithm of the absolute value of
970
- the gamma function of x using the Lanczos approximation.
971
- See http://www.rskey.org/gamma.htm
972
-
973
- The formula used is
974
- @f[
975
- \Gamma(x) = \frac{ \sum_{n=0}^{N} q_n x^n }{ \Pi_{n=0}^{N} (x+n) }
976
- (x+5.5)^{x+0.5} e^{-(x+5.5)}
977
- @f]
978
- so
979
- @f[
980
- \log\Gamma(x) = \log\left( \sum_{n=0}^{N} q_n x^n \right)
981
- + (x+0.5) \log(x+5.5) - (x+5.5) - \sum_{n=0}^{N} \log(x+n)
982
- @f]
983
- and
984
- q0 = 75122.6331530,
985
- q1 = 80916.6278952,
986
- q2 = 36308.2951477,
987
- q3 = 8687.24529705,
988
- q4 = 1168.92649479,
989
- q5 = 83.8676043424,
990
- q6 = 2.50662827511.
991
- */
992
- static double log_gamma_lanczos(float x)
993
- {
994
- static float q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
995
- 8687.24529705, 1168.92649479, 83.8676043424,
996
- 2.50662827511 };
997
- float a = (x+0.5) * log(x+5.5) - (x+5.5);
998
- float b = 0.0;
999
- int n;
1000
-
1001
- for(n=0;n<7;n++)
1002
- {
1003
- a -= log( x + (float) n );
1004
- b += q[n] * pow( x, (float) n );
1005
- }
1006
- return a + log(b);
1007
- }
1008
-
1009
- /*----------------------------------------------------------------------------*/
1010
- /** Computes the natural logarithm of the absolute value of
1011
- the gamma function of x using Windschitl method.
1012
- See http://www.rskey.org/gamma.htm
1013
-
1014
- The formula used is
1015
- @f[
1016
- \Gamma(x) = \sqrt{\frac{2\pi}{x}} \left( \frac{x}{e}
1017
- \sqrt{ x\sinh(1/x) + \frac{1}{810x^6} } \right)^x
1018
- @f]
1019
- so
1020
- @f[
1021
- \log\Gamma(x) = 0.5\log(2\pi) + (x-0.5)\log(x) - x
1022
- + 0.5x\log\left( x\sinh(1/x) + \frac{1}{810x^6} \right).
1023
- @f]
1024
- This formula is a good approximation when x > 15.
1025
- */
1026
- static double log_gamma_windschitl(float x)
1027
- {
1028
- return 0.918938533204673 + (x-0.5)*log(x) - x
1029
- + 0.5*x*log( x*sinh(1/x) + 1/(810.0*pow(x,6.0)) );
1030
- }
1031
-
1032
- /*----------------------------------------------------------------------------*/
1033
- /** Computes the natural logarithm of the absolute value of
1034
- the gamma function of x. When x>15 use log_gamma_windschitl(),
1035
- otherwise use log_gamma_lanczos().
1036
- */
1037
- #define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
1038
-
1039
- /*----------------------------------------------------------------------------*/
1040
- /** Size of the table to store already computed inverse values.
1041
- */
1042
- #define TABSIZE 100000
1043
-
1044
- /*----------------------------------------------------------------------------*/
1045
- /** Computes -log10(NFA).
1046
-
1047
- NFA stands for Number of False Alarms:
1048
- @f[
1049
- \mathrm{NFA} = NT \cdot B(n,k,p)
1050
- @f]
1051
-
1052
- - NT - number of tests
1053
- - B(n,k,p) - tail of binomial distribution with parameters n,k and p:
1054
- @f[
1055
- B(n,k,p) = \sum_{j=k}^n
1056
- \left(\begin{array}{c}n\\j\end{array}\right)
1057
- p^{j} (1-p)^{n-j}
1058
- @f]
1059
-
1060
- The value -log10(NFA) is equivalent but more intuitive than NFA:
1061
- - -1 corresponds to 10 mean false alarms
1062
- - 0 corresponds to 1 mean false alarm
1063
- - 1 corresponds to 0.1 mean false alarms
1064
- - 2 corresponds to 0.01 mean false alarms
1065
- - ...
1066
-
1067
- Used this way, the bigger the value, better the detection,
1068
- and a logarithmic scale is used.
1069
-
1070
- @param n,k,p binomial parameters.
1071
- @param logNT logarithm of Number of Tests
1072
-
1073
- The computation is based in the gamma function by the following
1074
- relation:
1075
- @f[
1076
- \left(\begin{array}{c}n\\k\end{array}\right)
1077
- = \frac{ \Gamma(n+1) }{ \Gamma(k+1) \cdot \Gamma(n-k+1) }.
1078
- @f]
1079
- We use efficient algorithms to compute the logarithm of
1080
- the gamma function.
1081
-
1082
- To make the computation faster, not all the sum is computed, part
1083
- of the terms are neglected based on a bound to the error obtained
1084
- (an error of 10% in the result is accepted).
1085
- */
1086
- static double nfa(int n, int k, float p, float logNT)
1087
- {
1088
- static float inv[TABSIZE]; /* table to keep computed inverse values */
1089
- float tolerance = 0.1; /* an error of 10% in the result is accepted */
1090
- float log1term,term,bin_term,mult_term,bin_tail,err,p_term;
1091
- int i;
1092
-
1093
- /* check parameters */
1094
- if( n<0 || k<0 || k>n || p<=0.0 || p>=1.0 )
1095
- error("nfa: wrong n, k or p values.");
1096
-
1097
- /* trivial cases */
1098
- if( n==0 || k==0 ) return -logNT;
1099
- if( n==k ) return -logNT - (float) n * log10(p);
1100
-
1101
- /* probability term */
1102
- p_term = p / (1.0-p);
1103
-
1104
- /* compute the first term of the series */
1105
- /*
1106
- binomial_tail(n,k,p) = sum_{i=k}^n bincoef(n,i) * p^i * (1-p)^{n-i}
1107
- where bincoef(n,i) are the binomial coefficients.
1108
- But
1109
- bincoef(n,k) = gamma(n+1) / ( gamma(k+1) * gamma(n-k+1) ).
1110
- We use this to compute the first term. Actually the log of it.
1111
- */
1112
- log1term = log_gamma( (float) n + 1.0 ) - log_gamma( (float) k + 1.0 )
1113
- - log_gamma( (float) (n-k) + 1.0 )
1114
- + (float) k * log(p) + (float) (n-k) * log(1.0-p);
1115
- term = exp(log1term);
1116
-
1117
- /* in some cases no more computations are needed */
1118
- if( double_equal(term,0.0) ) /* the first term is almost zero */
1119
- {
1120
- if( (float) k > (float) n * p ) /* at begin or end of the tail? */
1121
- return -log1term / M_LN10 - logNT; /* end: use just the first term */
1122
- else
1123
- return -logNT; /* begin: the tail is roughly 1 */
1124
- }
1125
-
1126
- /* compute more terms if needed */
1127
- bin_tail = term;
1128
- for(i=k+1;i<=n;i++)
1129
- {
1130
- /*
1131
- As
1132
- term_i = bincoef(n,i) * p^i * (1-p)^(n-i)
1133
- and
1134
- bincoef(n,i)/bincoef(n,i-1) = n-1+1 / i,
1135
- then,
1136
- term_i / term_i-1 = (n-i+1)/i * p/(1-p)
1137
- and
1138
- term_i = term_i-1 * (n-i+1)/i * p/(1-p).
1139
- 1/i is stored in a table as they are computed,
1140
- because divisions are expensive.
1141
- p/(1-p) is computed only once and stored in 'p_term'.
1142
- */
1143
- bin_term = (float) (n-i+1) * ( i<TABSIZE ?
1144
- ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (float) i ) ) :
1145
- 1.0 / (float) i );
1146
-
1147
- mult_term = bin_term * p_term;
1148
- term *= mult_term;
1149
- bin_tail += term;
1150
- if(bin_term<1.0)
1151
- {
1152
- /* When bin_term<1 then mult_term_j<mult_term_i for j>i.
1153
- Then, the error on the binomial tail when truncated at
1154
- the i term can be bounded by a geometric series of form
1155
- term_i * sum mult_term_i^j. */
1156
- err = term * ( ( 1.0 - pow( mult_term, (float) (n-i+1) ) ) /
1157
- (1.0-mult_term) - 1.0 );
1158
-
1159
- /* One wants an error at most of tolerance*final_result, or:
1160
- tolerance * abs(-log10(bin_tail)-logNT).
1161
- Now, the error that can be accepted on bin_tail is
1162
- given by tolerance*final_result divided by the derivative
1163
- of -log10(x) when x=bin_tail. that is:
1164
- tolerance * abs(-log10(bin_tail)-logNT) / (1/bin_tail)
1165
- Finally, we truncate the tail if the error is less than:
1166
- tolerance * abs(-log10(bin_tail)-logNT) * bin_tail */
1167
- if( err < tolerance * fabs(-log10(bin_tail)-logNT) * bin_tail ) break;
1168
- }
1169
- }
1170
- return -log10(bin_tail) - logNT;
1171
- }
1172
-
1173
-
1174
- /*----------------------------------------------------------------------------*/
1175
- /*--------------------------- Rectangle structure ----------------------------*/
1176
- /*----------------------------------------------------------------------------*/
1177
-
1178
- /*----------------------------------------------------------------------------*/
1179
- /** Rectangle structure: line segment with width.
1180
- */
1181
- struct rect
1182
- {
1183
- float x1,y1,x2,y2; /* first and second point of the line segment */
1184
- float width; /* rectangle width */
1185
- float x,y; /* center of the rectangle */
1186
- float theta; /* angle */
1187
- float dx,dy; /* (dx,dy) is vector oriented as the line segment */
1188
- float prec; /* tolerance angle */
1189
- float p; /* probability of a point with angle within 'prec' */
1190
- };
1191
-
1192
- /*----------------------------------------------------------------------------*/
1193
- /** Copy one rectangle structure to another.
1194
- */
1195
- static void rect_copy(struct rect * in, struct rect * out)
1196
- {
1197
- /* check parameters */
1198
- if( in == NULL || out == NULL ) error("rect_copy: invalid 'in' or 'out'.");
1199
-
1200
- /* copy values */
1201
- out->x1 = in->x1;
1202
- out->y1 = in->y1;
1203
- out->x2 = in->x2;
1204
- out->y2 = in->y2;
1205
- out->width = in->width;
1206
- out->x = in->x;
1207
- out->y = in->y;
1208
- out->theta = in->theta;
1209
- out->dx = in->dx;
1210
- out->dy = in->dy;
1211
- out->prec = in->prec;
1212
- out->p = in->p;
1213
- }
1214
-
1215
- /*----------------------------------------------------------------------------*/
1216
- /** Rectangle points iterator.
1217
-
1218
- The integer coordinates of pixels inside a rectangle are
1219
- iteratively explored. This structure keep track of the process and
1220
- functions ri_ini(), ri_inc(), ri_end(), and ri_del() are used in
1221
- the process. An example of how to use the iterator is as follows:
1222
- \code
1223
-
1224
- struct rect * rec = XXX; // some rectangle
1225
- rect_iter * i;
1226
- for( i=ri_ini(rec); !ri_end(i); ri_inc(i) )
1227
- {
1228
- // your code, using 'i->x' and 'i->y' as coordinates
1229
- }
1230
- ri_del(i); // delete iterator
1231
-
1232
- \endcode
1233
- The pixels are explored 'column' by 'column', where we call
1234
- 'column' a set of pixels with the same x value that are inside the
1235
- rectangle. The following is an schematic representation of a
1236
- rectangle, the 'column' being explored is marked by colons, and
1237
- the current pixel being explored is 'x,y'.
1238
- \verbatim
1239
-
1240
- vx[1],vy[1]
1241
- * *
1242
- * *
1243
- * *
1244
- * ye
1245
- * : *
1246
- vx[0],vy[0] : *
1247
- * : *
1248
- * x,y *
1249
- * : *
1250
- * : vx[2],vy[2]
1251
- * : *
1252
- y ys *
1253
- ^ * *
1254
- | * *
1255
- | * *
1256
- +---> x vx[3],vy[3]
1257
-
1258
- \endverbatim
1259
- The first 'column' to be explored is the one with the smaller x
1260
- value. Each 'column' is explored starting from the pixel of the
1261
- 'column' (inside the rectangle) with the smallest y value.
1262
-
1263
- The four corners of the rectangle are stored in order that rotates
1264
- around the corners at the arrays 'vx[]' and 'vy[]'. The first
1265
- point is always the one with smaller x value.
1266
-
1267
- 'x' and 'y' are the coordinates of the pixel being explored. 'ys'
1268
- and 'ye' are the start and end values of the current column being
1269
- explored. So, 'ys' < 'ye'.
1270
- */
1271
- typedef struct
1272
- {
1273
- float vx[4]; /* rectangle's corner X coordinates in circular order */
1274
- float vy[4]; /* rectangle's corner Y coordinates in circular order */
1275
- float ys,ye; /* start and end Y values of current 'column' */
1276
- int x,y; /* coordinates of currently explored pixel */
1277
- } rect_iter;
1278
-
1279
- /*----------------------------------------------------------------------------*/
1280
- /** Interpolate y value corresponding to 'x' value given, in
1281
- the line 'x1,y1' to 'x2,y2'; if 'x1=x2' return the smaller
1282
- of 'y1' and 'y2'.
1283
-
1284
- The following restrictions are required:
1285
- - x1 <= x2
1286
- - x1 <= x
1287
- - x <= x2
1288
- */
1289
- static double inter_low(float x, float x1, float y1, float x2, float y2)
1290
- {
1291
- /* check parameters */
1292
- if( x1 > x2 || x < x1 || x > x2 )
1293
- error("inter_low: unsuitable input, 'x1>x2' or 'x<x1' or 'x>x2'.");
1294
-
1295
- /* interpolation */
1296
- if( double_equal(x1,x2) && y1<y2 ) return y1;
1297
- if( double_equal(x1,x2) && y1>y2 ) return y2;
1298
- return y1 + (x-x1) * (y2-y1) / (x2-x1);
1299
- }
1300
-
1301
- /*----------------------------------------------------------------------------*/
1302
- /** Interpolate y value corresponding to 'x' value given, in
1303
- the line 'x1,y1' to 'x2,y2'; if 'x1=x2' return the larger
1304
- of 'y1' and 'y2'.
1305
-
1306
- The following restrictions are required:
1307
- - x1 <= x2
1308
- - x1 <= x
1309
- - x <= x2
1310
- */
1311
- static double inter_hi(float x, float x1, float y1, float x2, float y2)
1312
- {
1313
- /* check parameters */
1314
- if( x1 > x2 || x < x1 || x > x2 )
1315
- error("inter_hi: unsuitable input, 'x1>x2' or 'x<x1' or 'x>x2'.");
1316
-
1317
- /* interpolation */
1318
- if( double_equal(x1,x2) && y1<y2 ) return y2;
1319
- if( double_equal(x1,x2) && y1>y2 ) return y1;
1320
- return y1 + (x-x1) * (y2-y1) / (x2-x1);
1321
- }
1322
-
1323
- /*----------------------------------------------------------------------------*/
1324
- /** Free memory used by a rectangle iterator.
1325
- */
1326
- static void ri_del(rect_iter * iter)
1327
- {
1328
- if( iter == NULL ) error("ri_del: NULL iterator.");
1329
- free( (void *) iter );
1330
- }
1331
-
1332
- /*----------------------------------------------------------------------------*/
1333
- /** Check if the iterator finished the full iteration.
1334
-
1335
- See details in \ref rect_iter
1336
- */
1337
- static int ri_end(rect_iter * i)
1338
- {
1339
- /* check input */
1340
- if( i == NULL ) error("ri_end: NULL iterator.");
1341
-
1342
- /* if the current x value is larger than the largest
1343
- x value in the rectangle (vx[2]), we know the full
1344
- exploration of the rectangle is finished. */
1345
- return (float)(i->x) > i->vx[2];
1346
- }
1347
-
1348
- /*----------------------------------------------------------------------------*/
1349
- /** Increment a rectangle iterator.
1350
-
1351
- See details in \ref rect_iter
1352
- */
1353
- static void ri_inc(rect_iter * i)
1354
- {
1355
- /* check input */
1356
- if( i == NULL ) error("ri_inc: NULL iterator.");
1357
-
1358
- /* if not at end of exploration,
1359
- increase y value for next pixel in the 'column' */
1360
- if( !ri_end(i) ) i->y++;
1361
-
1362
- /* if the end of the current 'column' is reached,
1363
- and it is not the end of exploration,
1364
- advance to the next 'column' */
1365
- while( (float) (i->y) > i->ye && !ri_end(i) )
1366
- {
1367
- /* increase x, next 'column' */
1368
- i->x++;
1369
-
1370
- /* if end of exploration, return */
1371
- if( ri_end(i) ) return;
1372
-
1373
- /* update lower y limit (start) for the new 'column'.
1374
-
1375
- We need to interpolate the y value that corresponds to the
1376
- lower side of the rectangle. The first thing is to decide if
1377
- the corresponding side is
1378
-
1379
- vx[0],vy[0] to vx[3],vy[3] or
1380
- vx[3],vy[3] to vx[2],vy[2]
1381
-
1382
- Then, the side is interpolated for the x value of the
1383
- 'column'. But, if the side is vertical (as it could happen if
1384
- the rectangle is vertical and we are dealing with the first
1385
- or last 'columns') then we pick the lower value of the side
1386
- by using 'inter_low'.
1387
- */
1388
- if( (float) i->x < i->vx[3] )
1389
- i->ys = inter_low((float)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
1390
- else
1391
- i->ys = inter_low((float)i->x,i->vx[3],i->vy[3],i->vx[2],i->vy[2]);
1392
-
1393
- /* update upper y limit (end) for the new 'column'.
1394
-
1395
- We need to interpolate the y value that corresponds to the
1396
- upper side of the rectangle. The first thing is to decide if
1397
- the corresponding side is
1398
-
1399
- vx[0],vy[0] to vx[1],vy[1] or
1400
- vx[1],vy[1] to vx[2],vy[2]
1401
-
1402
- Then, the side is interpolated for the x value of the
1403
- 'column'. But, if the side is vertical (as it could happen if
1404
- the rectangle is vertical and we are dealing with the first
1405
- or last 'columns') then we pick the lower value of the side
1406
- by using 'inter_low'.
1407
- */
1408
- if( (float)i->x < i->vx[1] )
1409
- i->ye = inter_hi((float)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
1410
- else
1411
- i->ye = inter_hi((float)i->x,i->vx[1],i->vy[1],i->vx[2],i->vy[2]);
1412
-
1413
- /* new y */
1414
- i->y = (int) ceil(i->ys);
1415
- }
1416
- }
1417
-
1418
- /*----------------------------------------------------------------------------*/
1419
- /** Create and initialize a rectangle iterator.
1420
-
1421
- See details in \ref rect_iter
1422
- */
1423
- static rect_iter * ri_ini(struct rect * r)
1424
- {
1425
- float vx[4],vy[4];
1426
- int n,offset;
1427
- rect_iter * i;
1428
-
1429
- /* check parameters */
1430
- if( r == NULL ) error("ri_ini: invalid rectangle.");
1431
-
1432
- /* get memory */
1433
- i = (rect_iter *) malloc(sizeof(rect_iter));
1434
- if( i == NULL ) error("ri_ini: Not enough memory.");
1435
-
1436
- /* build list of rectangle corners ordered
1437
- in a circular way around the rectangle */
1438
- vx[0] = r->x1 - r->dy * r->width / 2.0;
1439
- vy[0] = r->y1 + r->dx * r->width / 2.0;
1440
- vx[1] = r->x2 - r->dy * r->width / 2.0;
1441
- vy[1] = r->y2 + r->dx * r->width / 2.0;
1442
- vx[2] = r->x2 + r->dy * r->width / 2.0;
1443
- vy[2] = r->y2 - r->dx * r->width / 2.0;
1444
- vx[3] = r->x1 + r->dy * r->width / 2.0;
1445
- vy[3] = r->y1 - r->dx * r->width / 2.0;
1446
-
1447
- /* compute rotation of index of corners needed so that the first
1448
- point has the smaller x.
1449
-
1450
- if one side is vertical, thus two corners have the same smaller x
1451
- value, the one with the largest y value is selected as the first.
1452
- */
1453
- if( r->x1 < r->x2 && r->y1 <= r->y2 ) offset = 0;
1454
- else if( r->x1 >= r->x2 && r->y1 < r->y2 ) offset = 1;
1455
- else if( r->x1 > r->x2 && r->y1 >= r->y2 ) offset = 2;
1456
- else offset = 3;
1457
-
1458
- /* apply rotation of index. */
1459
- for(n=0; n<4; n++)
1460
- {
1461
- i->vx[n] = vx[(offset+n)%4];
1462
- i->vy[n] = vy[(offset+n)%4];
1463
- }
1464
-
1465
- /* Set an initial condition.
1466
-
1467
- The values are set to values that will cause 'ri_inc' (that will
1468
- be called immediately) to initialize correctly the first 'column'
1469
- and compute the limits 'ys' and 'ye'.
1470
-
1471
- 'y' is set to the integer value of vy[0], the starting corner.
1472
-
1473
- 'ys' and 'ye' are set to very small values, so 'ri_inc' will
1474
- notice that it needs to start a new 'column'.
1475
-
1476
- The smallest integer coordinate inside of the rectangle is
1477
- 'ceil(vx[0])'. The current 'x' value is set to that value minus
1478
- one, so 'ri_inc' (that will increase x by one) will advance to
1479
- the first 'column'.
1480
- */
1481
- i->x = (int) ceil(i->vx[0]) - 1;
1482
- i->y = (int) ceil(i->vy[0]);
1483
- i->ys = i->ye = -DBL_MAX;
1484
-
1485
- /* advance to the first pixel */
1486
- ri_inc(i);
1487
-
1488
- return i;
1489
- }
1490
-
1491
- /*----------------------------------------------------------------------------*/
1492
- /** Compute a rectangle's NFA value.
1493
- */
1494
- static float rect_nfa(struct rect * rec, image_double angles, float logNT)
1495
- {
1496
- rect_iter * i;
1497
- int pts = 0;
1498
- int alg = 0;
1499
-
1500
- /* check parameters */
1501
- if( rec == NULL ) error("rect_nfa: invalid rectangle.");
1502
- if( angles == NULL ) error("rect_nfa: invalid 'angles'.");
1503
-
1504
- /* compute the total number of pixels and of aligned points in 'rec' */
1505
- for(i=ri_ini(rec); !ri_end(i); ri_inc(i)) /* rectangle iterator */
1506
- if( i->x >= 0 && i->y >= 0 &&
1507
- i->x < (int) angles->xsize && i->y < (int) angles->ysize )
1508
- {
1509
- ++pts; /* total number of pixels counter */
1510
- if( isaligned(i->x, i->y, angles, rec->theta, rec->prec) )
1511
- ++alg; /* aligned points counter */
1512
- }
1513
- ri_del(i); /* delete iterator */
1514
-
1515
- return nfa(pts,alg,rec->p,logNT); /* compute NFA value */
1516
- }
1517
-
1518
-
1519
- /*----------------------------------------------------------------------------*/
1520
- /*---------------------------------- Regions ---------------------------------*/
1521
- /*----------------------------------------------------------------------------*/
1522
-
1523
- /*----------------------------------------------------------------------------*/
1524
- /** Compute region's angle as the principal inertia axis of the region.
1525
-
1526
- The following is the region inertia matrix A:
1527
- @f[
1528
-
1529
- A = \left(\begin{array}{cc}
1530
- Ixx & Ixy \\
1531
- Ixy & Iyy \\
1532
- \end{array}\right)
1533
-
1534
- @f]
1535
- where
1536
-
1537
- Ixx = sum_i G(i).(y_i - cx)^2
1538
-
1539
- Iyy = sum_i G(i).(x_i - cy)^2
1540
-
1541
- Ixy = - sum_i G(i).(x_i - cx).(y_i - cy)
1542
-
1543
- and
1544
- - G(i) is the gradient norm at pixel i, used as pixel's weight.
1545
- - x_i and y_i are the coordinates of pixel i.
1546
- - cx and cy are the coordinates of the center of th region.
1547
-
1548
- lambda1 and lambda2 are the eigenvalues of matrix A,
1549
- with lambda1 >= lambda2. They are found by solving the
1550
- characteristic polynomial:
1551
-
1552
- det( lambda I - A) = 0
1553
-
1554
- that gives:
1555
-
1556
- lambda1 = ( Ixx + Iyy + sqrt( (Ixx-Iyy)^2 + 4.0*Ixy*Ixy) ) / 2
1557
-
1558
- lambda2 = ( Ixx + Iyy - sqrt( (Ixx-Iyy)^2 + 4.0*Ixy*Ixy) ) / 2
1559
-
1560
- To get the line segment direction we want to get the angle the
1561
- eigenvector associated to the smallest eigenvalue. We have
1562
- to solve for a,b in:
1563
-
1564
- a.Ixx + b.Ixy = a.lambda2
1565
-
1566
- a.Ixy + b.Iyy = b.lambda2
1567
-
1568
- We want the angle theta = atan(b/a). It can be computed with
1569
- any of the two equations:
1570
-
1571
- theta = atan( (lambda2-Ixx) / Ixy )
1572
-
1573
- or
1574
-
1575
- theta = atan( Ixy / (lambda2-Iyy) )
1576
-
1577
- When |Ixx| > |Iyy| we use the first, otherwise the second (just to
1578
- get better numeric precision).
1579
- */
1580
- static float get_theta( struct point * reg, int reg_size, float x, float y,
1581
- image_double modgrad, float reg_angle, float prec )
1582
- {
1583
- float lambda,theta,weight;
1584
- float Ixx = 0.0;
1585
- float Iyy = 0.0;
1586
- float Ixy = 0.0;
1587
- int i;
1588
-
1589
- /* check parameters */
1590
- if( reg == NULL ) error("get_theta: invalid region.");
1591
- if( reg_size <= 1 ) error("get_theta: region size <= 1.");
1592
- if( modgrad == NULL || modgrad->data == NULL )
1593
- error("get_theta: invalid 'modgrad'.");
1594
- if( prec < 0.0 ) error("get_theta: 'prec' must be positive.");
1595
-
1596
- /* compute inertia matrix */
1597
- for(i=0; i<reg_size; i++)
1598
- {
1599
- weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
1600
- Ixx += ( (float) reg[i].y - y ) * ( (float) reg[i].y - y ) * weight;
1601
- Iyy += ( (float) reg[i].x - x ) * ( (float) reg[i].x - x ) * weight;
1602
- Ixy -= ( (float) reg[i].x - x ) * ( (float) reg[i].y - y ) * weight;
1603
- }
1604
- if( double_equal(Ixx,0.0) && double_equal(Iyy,0.0) && double_equal(Ixy,0.0) )
1605
- error("get_theta: null inertia matrix.");
1606
-
1607
- /* compute smallest eigenvalue */
1608
- lambda = 0.5 * ( Ixx + Iyy - sqrt( (Ixx-Iyy)*(Ixx-Iyy) + 4.0*Ixy*Ixy ) );
1609
-
1610
- /* compute angle */
1611
- theta = fabs(Ixx)>fabs(Iyy) ? atan2(lambda-Ixx,Ixy) : atan2(Ixy,lambda-Iyy);
1612
-
1613
- /* The previous procedure doesn't cares about orientation,
1614
- so it could be wrong by 180 degrees. Here is corrected if necessary. */
1615
- if( angle_diff(theta,reg_angle) > prec ) theta += M_PI;
1616
-
1617
- return theta;
1618
- }
1619
-
1620
- /*----------------------------------------------------------------------------*/
1621
- /** Computes a rectangle that covers a region of points.
1622
- */
1623
- static void region2rect( struct point * reg, int reg_size,
1624
- image_double modgrad, float reg_angle,
1625
- float prec, float p, struct rect * rec )
1626
- {
1627
- float x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
1628
- int i;
1629
-
1630
- /* check parameters */
1631
- if( reg == NULL ) error("region2rect: invalid region.");
1632
- if( reg_size <= 1 ) error("region2rect: region size <= 1.");
1633
- if( modgrad == NULL || modgrad->data == NULL )
1634
- error("region2rect: invalid image 'modgrad'.");
1635
- if( rec == NULL ) error("region2rect: invalid 'rec'.");
1636
-
1637
- /* center of the region:
1638
-
1639
- It is computed as the weighted sum of the coordinates
1640
- of all the pixels in the region. The norm of the gradient
1641
- is used as the weight of a pixel. The sum is as follows:
1642
- cx = \sum_i G(i).x_i
1643
- cy = \sum_i G(i).y_i
1644
- where G(i) is the norm of the gradient of pixel i
1645
- and x_i,y_i are its coordinates.
1646
- */
1647
- x = y = sum = 0.0;
1648
- for(i=0; i<reg_size; i++)
1649
- {
1650
- weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
1651
- x += (float) reg[i].x * weight;
1652
- y += (float) reg[i].y * weight;
1653
- sum += weight;
1654
- }
1655
- if( sum <= 0.0 ) error("region2rect: weights sum equal to zero.");
1656
- x /= sum;
1657
- y /= sum;
1658
-
1659
- /* theta */
1660
- theta = get_theta(reg,reg_size,x,y,modgrad,reg_angle,prec);
1661
-
1662
- /* length and width:
1663
-
1664
- 'l' and 'w' are computed as the distance from the center of the
1665
- region to pixel i, projected along the rectangle axis (dx,dy) and
1666
- to the orthogonal axis (-dy,dx), respectively.
1667
-
1668
- The length of the rectangle goes from l_min to l_max, where l_min
1669
- and l_max are the minimum and maximum values of l in the region.
1670
- Analogously, the width is selected from w_min to w_max, where
1671
- w_min and w_max are the minimum and maximum of w for the pixels
1672
- in the region.
1673
- */
1674
- dx = cos(theta);
1675
- dy = sin(theta);
1676
- l_min = l_max = w_min = w_max = 0.0;
1677
- for(i=0; i<reg_size; i++)
1678
- {
1679
- l = ( (float) reg[i].x - x) * dx + ( (float) reg[i].y - y) * dy;
1680
- w = -( (float) reg[i].x - x) * dy + ( (float) reg[i].y - y) * dx;
1681
-
1682
- if( l > l_max ) l_max = l;
1683
- if( l < l_min ) l_min = l;
1684
- if( w > w_max ) w_max = w;
1685
- if( w < w_min ) w_min = w;
1686
- }
1687
-
1688
- /* store values */
1689
- rec->x1 = x + l_min * dx;
1690
- rec->y1 = y + l_min * dy;
1691
- rec->x2 = x + l_max * dx;
1692
- rec->y2 = y + l_max * dy;
1693
- rec->width = w_max - w_min;
1694
- rec->x = x;
1695
- rec->y = y;
1696
- rec->theta = theta;
1697
- rec->dx = dx;
1698
- rec->dy = dy;
1699
- rec->prec = prec;
1700
- rec->p = p;
1701
-
1702
- /* we impose a minimal width of one pixel
1703
-
1704
- A sharp horizontal or vertical step would produce a perfectly
1705
- horizontal or vertical region. The width computed would be
1706
- zero. But that corresponds to a one pixels width transition in
1707
- the image.
1708
- */
1709
- if( rec->width < 1.0 ) rec->width = 1.0;
1710
- }
1711
-
1712
- /*----------------------------------------------------------------------------*/
1713
- /** Build a region of pixels that share the same angle, up to a
1714
- tolerance 'prec', starting at point (x,y).
1715
- */
1716
- static void region_grow( int x, int y, image_double angles, struct point * reg,
1717
- int * reg_size, float * reg_angle, image_char used,
1718
- float prec )
1719
- {
1720
- float sumdx,sumdy;
1721
- int xx,yy,i;
1722
-
1723
- /* check parameters */
1724
- if( x < 0 || y < 0 || x >= (int) angles->xsize || y >= (int) angles->ysize )
1725
- error("region_grow: (x,y) out of the image.");
1726
- if( angles == NULL || angles->data == NULL )
1727
- error("region_grow: invalid image 'angles'.");
1728
- if( reg == NULL ) error("region_grow: invalid 'reg'.");
1729
- if( reg_size == NULL ) error("region_grow: invalid pointer 'reg_size'.");
1730
- if( reg_angle == NULL ) error("region_grow: invalid pointer 'reg_angle'.");
1731
- if( used == NULL || used->data == NULL )
1732
- error("region_grow: invalid image 'used'.");
1733
-
1734
- /* first point of the region */
1735
- *reg_size = 1;
1736
- reg[0].x = x;
1737
- reg[0].y = y;
1738
- *reg_angle = angles->data[x+y*angles->xsize]; /* region's angle */
1739
- sumdx = cos(*reg_angle);
1740
- sumdy = sin(*reg_angle);
1741
- used->data[x+y*used->xsize] = USED;
1742
-
1743
- /* try neighbors as new region points */
1744
- for(i=0; i<*reg_size; i++)
1745
- for(xx=reg[i].x-1; xx<=reg[i].x+1; xx++)
1746
- for(yy=reg[i].y-1; yy<=reg[i].y+1; yy++)
1747
- if( xx>=0 && yy>=0 && xx<(int)used->xsize && yy<(int)used->ysize &&
1748
- used->data[xx+yy*used->xsize] != USED &&
1749
- isaligned(xx,yy,angles,*reg_angle,prec) )
1750
- {
1751
- /* add point */
1752
- used->data[xx+yy*used->xsize] = USED;
1753
- reg[*reg_size].x = xx;
1754
- reg[*reg_size].y = yy;
1755
- ++(*reg_size);
1756
-
1757
- /* update region's angle */
1758
- sumdx += cos( angles->data[xx+yy*angles->xsize] );
1759
- sumdy += sin( angles->data[xx+yy*angles->xsize] );
1760
- *reg_angle = atan2(sumdy,sumdx);
1761
- }
1762
- }
1763
-
1764
- /*----------------------------------------------------------------------------*/
1765
- /** Try some rectangles variations to improve NFA value. Only if the
1766
- rectangle is not meaningful (i.e., log_nfa <= log_eps).
1767
- */
1768
- static float rect_improve( struct rect * rec, image_double angles,
1769
- float logNT, float log_eps )
1770
- {
1771
- struct rect r;
1772
- float log_nfa,log_nfa_new;
1773
- float delta = 0.5;
1774
- float delta_2 = delta / 2.0;
1775
- int n;
1776
-
1777
- log_nfa = rect_nfa(rec,angles,logNT);
1778
-
1779
- if( log_nfa > log_eps ) return log_nfa;
1780
-
1781
- /* try finer precisions */
1782
- rect_copy(rec,&r);
1783
- for(n=0; n<5; n++)
1784
- {
1785
- r.p /= 2.0;
1786
- r.prec = r.p * M_PI;
1787
- log_nfa_new = rect_nfa(&r,angles,logNT);
1788
- if( log_nfa_new > log_nfa )
1789
- {
1790
- log_nfa = log_nfa_new;
1791
- rect_copy(&r,rec);
1792
- }
1793
- }
1794
-
1795
- if( log_nfa > log_eps ) return log_nfa;
1796
-
1797
- /* try to reduce width */
1798
- rect_copy(rec,&r);
1799
- for(n=0; n<5; n++)
1800
- {
1801
- if( (r.width - delta) >= 0.5 )
1802
- {
1803
- r.width -= delta;
1804
- log_nfa_new = rect_nfa(&r,angles,logNT);
1805
- if( log_nfa_new > log_nfa )
1806
- {
1807
- rect_copy(&r,rec);
1808
- log_nfa = log_nfa_new;
1809
- }
1810
- }
1811
- }
1812
-
1813
- if( log_nfa > log_eps ) return log_nfa;
1814
-
1815
- /* try to reduce one side of the rectangle */
1816
- rect_copy(rec,&r);
1817
- for(n=0; n<5; n++)
1818
- {
1819
- if( (r.width - delta) >= 0.5 )
1820
- {
1821
- r.x1 += -r.dy * delta_2;
1822
- r.y1 += r.dx * delta_2;
1823
- r.x2 += -r.dy * delta_2;
1824
- r.y2 += r.dx * delta_2;
1825
- r.width -= delta;
1826
- log_nfa_new = rect_nfa(&r,angles,logNT);
1827
- if( log_nfa_new > log_nfa )
1828
- {
1829
- rect_copy(&r,rec);
1830
- log_nfa = log_nfa_new;
1831
- }
1832
- }
1833
- }
1834
-
1835
- if( log_nfa > log_eps ) return log_nfa;
1836
-
1837
- /* try to reduce the other side of the rectangle */
1838
- rect_copy(rec,&r);
1839
- for(n=0; n<5; n++)
1840
- {
1841
- if( (r.width - delta) >= 0.5 )
1842
- {
1843
- r.x1 -= -r.dy * delta_2;
1844
- r.y1 -= r.dx * delta_2;
1845
- r.x2 -= -r.dy * delta_2;
1846
- r.y2 -= r.dx * delta_2;
1847
- r.width -= delta;
1848
- log_nfa_new = rect_nfa(&r,angles,logNT);
1849
- if( log_nfa_new > log_nfa )
1850
- {
1851
- rect_copy(&r,rec);
1852
- log_nfa = log_nfa_new;
1853
- }
1854
- }
1855
- }
1856
-
1857
- if( log_nfa > log_eps ) return log_nfa;
1858
-
1859
- /* try even finer precisions */
1860
- rect_copy(rec,&r);
1861
- for(n=0; n<5; n++)
1862
- {
1863
- r.p /= 2.0;
1864
- r.prec = r.p * M_PI;
1865
- log_nfa_new = rect_nfa(&r,angles,logNT);
1866
- if( log_nfa_new > log_nfa )
1867
- {
1868
- log_nfa = log_nfa_new;
1869
- rect_copy(&r,rec);
1870
- }
1871
- }
1872
-
1873
- return log_nfa;
1874
- }
1875
-
1876
- /*----------------------------------------------------------------------------*/
1877
- /** Reduce the region size, by elimination the points far from the
1878
- starting point, until that leads to rectangle with the right
1879
- density of region points or to discard the region if too small.
1880
- */
1881
- static int reduce_region_radius( struct point * reg, int * reg_size,
1882
- image_double modgrad, float reg_angle,
1883
- float prec, float p, struct rect * rec,
1884
- image_char used, image_double angles,
1885
- float density_th )
1886
- {
1887
- float density,rad1,rad2,rad,xc,yc;
1888
- int i;
1889
-
1890
- /* check parameters */
1891
- if( reg == NULL ) error("reduce_region_radius: invalid pointer 'reg'.");
1892
- if( reg_size == NULL )
1893
- error("reduce_region_radius: invalid pointer 'reg_size'.");
1894
- if( prec < 0.0 ) error("reduce_region_radius: 'prec' must be positive.");
1895
- if( rec == NULL ) error("reduce_region_radius: invalid pointer 'rec'.");
1896
- if( used == NULL || used->data == NULL )
1897
- error("reduce_region_radius: invalid image 'used'.");
1898
- if( angles == NULL || angles->data == NULL )
1899
- error("reduce_region_radius: invalid image 'angles'.");
1900
-
1901
- /* compute region points density */
1902
- density = (float) *reg_size /
1903
- ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
1904
-
1905
- /* if the density criterion is satisfied there is nothing to do */
1906
- if( density >= density_th ) return TRUE;
1907
-
1908
- /* compute region's radius */
1909
- xc = (float) reg[0].x;
1910
- yc = (float) reg[0].y;
1911
- rad1 = dist( xc, yc, rec->x1, rec->y1 );
1912
- rad2 = dist( xc, yc, rec->x2, rec->y2 );
1913
- rad = rad1 > rad2 ? rad1 : rad2;
1914
-
1915
- /* while the density criterion is not satisfied, remove farther pixels */
1916
- while( density < density_th )
1917
- {
1918
- rad *= 0.75; /* reduce region's radius to 75% of its value */
1919
-
1920
- /* remove points from the region and update 'used' map */
1921
- for(i=0; i<*reg_size; i++)
1922
- if( dist( xc, yc, (float) reg[i].x, (float) reg[i].y ) > rad )
1923
- {
1924
- /* point not kept, mark it as NOTUSED */
1925
- used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
1926
- /* remove point from the region */
1927
- reg[i].x = reg[*reg_size-1].x; /* if i==*reg_size-1 copy itself */
1928
- reg[i].y = reg[*reg_size-1].y;
1929
- --(*reg_size);
1930
- --i; /* to avoid skipping one point */
1931
- }
1932
-
1933
- /* reject if the region is too small.
1934
- 2 is the minimal region size for 'region2rect' to work. */
1935
- if( *reg_size < 2 ) return FALSE;
1936
-
1937
- /* re-compute rectangle */
1938
- region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
1939
-
1940
- /* re-compute region points density */
1941
- density = (float) *reg_size /
1942
- ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
1943
- }
1944
-
1945
- /* if this point is reached, the density criterion is satisfied */
1946
- return TRUE;
1947
- }
1948
-
1949
- /*----------------------------------------------------------------------------*/
1950
- /** Refine a rectangle.
1951
-
1952
- For that, an estimation of the angle tolerance is performed by the
1953
- standard deviation of the angle at points near the region's
1954
- starting point. Then, a new region is grown starting from the same
1955
- point, but using the estimated angle tolerance. If this fails to
1956
- produce a rectangle with the right density of region points,
1957
- 'reduce_region_radius' is called to try to satisfy this condition.
1958
- */
1959
- static int refine( struct point * reg, int * reg_size, image_double modgrad,
1960
- float reg_angle, float prec, float p, struct rect * rec,
1961
- image_char used, image_double angles, float density_th )
1962
- {
1963
- float angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
1964
- int i,n;
1965
-
1966
- /* check parameters */
1967
- if( reg == NULL ) error("refine: invalid pointer 'reg'.");
1968
- if( reg_size == NULL ) error("refine: invalid pointer 'reg_size'.");
1969
- if( prec < 0.0 ) error("refine: 'prec' must be positive.");
1970
- if( rec == NULL ) error("refine: invalid pointer 'rec'.");
1971
- if( used == NULL || used->data == NULL )
1972
- error("refine: invalid image 'used'.");
1973
- if( angles == NULL || angles->data == NULL )
1974
- error("refine: invalid image 'angles'.");
1975
-
1976
- /* compute region points density */
1977
- density = (float) *reg_size /
1978
- ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
1979
-
1980
- /* if the density criterion is satisfied there is nothing to do */
1981
- if( density >= density_th ) return TRUE;
1982
-
1983
- /*------ First try: reduce angle tolerance ------*/
1984
-
1985
- /* compute the new mean angle and tolerance */
1986
- xc = (float) reg[0].x;
1987
- yc = (float) reg[0].y;
1988
- ang_c = angles->data[ reg[0].x + reg[0].y * angles->xsize ];
1989
- sum = s_sum = 0.0;
1990
- n = 0;
1991
- for(i=0; i<*reg_size; i++)
1992
- {
1993
- used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
1994
- if( dist( xc, yc, (float) reg[i].x, (float) reg[i].y ) < rec->width )
1995
- {
1996
- angle = angles->data[ reg[i].x + reg[i].y * angles->xsize ];
1997
- ang_d = angle_diff_signed(angle,ang_c);
1998
- sum += ang_d;
1999
- s_sum += ang_d * ang_d;
2000
- ++n;
2001
- }
2002
- }
2003
- mean_angle = sum / (float) n;
2004
- tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (float) n
2005
- + mean_angle*mean_angle ); /* 2 * standard deviation */
2006
-
2007
- /* find a new region from the same starting point and new angle tolerance */
2008
- region_grow(reg[0].x,reg[0].y,angles,reg,reg_size,&reg_angle,used,tau);
2009
-
2010
- /* if the region is too small, reject */
2011
- if( *reg_size < 2 ) return FALSE;
2012
-
2013
- /* re-compute rectangle */
2014
- region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
2015
-
2016
- /* re-compute region points density */
2017
- density = (float) *reg_size /
2018
- ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
2019
-
2020
- /*------ Second try: reduce region radius ------*/
2021
- if( density < density_th )
2022
- return reduce_region_radius( reg, reg_size, modgrad, reg_angle, prec, p,
2023
- rec, used, angles, density_th );
2024
-
2025
- /* if this point is reached, the density criterion is satisfied */
2026
- return TRUE;
2027
- }
2028
-
2029
-
2030
- /*----------------------------------------------------------------------------*/
2031
- /*-------------------------- Line Segment Detector ---------------------------*/
2032
- /*----------------------------------------------------------------------------*/
2033
-
2034
- /*----------------------------------------------------------------------------*/
2035
- /** LSD full interface.
2036
- */
2037
- float * LineSegmentDetection( int * n_out,
2038
- float * img, int X, int Y,
2039
- float scale, float sigma_scale, float quant,
2040
- float ang_th, float log_eps, float density_th,
2041
- int n_bins,
2042
- int ** reg_img, int * reg_x, int * reg_y )
2043
- {
2044
- image_double image;
2045
- ntuple_list out = new_ntuple_list(7);
2046
- float * return_value;
2047
- image_double scaled_image,angles,modgrad;
2048
- image_char used;
2049
- image_int region = NULL;
2050
- struct coorlist * list_p;
2051
- void * mem_p;
2052
- struct rect rec;
2053
- struct point * reg;
2054
- int reg_size,min_reg_size,i;
2055
- unsigned int xsize,ysize;
2056
- float rho,reg_angle,prec,p,log_nfa,logNT;
2057
- int ls_count = 0; /* line segments are numbered 1,2,3,... */
2058
-
2059
-
2060
- /* check parameters */
2061
- if( img == NULL || X <= 0 || Y <= 0 ) error("invalid image input.");
2062
- if( scale <= 0.0 ) error("'scale' value must be positive.");
2063
- if( sigma_scale <= 0.0 ) error("'sigma_scale' value must be positive.");
2064
- if( quant < 0.0 ) error("'quant' value must be positive.");
2065
- if( ang_th <= 0.0 || ang_th >= 180.0 )
2066
- error("'ang_th' value must be in the range (0,180).");
2067
- if( density_th < 0.0 || density_th > 1.0 )
2068
- error("'density_th' value must be in the range [0,1].");
2069
- if( n_bins <= 0 ) error("'n_bins' value must be positive.");
2070
-
2071
-
2072
- /* angle tolerance */
2073
- prec = M_PI * ang_th / 180.0;
2074
- p = ang_th / 180.0;
2075
- rho = quant / sin(prec); /* gradient magnitude threshold */
2076
-
2077
-
2078
- /* load and scale image (if necessary) and compute angle at each pixel */
2079
- image = new_image_double_ptr( (unsigned int) X, (unsigned int) Y, img );
2080
- if( scale != 1.0 )
2081
- {
2082
- scaled_image = gaussian_sampler( image, scale, sigma_scale );
2083
- angles = ll_angle( scaled_image, rho, &list_p, &mem_p,
2084
- &modgrad, (unsigned int) n_bins );
2085
- free_image_double(scaled_image);
2086
- }
2087
- else
2088
- angles = ll_angle( image, rho, &list_p, &mem_p, &modgrad,
2089
- (unsigned int) n_bins );
2090
- xsize = angles->xsize;
2091
- ysize = angles->ysize;
2092
-
2093
- /* Number of Tests - NT
2094
-
2095
- The theoretical number of tests is Np.(XY)^(5/2)
2096
- where X and Y are number of columns and rows of the image.
2097
- Np corresponds to the number of angle precisions considered.
2098
- As the procedure 'rect_improve' tests 5 times to halve the
2099
- angle precision, and 5 more times after improving other factors,
2100
- 11 different precision values are potentially tested. Thus,
2101
- the number of tests is
2102
- 11 * (X*Y)^(5/2)
2103
- whose logarithm value is
2104
- log10(11) + 5/2 * (log10(X) + log10(Y)).
2105
- */
2106
- logNT = 5.0 * ( log10( (float) xsize ) + log10( (float) ysize ) ) / 2.0
2107
- + log10(11.0);
2108
- min_reg_size = (int) (-logNT/log10(p)); /* minimal number of points in region
2109
- that can give a meaningful event */
2110
-
2111
-
2112
- /* initialize some structures */
2113
- if( reg_img != NULL && reg_x != NULL && reg_y != NULL ) /* save region data */
2114
- region = new_image_int_ini(angles->xsize,angles->ysize,0);
2115
- used = new_image_char_ini(xsize,ysize,NOTUSED);
2116
- reg = (struct point *) calloc( (size_t) (xsize*ysize), sizeof(struct point) );
2117
- if( reg == NULL ) error("not enough memory!");
2118
-
2119
-
2120
- /* search for line segments */
2121
- for(; list_p != NULL; list_p = list_p->next )
2122
- if( used->data[ list_p->x + list_p->y * used->xsize ] == NOTUSED &&
2123
- angles->data[ list_p->x + list_p->y * angles->xsize ] != NOTDEF )
2124
- /* there is no risk of double comparison problems here
2125
- because we are only interested in the exact NOTDEF value */
2126
- {
2127
- /* find the region of connected point and ~equal angle */
2128
- region_grow( list_p->x, list_p->y, angles, reg, &reg_size,
2129
- &reg_angle, used, prec );
2130
-
2131
- /* reject small regions */
2132
- if( reg_size < min_reg_size ) continue;
2133
-
2134
- /* construct rectangular approximation for the region */
2135
- region2rect(reg,reg_size,modgrad,reg_angle,prec,p,&rec);
2136
-
2137
- /* Check if the rectangle exceeds the minimal density of
2138
- region points. If not, try to improve the region.
2139
- The rectangle will be rejected if the final one does
2140
- not fulfill the minimal density condition.
2141
- This is an addition to the original LSD algorithm published in
2142
- "LSD: A Fast Line Segment Detector with a False Detection Control"
2143
- by R. Grompone von Gioi, J. Jakubowicz, J.M. Morel, and G. Randall.
2144
- The original algorithm is obtained with density_th = 0.0.
2145
- */
2146
- if( !refine( reg, &reg_size, modgrad, reg_angle,
2147
- prec, p, &rec, used, angles, density_th ) ) continue;
2148
-
2149
- /* compute NFA value */
2150
- log_nfa = rect_improve(&rec,angles,logNT,log_eps);
2151
- if( log_nfa <= log_eps ) continue;
2152
-
2153
- /* A New Line Segment was found! */
2154
- ++ls_count; /* increase line segment counter */
2155
-
2156
- /*
2157
- The gradient was computed with a 2x2 mask, its value corresponds to
2158
- points with an offset of (0.5,0.5), that should be added to output.
2159
- The coordinates origin is at the center of pixel (0,0).
2160
- */
2161
- rec.x1 += 0.5; rec.y1 += 0.5;
2162
- rec.x2 += 0.5; rec.y2 += 0.5;
2163
-
2164
- /* scale the result values if a subsampling was performed */
2165
- if( scale != 1.0 )
2166
- {
2167
- rec.x1 /= scale; rec.y1 /= scale;
2168
- rec.x2 /= scale; rec.y2 /= scale;
2169
- rec.width /= scale;
2170
- }
2171
-
2172
- /* add line segment found to output */
2173
- add_7tuple( out, rec.x1, rec.y1, rec.x2, rec.y2,
2174
- rec.width, rec.p, log_nfa );
2175
-
2176
- /* add region number to 'region' image if needed */
2177
- if( region != NULL )
2178
- for(i=0; i<reg_size; i++)
2179
- region->data[ reg[i].x + reg[i].y * region->xsize ] = ls_count;
2180
- }
2181
-
2182
-
2183
- /* free memory */
2184
- free( (void *) image ); /* only the double_image structure should be freed,
2185
- the data pointer was provided to this functions
2186
- and should not be destroyed. */
2187
- free_image_double(angles);
2188
- free_image_double(modgrad);
2189
- free_image_char(used);
2190
- free( (void *) reg );
2191
- free( (void *) mem_p );
2192
-
2193
- /* return the result */
2194
- if( reg_img != NULL && reg_x != NULL && reg_y != NULL )
2195
- {
2196
- if( region == NULL ) error("'region' should be a valid image.");
2197
- *reg_img = region->data;
2198
- if( region->xsize > (unsigned int) INT_MAX ||
2199
- region->xsize > (unsigned int) INT_MAX )
2200
- error("region image to big to fit in INT sizes.");
2201
- *reg_x = (int) (region->xsize);
2202
- *reg_y = (int) (region->ysize);
2203
-
2204
- /* free the 'region' structure.
2205
- we cannot use the function 'free_image_int' because we need to keep
2206
- the memory with the image data to be returned by this function. */
2207
- free( (void *) region );
2208
- }
2209
- if( out->size > (unsigned int) INT_MAX )
2210
- error("too many detections to fit in an INT.");
2211
- *n_out = (int) (out->size);
2212
-
2213
- return_value = out->values;
2214
- free( (void *) out ); /* only the 'ntuple_list' structure must be freed,
2215
- but the 'values' pointer must be keep to return
2216
- as a result. */
2217
-
2218
- return return_value;
2219
- }
2220
-
2221
- /*----------------------------------------------------------------------------*/
2222
- /** LSD Simple Interface with Scale and Region output.
2223
- */
2224
- float * lsd_scale_region( int * n_out,
2225
- float * img, int X, int Y, float scale,
2226
- int ** reg_img, int * reg_x, int * reg_y )
2227
- {
2228
- /* LSD parameters */
2229
- float sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
2230
- sigma = sigma_scale/scale. */
2231
- float quant = 2.0; /* Bound to the quantization error on the
2232
- gradient norm. */
2233
- float ang_th = 22.5; /* Gradient angle tolerance in degrees. */
2234
- float log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
2235
- float density_th = 0.7; /* Minimal density of region points in rectangle. */
2236
- int n_bins = 1024; /* Number of bins in pseudo-ordering of gradient
2237
- modulus. */
2238
-
2239
- return LineSegmentDetection( n_out, img, X, Y, scale, sigma_scale, quant,
2240
- ang_th, log_eps, density_th, n_bins,
2241
- reg_img, reg_x, reg_y );
2242
- }
2243
-
2244
- /*----------------------------------------------------------------------------*/
2245
- /** LSD Simple Interface with Scale.
2246
- */
2247
- float * lsd_scale(int * n_out, float * img, int X, int Y, float scale)
2248
- {
2249
- return lsd_scale_region(n_out,img,X,Y,scale,NULL,NULL,NULL);
2250
- }
2251
-
2252
- /*----------------------------------------------------------------------------*/
2253
- /** LSD Simple Interface.
2254
- */
2255
- float * lsd(int * n_out, float * img, int X, int Y)
2256
- {
2257
- /* LSD parameters */
2258
- float scale = 0.8; /* Scale the image by Gaussian filter to 'scale'. */
2259
-
2260
- return lsd_scale(n_out,img,X,Y,scale);
2261
-
2262
-
2263
- }
2264
- /*----------------------------------------------------------------------------*/
2265
-
2266
- /***** added by manuel aristaran ****/
2267
-
2268
- void free_values(float * p) {
2269
- free((void *) p);
2270
- }