tabula-extractor 0.0.1-java → 0.5.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/ext/Makefile.OSX ADDED
@@ -0,0 +1,15 @@
1
+ include Makefile.defaults
2
+
3
+ lib: lib$(NAME).$(VERSION).dylib
4
+
5
+ lib$(NAME).$(VERSION).dylib: $(NAME).o
6
+ $(CC) -dynamiclib -lm -o lib$(NAME).dylib $^
7
+
8
+ clean:
9
+ $(RM) *.o
10
+
11
+ $(NAME)_test: lib$(NAME).$(VERSION).dylib
12
+ $(CC) lsd_call_example.c -o $@ -L. -l$(NAME)
13
+
14
+ test: $(NAME)_test
15
+ LD_LIBRARY_PATH=. ./$(NAME)_test
@@ -0,0 +1,9 @@
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
@@ -0,0 +1,11 @@
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
+
@@ -0,0 +1,12 @@
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
+
@@ -0,0 +1,10 @@
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 $^
Binary file
Binary file
data/ext/liblsd.def ADDED
@@ -0,0 +1,3 @@
1
+ EXPORTS
2
+ lsd
3
+ free_values
data/ext/liblsd.dll ADDED
Binary file
data/ext/liblsd.dylib ADDED
Binary file
data/ext/lsd.c ADDED
@@ -0,0 +1,2270 @@
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(double a, double b)
193
+ {
194
+ double 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 double dist(double x1, double y1, double x2, double 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
+ double * 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 = (double *) malloc( dim*n_tuple->max_size * sizeof(double) );
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 = (double *) realloc( (void *) n_tuple->values,
309
+ n_tuple->dim * n_tuple->max_size * sizeof(double) );
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, double v1, double v2, double v3,
317
+ double v4, double v5, double v6, double 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
+ double * 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 = (double *) calloc( (size_t) (xsize*ysize), sizeof(double) );
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, double * 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, double sigma, double mean)
560
+ {
561
+ double sum = 0.0;
562
+ double 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 = ( (double) 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, double scale,
623
+ double 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
+ double 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 > (double) UINT_MAX ||
640
+ in->ysize * scale > (double) 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 = (double) 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, (double) h + xx - (double) 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 = (double) 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, (double) h + yy - (double) 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, double 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
+ double 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
+ double 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 * (double) 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, double theta,
906
+ double prec )
907
+ {
908
+ double 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(double a, double 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(double a, double 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(double x)
993
+ {
994
+ static double q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
995
+ 8687.24529705, 1168.92649479, 83.8676043424,
996
+ 2.50662827511 };
997
+ double a = (x+0.5) * log(x+5.5) - (x+5.5);
998
+ double b = 0.0;
999
+ int n;
1000
+
1001
+ for(n=0;n<7;n++)
1002
+ {
1003
+ a -= log( x + (double) n );
1004
+ b += q[n] * pow( x, (double) 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(double 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, double p, double logNT)
1087
+ {
1088
+ static double inv[TABSIZE]; /* table to keep computed inverse values */
1089
+ double tolerance = 0.1; /* an error of 10% in the result is accepted */
1090
+ double 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 - (double) 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( (double) n + 1.0 ) - log_gamma( (double) k + 1.0 )
1113
+ - log_gamma( (double) (n-k) + 1.0 )
1114
+ + (double) k * log(p) + (double) (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( (double) k > (double) 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 = (double) (n-i+1) * ( i<TABSIZE ?
1144
+ ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (double) i ) ) :
1145
+ 1.0 / (double) 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, (double) (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
+ double x1,y1,x2,y2; /* first and second point of the line segment */
1184
+ double width; /* rectangle width */
1185
+ double x,y; /* center of the rectangle */
1186
+ double theta; /* angle */
1187
+ double dx,dy; /* (dx,dy) is vector oriented as the line segment */
1188
+ double prec; /* tolerance angle */
1189
+ double 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
+ double vx[4]; /* rectangle's corner X coordinates in circular order */
1274
+ double vy[4]; /* rectangle's corner Y coordinates in circular order */
1275
+ double 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(double x, double x1, double y1, double x2, double 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(double x, double x1, double y1, double x2, double 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 (double)(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( (double) (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( (double) i->x < i->vx[3] )
1389
+ i->ys = inter_low((double)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
1390
+ else
1391
+ i->ys = inter_low((double)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( (double)i->x < i->vx[1] )
1409
+ i->ye = inter_hi((double)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
1410
+ else
1411
+ i->ye = inter_hi((double)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
+ double 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 double rect_nfa(struct rect * rec, image_double angles, double 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 double get_theta( struct point * reg, int reg_size, double x, double y,
1581
+ image_double modgrad, double reg_angle, double prec )
1582
+ {
1583
+ double lambda,theta,weight;
1584
+ double Ixx = 0.0;
1585
+ double Iyy = 0.0;
1586
+ double 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 += ( (double) reg[i].y - y ) * ( (double) reg[i].y - y ) * weight;
1601
+ Iyy += ( (double) reg[i].x - x ) * ( (double) reg[i].x - x ) * weight;
1602
+ Ixy -= ( (double) reg[i].x - x ) * ( (double) 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, double reg_angle,
1625
+ double prec, double p, struct rect * rec )
1626
+ {
1627
+ double 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 += (double) reg[i].x * weight;
1652
+ y += (double) 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 = ( (double) reg[i].x - x) * dx + ( (double) reg[i].y - y) * dy;
1680
+ w = -( (double) reg[i].x - x) * dy + ( (double) 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, double * reg_angle, image_char used,
1718
+ double prec )
1719
+ {
1720
+ double 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 double rect_improve( struct rect * rec, image_double angles,
1769
+ double logNT, double log_eps )
1770
+ {
1771
+ struct rect r;
1772
+ double log_nfa,log_nfa_new;
1773
+ double delta = 0.5;
1774
+ double 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, double reg_angle,
1883
+ double prec, double p, struct rect * rec,
1884
+ image_char used, image_double angles,
1885
+ double density_th )
1886
+ {
1887
+ double 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 = (double) *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 = (double) reg[0].x;
1910
+ yc = (double) 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, (double) reg[i].x, (double) 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 = (double) *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
+ double reg_angle, double prec, double p, struct rect * rec,
1961
+ image_char used, image_double angles, double density_th )
1962
+ {
1963
+ double 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 = (double) *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 = (double) reg[0].x;
1987
+ yc = (double) 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, (double) reg[i].x, (double) 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 / (double) n;
2004
+ tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (double) 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 = (double) *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
+ double * LineSegmentDetection( int * n_out,
2038
+ double * img, int X, int Y,
2039
+ double scale, double sigma_scale, double quant,
2040
+ double ang_th, double log_eps, double 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
+ double * 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
+ double 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( (double) xsize ) + log10( (double) 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
+ double * lsd_scale_region( int * n_out,
2225
+ double * img, int X, int Y, double scale,
2226
+ int ** reg_img, int * reg_x, int * reg_y )
2227
+ {
2228
+ /* LSD parameters */
2229
+ double sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
2230
+ sigma = sigma_scale/scale. */
2231
+ double quant = 2.0; /* Bound to the quantization error on the
2232
+ gradient norm. */
2233
+ double ang_th = 22.5; /* Gradient angle tolerance in degrees. */
2234
+ double log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
2235
+ double 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
+ double * lsd_scale(int * n_out, double * img, int X, int Y, double 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
+ double * lsd(int * n_out, double * img, int X, int Y)
2256
+ {
2257
+ /* LSD parameters */
2258
+ double 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(double * p) {
2269
+ free((void *) p);
2270
+ }