Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
ashift_lsd.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2016-2017 Peter Budai.
4 Copyright (C) 2016 Roman Lebedev.
5 Copyright (C) 2016 Tobias Ellinghaus.
6 Copyright (C) 2016-2017 Ulrich Pegelow.
7 Copyright (C) 2018 Maks Naumov.
8 Copyright (C) 2019 luzpaz.
9 Copyright (C) 2020-2021 Hubert Kowalski.
10 Copyright (C) 2020 Pascal Obry.
11 Copyright (C) 2020 Ralf Brown.
12 Copyright (C) 2022 Martin Bařinka.
13 Copyright (C) 2025 Aurélien PIERRE.
14
15 darktable is free software: you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 darktable 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 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with darktable. If not, see <http://www.gnu.org/licenses/>.
27*/
28
29
30/* For line detection we are using the LSD code as published below.
31 * Changes versus the original code:
32 * do not include "lsd.h" (not needed)
33 * make all interface functions static * comment out unused interface functions
34 * catch (unlikely) division by zero near line 2035
35 * rename rad1 and rad2 to radius1 and radius2 in reduce_region_radius()
36 * to avoid naming conflict in windows build
37 *
38 */
39
40/* TODO: LSD employs intensive sanity checks of input data and allocation
41 * results. In case of errors it will terminate the program. On the one side
42 * this is not optimal for a module within darktable - it should better
43 * report errors upstream where they should be handled properly. On the other
44 * hand the kind of error which could be triggered in LSD would make it very unlikely
45 * that the darktable process could survive anyhow.
46 */
47
48// clang-format off
49
50/*==================================================================================
51 * begin LSD code version 1.6. downloaded on January 30, 2016
52 *==================================================================================*/
53
54/*----------------------------------------------------------------------------
55
56 LSD - Line Segment Detector on digital images
57
58 This code is part of the following publication and was subject
59 to peer review:
60
61 "LSD: a Line Segment Detector" by Rafael Grompone von Gioi,
62 Jeremie Jakubowicz, Jean-Michel Morel, and Gregory Randall,
63 Image Processing On Line, 2012. DOI:10.5201/ipol.2012.gjmr-lsd
64 http://dx.doi.org/10.5201/ipol.2012.gjmr-lsd
65
66 Copyright (c) 2007-2011 rafael grompone von gioi <grompone@gmail.com>
67
68 This program is free software: you can redistribute it and/or modify
69 it under the terms of the GNU Affero General Public License as
70 published by the Free Software Foundation, either version 3 of the
71 License, or (at your option) any later version.
72
73 This program is distributed in the hope that it will be useful,
74 but WITHOUT ANY WARRANTY; without even the implied warranty of
75 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76 GNU Affero General Public License for more details.
77
78 You should have received a copy of the GNU Affero General Public License
79 along with this program. If not, see <http://www.gnu.org/licenses/>.
80
81 ----------------------------------------------------------------------------*/
82
83/*----------------------------------------------------------------------------*/
88/*----------------------------------------------------------------------------*/
89
90/*----------------------------------------------------------------------------*/
148/*----------------------------------------------------------------------------*/
149
150#include "common/darktable.h"
151#include <stdio.h>
152#include <stdlib.h>
153#include <limits.h>
154#include <float.h>
155#include "common/math.h"
156
157#ifndef FALSE
158#define FALSE 0
159#endif /* !FALSE */
160
161#ifndef TRUE
162#define TRUE 1
163#endif /* !TRUE */
164
166#define NOTDEF -1024.0
167
169#define M_3_2_PI 4.71238898038
170
172#define M_2__PI 6.28318530718
173
175#define NOTUSED 0
176
178#define USED 1
179
180/*----------------------------------------------------------------------------*/
184{
185 int x,y;
186 struct coorlist * next;
187};
188
189/*----------------------------------------------------------------------------*/
192struct point {int x,y;};
193
194
195/*----------------------------------------------------------------------------*/
196/*------------------------- Miscellaneous functions --------------------------*/
197/*----------------------------------------------------------------------------*/
198
199/*----------------------------------------------------------------------------*/
202static void error(char * msg)
203{
204 fprintf(stderr,"LSD Error: %s\n",msg);
205 exit(EXIT_FAILURE);
206}
207
208/*----------------------------------------------------------------------------*/
211#define RELATIVE_ERROR_FACTOR 100.0
212
213/*----------------------------------------------------------------------------*/
224static int double_equal(double a, double b)
225{
226 double abs_diff,aa,bb,abs_max;
227
228 /* trivial case */
229 if( a == b ) return TRUE;
230
231 abs_diff = fabs(a-b);
232 aa = fabs(a);
233 bb = fabs(b);
234 abs_max = aa > bb ? aa : bb;
235
236 /* DBL_MIN is the smallest normalized number, thus, the smallest
237 number whose relative error is bounded by DBL_EPSILON. For
238 smaller numbers, the same quantization steps as for DBL_MIN
239 are used. Then, for smaller numbers, a meaningful "relative"
240 error should be computed by dividing the difference by DBL_MIN. */
241 if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
242
243 /* equal if relative error <= factor x eps */
244 return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
245}
246
247/*----------------------------------------------------------------------------*/
250static double dist(double x1, double y1, double x2, double y2)
251{
252 return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
253}
254
255
256/*----------------------------------------------------------------------------*/
257/*----------------------- 'list of n-tuple' data type ------------------------*/
258/*----------------------------------------------------------------------------*/
259
260/*----------------------------------------------------------------------------*/
281typedef struct ntuple_list_s
282{
283 unsigned int size;
284 unsigned int max_size;
285 unsigned int dim;
286 double * values;
288
289/*----------------------------------------------------------------------------*/
293{
294 if( in == NULL || in->values == NULL )
295 error("free_ntuple_list: invalid n-tuple input.");
296 dt_free(in->values);
297 dt_free(in);
298}
299
300/*----------------------------------------------------------------------------*/
304static ntuple_list new_ntuple_list(unsigned int dim)
305{
306 ntuple_list n_tuple;
307
308 /* check parameters */
309 if( dim == 0 ) error("new_ntuple_list: 'dim' must be positive.");
310
311 /* get memory for list structure */
312 n_tuple = (ntuple_list) malloc( sizeof(struct ntuple_list_s) );
313 if( n_tuple == NULL ) error("not enough memory.");
314
315 /* initialize list */
316 n_tuple->size = 0;
317 n_tuple->max_size = 1;
318 n_tuple->dim = dim;
319
320 /* get memory for tuples */
321 n_tuple->values = (double *) malloc(sizeof(double) * dim * n_tuple->max_size);
322 if( n_tuple->values == NULL ) error("not enough memory.");
323
324 return n_tuple;
325}
326
327/*----------------------------------------------------------------------------*/
331{
332 /* check parameters */
333 if( n_tuple == NULL || n_tuple->values == NULL || n_tuple->max_size == 0 )
334 error("enlarge_ntuple_list: invalid n-tuple.");
335
336 /* duplicate number of tuples */
337 n_tuple->max_size *= 2;
338
339 /* realloc memory */
340 n_tuple->values = (double *) realloc( (void *) n_tuple->values,
341 sizeof(double) * n_tuple->dim * n_tuple->max_size );
342 if( n_tuple->values == NULL ) error("not enough memory.");
343}
344
345/*----------------------------------------------------------------------------*/
348static void add_7tuple( ntuple_list out, double v1, double v2, double v3,
349 double v4, double v5, double v6, double v7 )
350{
351 /* check parameters */
352 if( out == NULL ) error("add_7tuple: invalid n-tuple input.");
353 if( out->dim != 7 ) error("add_7tuple: the n-tuple must be a 7-tuple.");
354
355 /* if needed, alloc more tuples to 'out' */
356 if( out->size == out->max_size ) enlarge_ntuple_list(out);
357 if( out->values == NULL ) error("add_7tuple: invalid n-tuple input.");
358
359 /* add new 7-tuple */
360 out->values[ out->size * out->dim + 0 ] = v1;
361 out->values[ out->size * out->dim + 1 ] = v2;
362 out->values[ out->size * out->dim + 2 ] = v3;
363 out->values[ out->size * out->dim + 3 ] = v4;
364 out->values[ out->size * out->dim + 4 ] = v5;
365 out->values[ out->size * out->dim + 5 ] = v6;
366 out->values[ out->size * out->dim + 6 ] = v7;
367
368 /* update number of tuples counter */
369 out->size++;
370}
371
372
373/*----------------------------------------------------------------------------*/
374/*----------------------------- Image Data Types -----------------------------*/
375/*----------------------------------------------------------------------------*/
376
377/*----------------------------------------------------------------------------*/
386typedef struct image_char_s
387{
388 unsigned char * data;
389 unsigned int xsize,ysize;
391
392/*----------------------------------------------------------------------------*/
396{
397 if( i == NULL || i->data == NULL )
398 error("free_image_char: invalid input image.");
399 dt_free(i->data);
400 dt_free(i);
401}
402
403/*----------------------------------------------------------------------------*/
406static image_char new_image_char(unsigned int xsize, unsigned int ysize)
407{
408 image_char image;
409
410 /* check parameters */
411 if( xsize == 0 || ysize == 0 ) error("new_image_char: invalid image size.");
412
413 /* get memory */
414 image = (image_char) malloc( sizeof(struct image_char_s) );
415 if( image == NULL ) error("not enough memory.");
416 image->data = (unsigned char *) calloc( (size_t) (xsize*ysize),
417 sizeof(unsigned char) );
418 if( image->data == NULL ) error("not enough memory.");
419
420 /* set image size */
421 image->xsize = xsize;
422 image->ysize = ysize;
423
424 return image;
425}
426
427/*----------------------------------------------------------------------------*/
431static image_char new_image_char_ini( unsigned int xsize, unsigned int ysize,
432 unsigned char fill_value )
433{
434 image_char image = new_image_char(xsize,ysize); /* create image */
435 unsigned int N = xsize*ysize;
436 unsigned int i;
437
438 /* check parameters */
439 if( image == NULL || image->data == NULL )
440 error("new_image_char_ini: invalid image.");
441
442 /* initialize */
443 for(i=0; i<N; i++) image->data[i] = fill_value;
444
445 return image;
446}
447
448/*----------------------------------------------------------------------------*/
457typedef struct image_int_s
458{
459 int * data;
460 unsigned int xsize,ysize;
462
463/*----------------------------------------------------------------------------*/
466static image_int new_image_int(unsigned int xsize, unsigned int ysize)
467{
468 image_int image;
469
470 /* check parameters */
471 if( xsize == 0 || ysize == 0 ) error("new_image_int: invalid image size.");
472
473 /* get memory */
474 image = (image_int) malloc( sizeof(struct image_int_s) );
475 if( image == NULL ) error("not enough memory.");
476 image->data = (int *) calloc( (size_t) (xsize*ysize), sizeof(int) );
477 if( image->data == NULL ) error("not enough memory.");
478
479 /* set image size */
480 image->xsize = xsize;
481 image->ysize = ysize;
482
483 return image;
484}
485
486/*----------------------------------------------------------------------------*/
490static image_int new_image_int_ini( unsigned int xsize, unsigned int ysize,
491 int fill_value )
492{
493 image_int image = new_image_int(xsize,ysize); /* create image */
494 unsigned int N = xsize*ysize;
495 unsigned int i;
496
497 /* initialize */
498 for(i=0; i<N; i++) image->data[i] = fill_value;
499
500 return image;
501}
502
503/*----------------------------------------------------------------------------*/
512typedef struct image_double_s
513{
514 double * data;
515 unsigned int xsize,ysize;
517
518/*----------------------------------------------------------------------------*/
522{
523 if( i == NULL || i->data == NULL )
524 error("free_image_double: invalid input image.");
525 dt_free(i->data);
526 dt_free(i);
527}
528
529/*----------------------------------------------------------------------------*/
532static image_double new_image_double(unsigned int xsize, unsigned int ysize)
533{
534 image_double image;
535
536 /* check parameters */
537 if( xsize == 0 || ysize == 0 ) error("new_image_double: invalid image size.");
538
539 /* get memory */
540 image = (image_double) malloc( sizeof(struct image_double_s) );
541 if( image == NULL ) error("not enough memory.");
542 image->data = (double *) calloc( (size_t) (xsize*ysize), sizeof(double) );
543 if( image->data == NULL ) error("not enough memory.");
544
545 /* set image size */
546 image->xsize = xsize;
547 image->ysize = ysize;
548
549 return image;
550}
551
552/*----------------------------------------------------------------------------*/
556static image_double new_image_double_ptr( unsigned int xsize,
557 unsigned int ysize, double * data )
558{
559 image_double image;
560
561 /* check parameters */
562 if( xsize == 0 || ysize == 0 )
563 error("new_image_double_ptr: invalid image size.");
564 if( data == NULL ) error("new_image_double_ptr: NULL data pointer.");
565
566 /* get memory */
567 image = (image_double) malloc( sizeof(struct image_double_s) );
568 if( image == NULL ) error("not enough memory.");
569
570 /* set image */
571 image->xsize = xsize;
572 image->ysize = ysize;
573 image->data = data;
574
575 return image;
576}
577
578
579/*----------------------------------------------------------------------------*/
580/*----------------------------- Gaussian filter ------------------------------*/
581/*----------------------------------------------------------------------------*/
582
583/*----------------------------------------------------------------------------*/
591static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
592{
593 double sum = 0.0;
594 double val;
595 unsigned int i;
596
597 /* check parameters */
598 if( kernel == NULL || kernel->values == NULL )
599 error("gaussian_kernel: invalid n-tuple 'kernel'.");
600 if( sigma <= 0.0 ) error("gaussian_kernel: 'sigma' must be positive.");
601
602 /* compute Gaussian kernel */
603 if( kernel->max_size < 1 ) enlarge_ntuple_list(kernel);
604 kernel->size = 1;
605 for(i=0;i<kernel->dim;i++)
606 {
607 val = ( (double) i - mean ) / sigma;
608 kernel->values[i] = exp( -0.5 * val * val );
609 sum += kernel->values[i];
610 }
611
612 /* normalization */
613 if( sum >= 0.0 ) for(i=0;i<kernel->dim;i++) kernel->values[i] /= sum;
614}
615
616/*----------------------------------------------------------------------------*/
655 double sigma_scale )
656{
657 image_double aux,out;
659 unsigned int N,M,h,n,x,y,i;
660 int xc,yc,j,double_x_size,double_y_size;
661 double sigma,xx,yy,sum,prec;
662
663 /* check parameters */
664 if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
665 error("gaussian_sampler: invalid image.");
666 if( scale <= 0.0 ) error("gaussian_sampler: 'scale' must be positive.");
667 if( sigma_scale <= 0.0 )
668 error("gaussian_sampler: 'sigma_scale' must be positive.");
669
670 /* compute new image size and get memory for images */
671 if( in->xsize * scale > (double) UINT_MAX ||
672 in->ysize * scale > (double) UINT_MAX )
673 error("gaussian_sampler: the output image size exceeds the handled size.");
674 N = (unsigned int) ceil( in->xsize * scale );
675 M = (unsigned int) ceil( in->ysize * scale );
676 aux = new_image_double(N,in->ysize);
678
679 /* sigma, kernel size and memory for the kernel */
680 sigma = scale < 1.0 ? sigma_scale / scale : sigma_scale;
681 /*
682 The size of the kernel is selected to guarantee that the
683 the first discarded term is at least 10^prec times smaller
684 than the central value. For that, h should be larger than x, with
685 e^(-x^2/2sigma^2) = 1/10^prec.
686 Then,
687 x = sigma * sqrt( 2 * prec * ln(10) ).
688 */
689 prec = 3.0;
690 h = (unsigned int) ceil( sigma * sqrt( 2.0 * prec * log(10.0) ) );
691 n = 1+2*h; /* kernel size */
693
694 /* auxiliary double image size variables */
695 double_x_size = (int) (2 * in->xsize);
696 double_y_size = (int) (2 * in->ysize);
697
698 /* First subsampling: x axis */
699 for(x=0;x<aux->xsize;x++)
700 {
701 /*
702 x is the coordinate in the new image.
703 xx is the corresponding x-value in the original size image.
704 xc is the integer value, the pixel coordinate of xx.
705 */
706 xx = (double) x / scale;
707 /* coordinate (0.0,0.0) is in the center of pixel (0,0),
708 so the pixel with xc=0 get the values of xx from -0.5 to 0.5 */
709 xc = (int) floor( xx + 0.5 );
710 gaussian_kernel( kernel, sigma, (double) h + xx - (double) xc );
711 /* the kernel must be computed for each x because the fine
712 offset xx-xc is different in each case */
713
714 for(y=0;y<aux->ysize;y++)
715 {
716 sum = 0.0;
717 for(i=0;i<kernel->dim;i++)
718 {
719 j = xc - h + i;
720
721 /* symmetry boundary condition */
722 while( j < 0 ) j += double_x_size;
723 while( j >= double_x_size ) j -= double_x_size;
724 if( j >= (int) in->xsize ) j = double_x_size-1-j;
725
726 sum += in->data[ j + y * in->xsize ] * kernel->values[i];
727 }
728 aux->data[ x + y * aux->xsize ] = sum;
729 }
730 }
731
732 /* Second subsampling: y axis */
733 for(y=0;y<out->ysize;y++)
734 {
735 /*
736 y is the coordinate in the new image.
737 yy is the corresponding x-value in the original size image.
738 yc is the integer value, the pixel coordinate of xx.
739 */
740 yy = (double) y / scale;
741 /* coordinate (0.0,0.0) is in the center of pixel (0,0),
742 so the pixel with yc=0 get the values of yy from -0.5 to 0.5 */
743 yc = (int) floor( yy + 0.5 );
744 gaussian_kernel( kernel, sigma, (double) h + yy - (double) yc );
745 /* the kernel must be computed for each y because the fine
746 offset yy-yc is different in each case */
747
748 for(x=0;x<out->xsize;x++)
749 {
750 sum = 0.0;
751 for(i=0;i<kernel->dim;i++)
752 {
753 j = yc - h + i;
754
755 /* symmetry boundary condition */
756 while( j < 0 ) j += double_y_size;
757 while( j >= double_y_size ) j -= double_y_size;
758 if( j >= (int) in->ysize ) j = double_y_size-1-j;
759
760 sum += aux->data[ x + j * aux->xsize ] * kernel->values[i];
761 }
762 out->data[ x + y * out->xsize ] = sum;
763 }
764 }
765
766 /* free memory */
769
770 return out;
771}
772
773
774/*----------------------------------------------------------------------------*/
775/*--------------------------------- Gradient ---------------------------------*/
776/*----------------------------------------------------------------------------*/
777
778/*----------------------------------------------------------------------------*/
796 struct coorlist ** list_p, void ** mem_p,
797 image_double * modgrad, unsigned int n_bins )
798{
800 unsigned int n,p,x,y,adr,i;
801 double com1,com2,gx,gy,norm,norm2;
802 /* the rest of the variables are used for pseudo-ordering
803 the gradient magnitude values */
804 int list_count = 0;
805 struct coorlist * list;
806 struct coorlist ** range_l_s; /* array of pointers to start of bin list */
807 struct coorlist ** range_l_e; /* array of pointers to end of bin list */
808 struct coorlist * start;
809 struct coorlist * end;
810 double max_grad = 0.0;
811
812 /* check parameters */
813 if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
814 error("ll_angle: invalid image.");
815 if( threshold < 0.0 ) error("ll_angle: 'threshold' must be positive.");
816 if( list_p == NULL ) error("ll_angle: NULL pointer 'list_p'.");
817 if( mem_p == NULL ) error("ll_angle: NULL pointer 'mem_p'.");
818 if( modgrad == NULL ) error("ll_angle: NULL pointer 'modgrad'.");
819 if( n_bins == 0 ) error("ll_angle: 'n_bins' must be positive.");
820
821 /* image size shortcuts */
822 n = in->ysize;
823 p = in->xsize;
824
825 /* allocate output image */
826 g = new_image_double(in->xsize,in->ysize);
827
828 /* get memory for the image of gradient modulus */
829 *modgrad = new_image_double(in->xsize,in->ysize);
830
831 /* get memory for "ordered" list of pixels */
832 list = (struct coorlist *) calloc( (size_t) (n*p), sizeof(struct coorlist) );
833 *mem_p = (void *) list;
834 range_l_s = (struct coorlist **) calloc( (size_t) n_bins,
835 sizeof(struct coorlist *) );
836 range_l_e = (struct coorlist **) calloc( (size_t) n_bins,
837 sizeof(struct coorlist *) );
838 if( list == NULL || range_l_s == NULL || range_l_e == NULL )
839 error("not enough memory.");
840 for(i=0;i<n_bins;i++) range_l_s[i] = range_l_e[i] = NULL;
841
842 /* 'undefined' on the down and right boundaries */
843 for(x=0;x<p;x++) g->data[(n-1)*p+x] = NOTDEF;
844 for(y=0;y<n;y++) g->data[p*y+p-1] = NOTDEF;
845
846 /* compute gradient on the remaining pixels */
847 for(x=0;x<p-1;x++)
848 for(y=0;y<n-1;y++)
849 {
850 adr = y*p+x;
851
852 /*
853 Norm 2 computation using 2x2 pixel window:
854 A B
855 C D
856 and
857 com1 = D-A, com2 = B-C.
858 Then
859 gx = B+D - (A+C) horizontal difference
860 gy = C+D - (A+B) vertical difference
861 com1 and com2 are just to avoid 2 additions.
862 */
863 com1 = in->data[adr+p+1] - in->data[adr];
864 com2 = in->data[adr+1] - in->data[adr+p];
865
866 gx = com1+com2; /* gradient x component */
867 gy = com1-com2; /* gradient y component */
868 norm2 = gx*gx+gy*gy;
869 norm = sqrt( norm2 / 4.0 ); /* gradient norm */
870
871 (*modgrad)->data[adr] = norm; /* store gradient norm */
872
873 if( norm <= threshold ) /* norm too small, gradient no defined */
874 g->data[adr] = NOTDEF; /* gradient angle not defined */
875 else
876 {
877 /* gradient angle computation */
878 g->data[adr] = atan2(gx,-gy);
879
880 /* look for the maximum of the gradient */
881 if( norm > max_grad ) max_grad = norm;
882 }
883 }
884
885 /* compute histogram of gradient values */
886 for(x=0;x<p-1;x++)
887 for(y=0;y<n-1;y++)
888 {
889 norm = (*modgrad)->data[y*p+x];
890
891 /* store the point in the right bin according to its norm */
892 i = (unsigned int) (norm * (double) n_bins / max_grad);
893 if( i >= n_bins ) i = n_bins-1;
894 if( range_l_e[i] == NULL )
895 range_l_s[i] = range_l_e[i] = list+list_count++;
896 else
897 {
898 range_l_e[i]->next = list+list_count;
899 range_l_e[i] = list+list_count++;
900 }
901 range_l_e[i]->x = (int) x;
902 range_l_e[i]->y = (int) y;
903 range_l_e[i]->next = NULL;
904 }
905
906 /* Make the list of pixels (almost) ordered by norm value.
907 It starts by the larger bin, so the list starts by the
908 pixels with the highest gradient value. Pixels would be ordered
909 by norm value, up to a precision given by max_grad/n_bins.
910 */
911 for(i=n_bins-1; i>0 && range_l_s[i]==NULL; i--);
912 start = range_l_s[i];
913 end = range_l_e[i];
914 if( start != NULL )
915 while(i>0)
916 {
917 --i;
918 if( range_l_s[i] != NULL )
919 {
920 end->next = range_l_s[i];
921 end = range_l_e[i];
922 }
923 }
924 *list_p = start;
925
926 /* free memory */
929
930 return g;
931}
932
933/*----------------------------------------------------------------------------*/
936static int isaligned( int x, int y, image_double angles, double theta,
937 double prec )
938{
939 double a;
940
941 /* check parameters */
942 if( angles == NULL || angles->data == NULL )
943 error("isaligned: invalid image 'angles'.");
944 if( x < 0 || y < 0 || x >= (int) angles->xsize || y >= (int) angles->ysize )
945 error("isaligned: (x,y) out of the image.");
946 if( prec < 0.0 ) error("isaligned: 'prec' must be positive.");
947
948 /* angle at pixel (x,y) */
949 a = angles->data[ x + y * angles->xsize ];
950
951 /* pixels whose level-line angle is not defined
952 are considered as NON-aligned */
953 if( a == NOTDEF ) return FALSE; /* there is no need to call the function
954 'double_equal' here because there is
955 no risk of problems related to the
956 comparison doubles, we are only
957 interested in the exact NOTDEF value */
958
959 /* it is assumed that 'theta' and 'a' are in the range [-pi,pi] */
960 theta -= a;
961 if( theta < 0.0 ) theta = -theta;
962 if( theta > M_3_2_PI )
963 {
964 theta -= M_2__PI;
965 if( theta < 0.0 ) theta = -theta;
966 }
967
968 return theta <= prec;
969}
970
971/*----------------------------------------------------------------------------*/
974static double angle_diff(double a, double b)
975{
976 a -= b;
977 while( a <= -M_PI ) a += M_2__PI;
978 while( a > M_PI ) a -= M_2__PI;
979 if( a < 0.0 ) a = -a;
980 return a;
981}
982
983/*----------------------------------------------------------------------------*/
986static double angle_diff_signed(double a, double b)
987{
988 a -= b;
989 while( a <= -M_PI ) a += M_2__PI;
990 while( a > M_PI ) a -= M_2__PI;
991 return a;
992}
993
994
995/*----------------------------------------------------------------------------*/
996/*----------------------------- NFA computation ------------------------------*/
997/*----------------------------------------------------------------------------*/
998
999/*----------------------------------------------------------------------------*/
1023static double log_gamma_lanczos(double x)
1024{
1025 static double q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
1026 8687.24529705, 1168.92649479, 83.8676043424,
1027 2.50662827511 };
1028 double a = (x+0.5) * log(x+5.5) - (x+5.5);
1029 double b = 0.0;
1030 int n;
1031
1032 for(n=0;n<7;n++)
1033 {
1034 a -= log( x + (double) n );
1035 b += q[n] * pow( x, (double) n );
1036 }
1037 return a + log(b);
1038}
1039
1040/*----------------------------------------------------------------------------*/
1057static double log_gamma_windschitl(double x)
1058{
1059 return 0.918938533204673 + (x-0.5)*log(x) - x
1060 + 0.5*x*log( x*sinh(1/x) + 1/(810.0*pow(x,6.0)) );
1061}
1062
1063/*----------------------------------------------------------------------------*/
1068#define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
1069
1070/*----------------------------------------------------------------------------*/
1073#define TABSIZE 100000
1074
1075// clang-format on
1076
1077static double *inv = NULL; /* table to keep computed inverse values */
1078
1080{
1081 if(inv) return;
1082 inv = malloc(sizeof(double) * TABSIZE);
1083}
1084
1085__attribute__((destructor)) static void invDestructor()
1086{
1087 dt_free(inv);
1088}
1089
1090// clang-format off
1091
1092/*----------------------------------------------------------------------------*/
1134static double nfa(int n, int k, double p, double logNT)
1135{
1136 double tolerance = 0.1; /* an error of 10% in the result is accepted */
1138 int i;
1139
1140 /* check parameters */
1141 if( n<0 || k<0 || k>n || p<=0.0 || p>=1.0 )
1142 error("nfa: wrong n, k or p values.");
1143
1144 /* trivial cases */
1145 if( n==0 || k==0 ) return -logNT;
1146 if( n==k ) return -logNT - (double) n * log10(p);
1147
1148 /* probability term */
1149 p_term = p / (1.0-p);
1150
1151 /* compute the first term of the series */
1152 /*
1153 binomial_tail(n,k,p) = sum_{i=k}^n bincoef(n,i) * p^i * (1-p)^{n-i}
1154 where bincoef(n,i) are the binomial coefficients.
1155 But
1156 bincoef(n,k) = gamma(n+1) / ( gamma(k+1) * gamma(n-k+1) ).
1157 We use this to compute the first term. Actually the log of it.
1158 */
1159 log1term = log_gamma( (double) n + 1.0 ) - log_gamma( (double) k + 1.0 )
1160 - log_gamma( (double) (n-k) + 1.0 )
1161 + (double) k * log(p) + (double) (n-k) * log(1.0-p);
1162 term = exp(log1term);
1163
1164 /* in some cases no more computations are needed */
1165 if( double_equal(term,0.0) ) /* the first term is almost zero */
1166 {
1167 if( (double) k > (double) n * p ) /* at begin or end of the tail? */
1168 return -log1term / M_LN10 - logNT; /* end: use just the first term */
1169 else
1170 return -logNT; /* begin: the tail is roughly 1 */
1171 }
1172
1173 /* compute more terms if needed */
1174 bin_tail = term;
1175 for(i=k+1;i<=n;i++)
1176 {
1177 /*
1178 As
1179 term_i = bincoef(n,i) * p^i * (1-p)^(n-i)
1180 and
1181 bincoef(n,i)/bincoef(n,i-1) = n-1+1 / i,
1182 then,
1183 term_i / term_i-1 = (n-i+1)/i * p/(1-p)
1184 and
1185 term_i = term_i-1 * (n-i+1)/i * p/(1-p).
1186 1/i is stored in a table as they are computed,
1187 because divisions are expensive.
1188 p/(1-p) is computed only once and stored in 'p_term'.
1189 */
1190 bin_term = (double) (n-i+1) * ( i<TABSIZE ?
1191 ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (double) i ) ) :
1192 1.0 / (double) i );
1193
1195 term *= mult_term;
1196 bin_tail += term;
1197 if(bin_term<1.0)
1198 {
1199 /* When bin_term<1 then mult_term_j<mult_term_i for j>i.
1200 Then, the error on the binomial tail when truncated at
1201 the i term can be bounded by a geometric series of form
1202 term_i * sum mult_term_i^j. */
1203 err = term * ( ( 1.0 - pow( mult_term, (double) (n-i+1) ) ) /
1204 (1.0-mult_term) - 1.0 );
1205
1206 /* One wants an error at most of tolerance*final_result, or:
1207 tolerance * abs(-log10(bin_tail)-logNT).
1208 Now, the error that can be accepted on bin_tail is
1209 given by tolerance*final_result divided by the derivative
1210 of -log10(x) when x=bin_tail. that is:
1211 tolerance * abs(-log10(bin_tail)-logNT) / (1/bin_tail)
1212 Finally, we truncate the tail if the error is less than:
1213 tolerance * abs(-log10(bin_tail)-logNT) * bin_tail */
1214 if( err < tolerance * fabs(-log10(bin_tail)-logNT) * bin_tail ) break;
1215 }
1216 }
1217 return -log10(bin_tail) - logNT;
1218}
1219
1220
1221/*----------------------------------------------------------------------------*/
1222/*--------------------------- Rectangle structure ----------------------------*/
1223/*----------------------------------------------------------------------------*/
1224
1225/*----------------------------------------------------------------------------*/
1228struct rect
1229{
1230 double x1,y1,x2,y2; /* first and second point of the line segment */
1231 double width; /* rectangle width */
1232 double x,y; /* center of the rectangle */
1233 double theta; /* angle */
1234 double dx,dy; /* (dx,dy) is vector oriented as the line segment */
1235 double prec; /* tolerance angle */
1236 double p; /* probability of a point with angle within 'prec' */
1237};
1238
1239/*----------------------------------------------------------------------------*/
1242static void rect_copy(struct rect * in, struct rect * out)
1243{
1244 /* check parameters */
1245 if( in == NULL || out == NULL ) error("rect_copy: invalid 'in' or 'out'.");
1246
1247 /* copy values */
1248 out->x1 = in->x1;
1249 out->y1 = in->y1;
1250 out->x2 = in->x2;
1251 out->y2 = in->y2;
1252 out->width = in->width;
1253 out->x = in->x;
1254 out->y = in->y;
1255 out->theta = in->theta;
1256 out->dx = in->dx;
1257 out->dy = in->dy;
1258 out->prec = in->prec;
1259 out->p = in->p;
1260}
1261
1262/*----------------------------------------------------------------------------*/
1318typedef struct
1319{
1320 double vx[4]; /* rectangle's corner X coordinates in circular order */
1321 double vy[4]; /* rectangle's corner Y coordinates in circular order */
1322 double ys,ye; /* start and end Y values of current 'column' */
1323 int x,y; /* coordinates of currently explored pixel */
1324} rect_iter;
1325
1326/*----------------------------------------------------------------------------*/
1336static double inter_low(double x, double x1, double y1, double x2, double y2)
1337{
1338 /* check parameters */
1339 if( x1 > x2 || x < x1 || x > x2 )
1340 error("inter_low: unsuitable input, 'x1>x2' or 'x<x1' or 'x>x2'.");
1341
1342 /* interpolation */
1343 if( double_equal(x1,x2) && y1<y2 ) return y1;
1344 if( double_equal(x1,x2) && y1>y2 ) return y2;
1345 return y1 + (x-x1) * (y2-y1) / (x2-x1);
1346}
1347
1348/*----------------------------------------------------------------------------*/
1358static double inter_hi(double x, double x1, double y1, double x2, double y2)
1359{
1360 /* check parameters */
1361 if( x1 > x2 || x < x1 || x > x2 )
1362 error("inter_hi: unsuitable input, 'x1>x2' or 'x<x1' or 'x>x2'.");
1363
1364 /* interpolation */
1365 if( double_equal(x1,x2) && y1<y2 ) return y2;
1366 if( double_equal(x1,x2) && y1>y2 ) return y1;
1367 return y1 + (x-x1) * (y2-y1) / (x2-x1);
1368}
1369
1370/*----------------------------------------------------------------------------*/
1373static void ri_del(rect_iter * iter)
1374{
1375 if( iter == NULL ) error("ri_del: NULL iterator.");
1376 dt_free(iter);
1377}
1378
1379/*----------------------------------------------------------------------------*/
1384static int ri_end(rect_iter * i)
1385{
1386 /* check input */
1387 if( i == NULL ) error("ri_end: NULL iterator.");
1388
1389 /* if the current x value is larger than the largest
1390 x value in the rectangle (vx[2]), we know the full
1391 exploration of the rectangle is finished. */
1392 return (double)(i->x) > i->vx[2];
1393}
1394
1395/*----------------------------------------------------------------------------*/
1400static void ri_inc(rect_iter * i)
1401{
1402 /* check input */
1403 if( i == NULL ) error("ri_inc: NULL iterator.");
1404
1405 /* if not at end of exploration,
1406 increase y value for next pixel in the 'column' */
1407 if( !ri_end(i) ) i->y++;
1408
1409 /* if the end of the current 'column' is reached,
1410 and it is not the end of exploration,
1411 advance to the next 'column' */
1412 while( (double) (i->y) > i->ye && !ri_end(i) )
1413 {
1414 /* increase x, next 'column' */
1415 i->x++;
1416
1417 /* if end of exploration, return */
1418 if( ri_end(i) ) return;
1419
1420 /* update lower y limit (start) for the new 'column'.
1421
1422 We need to interpolate the y value that corresponds to the
1423 lower side of the rectangle. The first thing is to decide if
1424 the corresponding side is
1425
1426 vx[0],vy[0] to vx[3],vy[3] or
1427 vx[3],vy[3] to vx[2],vy[2]
1428
1429 Then, the side is interpolated for the x value of the
1430 'column'. But, if the side is vertical (as it could happen if
1431 the rectangle is vertical and we are dealing with the first
1432 or last 'columns') then we pick the lower value of the side
1433 by using 'inter_low'.
1434 */
1435 if( (double) i->x < i->vx[3] )
1436 i->ys = inter_low((double)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
1437 else
1438 i->ys = inter_low((double)i->x,i->vx[3],i->vy[3],i->vx[2],i->vy[2]);
1439
1440 /* update upper y limit (end) for the new 'column'.
1441
1442 We need to interpolate the y value that corresponds to the
1443 upper side of the rectangle. The first thing is to decide if
1444 the corresponding side is
1445
1446 vx[0],vy[0] to vx[1],vy[1] or
1447 vx[1],vy[1] to vx[2],vy[2]
1448
1449 Then, the side is interpolated for the x value of the
1450 'column'. But, if the side is vertical (as it could happen if
1451 the rectangle is vertical and we are dealing with the first
1452 or last 'columns') then we pick the lower value of the side
1453 by using 'inter_low'.
1454 */
1455 if( (double)i->x < i->vx[1] )
1456 i->ye = inter_hi((double)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
1457 else
1458 i->ye = inter_hi((double)i->x,i->vx[1],i->vy[1],i->vx[2],i->vy[2]);
1459
1460 /* new y */
1461 i->y = (int) ceil(i->ys);
1462 }
1463}
1464
1465/*----------------------------------------------------------------------------*/
1470static rect_iter * ri_ini(struct rect * r)
1471{
1472 double vx[4],vy[4];
1473 int n,offset;
1474 rect_iter * i;
1475
1476 /* check parameters */
1477 if( r == NULL ) error("ri_ini: invalid rectangle.");
1478
1479 /* get memory */
1480 i = (rect_iter *) malloc(sizeof(rect_iter));
1481 if( i == NULL ) error("ri_ini: Not enough memory.");
1482
1483 /* build list of rectangle corners ordered
1484 in a circular way around the rectangle */
1485 vx[0] = r->x1 - r->dy * r->width / 2.0;
1486 vy[0] = r->y1 + r->dx * r->width / 2.0;
1487 vx[1] = r->x2 - r->dy * r->width / 2.0;
1488 vy[1] = r->y2 + r->dx * r->width / 2.0;
1489 vx[2] = r->x2 + r->dy * r->width / 2.0;
1490 vy[2] = r->y2 - r->dx * r->width / 2.0;
1491 vx[3] = r->x1 + r->dy * r->width / 2.0;
1492 vy[3] = r->y1 - r->dx * r->width / 2.0;
1493
1494 /* compute rotation of index of corners needed so that the first
1495 point has the smaller x.
1496
1497 if one side is vertical, thus two corners have the same smaller x
1498 value, the one with the largest y value is selected as the first.
1499 */
1500 if( r->x1 < r->x2 && r->y1 <= r->y2 ) offset = 0;
1501 else if( r->x1 >= r->x2 && r->y1 < r->y2 ) offset = 1;
1502 else if( r->x1 > r->x2 && r->y1 >= r->y2 ) offset = 2;
1503 else offset = 3;
1504
1505 /* apply rotation of index. */
1506 for(n=0; n<4; n++)
1507 {
1508 i->vx[n] = vx[(offset+n)%4];
1509 i->vy[n] = vy[(offset+n)%4];
1510 }
1511
1512 /* Set an initial condition.
1513
1514 The values are set to values that will cause 'ri_inc' (that will
1515 be called immediately) to initialize correctly the first 'column'
1516 and compute the limits 'ys' and 'ye'.
1517
1518 'y' is set to the integer value of vy[0], the starting corner.
1519
1520 'ys' and 'ye' are set to very small values, so 'ri_inc' will
1521 notice that it needs to start a new 'column'.
1522
1523 The smallest integer coordinate inside of the rectangle is
1524 'ceil(vx[0])'. The current 'x' value is set to that value minus
1525 one, so 'ri_inc' (that will increase x by one) will advance to
1526 the first 'column'.
1527 */
1528 i->x = (int) ceil(i->vx[0]) - 1;
1529 i->y = (int) ceil(i->vy[0]);
1530 i->ys = i->ye = -DBL_MAX;
1531
1532 /* advance to the first pixel */
1533 ri_inc(i);
1534
1535 return i;
1536}
1537
1538/*----------------------------------------------------------------------------*/
1541static double rect_nfa(struct rect * rec, image_double angles, double logNT)
1542{
1543 rect_iter * i;
1544 int pts = 0;
1545 int alg = 0;
1546
1547 /* check parameters */
1548 if( rec == NULL ) error("rect_nfa: invalid rectangle.");
1549 if( angles == NULL ) error("rect_nfa: invalid 'angles'.");
1550
1551 /* compute the total number of pixels and of aligned points in 'rec' */
1552 for(i=ri_ini(rec); !ri_end(i); ri_inc(i)) /* rectangle iterator */
1553 if( i->x >= 0 && i->y >= 0 &&
1554 i->x < (int) angles->xsize && i->y < (int) angles->ysize )
1555 {
1556 ++pts; /* total number of pixels counter */
1557 if( isaligned(i->x, i->y, angles, rec->theta, rec->prec) )
1558 ++alg; /* aligned points counter */
1559 }
1560 ri_del(i); /* delete iterator */
1561
1562 return nfa(pts,alg,rec->p,logNT); /* compute NFA value */
1563}
1564
1565
1566/*----------------------------------------------------------------------------*/
1567/*---------------------------------- Regions ---------------------------------*/
1568/*----------------------------------------------------------------------------*/
1569
1570/*----------------------------------------------------------------------------*/
1627static double get_theta( struct point * reg, int reg_size, double x, double y,
1628 image_double modgrad, double reg_angle, double prec )
1629{
1630 double lambda,theta,weight;
1631 double Ixx = 0.0;
1632 double Iyy = 0.0;
1633 double Ixy = 0.0;
1634 int i;
1635
1636 /* check parameters */
1637 if( reg == NULL ) error("get_theta: invalid region.");
1638 if( reg_size <= 1 ) error("get_theta: region size <= 1.");
1639 if( modgrad == NULL || modgrad->data == NULL )
1640 error("get_theta: invalid 'modgrad'.");
1641 if( prec < 0.0 ) error("get_theta: 'prec' must be positive.");
1642
1643 /* compute inertia matrix */
1644 for(i=0; i<reg_size; i++)
1645 {
1646 weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
1647 Ixx += ( (double) reg[i].y - y ) * ( (double) reg[i].y - y ) * weight;
1648 Iyy += ( (double) reg[i].x - x ) * ( (double) reg[i].x - x ) * weight;
1649 Ixy -= ( (double) reg[i].x - x ) * ( (double) reg[i].y - y ) * weight;
1650 }
1651 if( double_equal(Ixx,0.0) && double_equal(Iyy,0.0) && double_equal(Ixy,0.0) )
1652 error("get_theta: null inertia matrix.");
1653
1654 /* compute smallest eigenvalue */
1655 lambda = 0.5 * ( Ixx + Iyy - sqrt( (Ixx-Iyy)*(Ixx-Iyy) + 4.0*Ixy*Ixy ) );
1656
1657 /* compute angle */
1658 theta = fabs(Ixx)>fabs(Iyy) ? atan2(lambda-Ixx,Ixy) : atan2(Ixy,lambda-Iyy);
1659
1660 /* The previous procedure doesn't cares about orientation,
1661 so it could be wrong by 180 degrees. Here is corrected if necessary. */
1662 if( angle_diff(theta,reg_angle) > prec ) theta += M_PI;
1663
1664 return theta;
1665}
1666
1667/*----------------------------------------------------------------------------*/
1670static void region2rect( struct point * reg, int reg_size,
1671 image_double modgrad, double reg_angle,
1672 double prec, double p, struct rect * rec )
1673{
1674 double x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
1675 int i;
1676
1677 /* check parameters */
1678 if( reg == NULL ) error("region2rect: invalid region.");
1679 if( reg_size <= 1 ) error("region2rect: region size <= 1.");
1680 if( modgrad == NULL || modgrad->data == NULL )
1681 error("region2rect: invalid image 'modgrad'.");
1682 if( rec == NULL ) error("region2rect: invalid 'rec'.");
1683
1684 /* center of the region:
1685
1686 It is computed as the weighted sum of the coordinates
1687 of all the pixels in the region. The norm of the gradient
1688 is used as the weight of a pixel. The sum is as follows:
1689 cx = \sum_i G(i).x_i
1690 cy = \sum_i G(i).y_i
1691 where G(i) is the norm of the gradient of pixel i
1692 and x_i,y_i are its coordinates.
1693 */
1694 x = y = sum = 0.0;
1695 for(i=0; i<reg_size; i++)
1696 {
1697 weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
1698 x += (double) reg[i].x * weight;
1699 y += (double) reg[i].y * weight;
1700 sum += weight;
1701 }
1702 if( sum <= 0.0 ) error("region2rect: weights sum equal to zero.");
1703 x /= sum;
1704 y /= sum;
1705
1706 /* theta */
1707 theta = get_theta(reg,reg_size,x,y,modgrad,reg_angle,prec);
1708
1709 /* length and width:
1710
1711 'l' and 'w' are computed as the distance from the center of the
1712 region to pixel i, projected along the rectangle axis (dx,dy) and
1713 to the orthogonal axis (-dy,dx), respectively.
1714
1715 The length of the rectangle goes from l_min to l_max, where l_min
1716 and l_max are the minimum and maximum values of l in the region.
1717 Analogously, the width is selected from w_min to w_max, where
1718 w_min and w_max are the minimum and maximum of w for the pixels
1719 in the region.
1720 */
1721 dx = cos(theta);
1722 dy = sin(theta);
1723 l_min = l_max = w_min = w_max = 0.0;
1724 for(i=0; i<reg_size; i++)
1725 {
1726 l = ( (double) reg[i].x - x) * dx + ( (double) reg[i].y - y) * dy;
1727 w = -( (double) reg[i].x - x) * dy + ( (double) reg[i].y - y) * dx;
1728
1729 if( l > l_max ) l_max = l;
1730 if( l < l_min ) l_min = l;
1731 if( w > w_max ) w_max = w;
1732 if( w < w_min ) w_min = w;
1733 }
1734
1735 /* store values */
1736 rec->x1 = x + l_min * dx;
1737 rec->y1 = y + l_min * dy;
1738 rec->x2 = x + l_max * dx;
1739 rec->y2 = y + l_max * dy;
1740 rec->width = w_max - w_min;
1741 rec->x = x;
1742 rec->y = y;
1743 rec->theta = theta;
1744 rec->dx = dx;
1745 rec->dy = dy;
1746 rec->prec = prec;
1747 rec->p = p;
1748
1749 /* we impose a minimal width of one pixel
1750
1751 A sharp horizontal or vertical step would produce a perfectly
1752 horizontal or vertical region. The width computed would be
1753 zero. But that corresponds to a one pixels width transition in
1754 the image.
1755 */
1756 if( rec->width < 1.0 ) rec->width = 1.0;
1757}
1758
1759/*----------------------------------------------------------------------------*/
1763static void region_grow( int x, int y, image_double angles, struct point * reg,
1764 int * reg_size, double * reg_angle, image_char used,
1765 double prec )
1766{
1767 double sumdx,sumdy;
1768 int xx,yy,i;
1769
1770 /* check parameters */
1771 if( x < 0 || y < 0 || x >= (int) angles->xsize || y >= (int) angles->ysize )
1772 error("region_grow: (x,y) out of the image.");
1773 if( angles == NULL || angles->data == NULL )
1774 error("region_grow: invalid image 'angles'.");
1775 if( reg == NULL ) error("region_grow: invalid 'reg'.");
1776 if( reg_size == NULL ) error("region_grow: invalid pointer 'reg_size'.");
1777 if( reg_angle == NULL ) error("region_grow: invalid pointer 'reg_angle'.");
1778 if( used == NULL || used->data == NULL )
1779 error("region_grow: invalid image 'used'.");
1780
1781 /* first point of the region */
1782 *reg_size = 1;
1783 reg[0].x = x;
1784 reg[0].y = y;
1785 *reg_angle = angles->data[x+y*angles->xsize]; /* region's angle */
1786 sumdx = cos(*reg_angle);
1787 sumdy = sin(*reg_angle);
1788 used->data[x+y*used->xsize] = USED;
1789
1790 /* try neighbors as new region points */
1791 for(i=0; i<*reg_size; i++)
1792 for(xx=reg[i].x-1; xx<=reg[i].x+1; xx++)
1793 for(yy=reg[i].y-1; yy<=reg[i].y+1; yy++)
1794 if( xx>=0 && yy>=0 && xx<(int)used->xsize && yy<(int)used->ysize &&
1795 used->data[xx+yy*used->xsize] != USED &&
1796 isaligned(xx,yy,angles,*reg_angle,prec) )
1797 {
1798 /* add point */
1799 used->data[xx+yy*used->xsize] = USED;
1800 reg[*reg_size].x = xx;
1801 reg[*reg_size].y = yy;
1802 ++(*reg_size);
1803
1804 /* update region's angle */
1805 sumdx += cos( angles->data[xx+yy*angles->xsize] );
1806 sumdy += sin( angles->data[xx+yy*angles->xsize] );
1807 *reg_angle = atan2(sumdy,sumdx);
1808 }
1809}
1810
1811/*----------------------------------------------------------------------------*/
1815static double rect_improve( struct rect * rec, image_double angles,
1816 double logNT, double log_eps )
1817{
1818 struct rect r;
1819 double log_nfa,log_nfa_new;
1820 double delta = 0.5;
1821 double delta_2 = delta / 2.0;
1822 int n;
1823
1825
1826 if( log_nfa > log_eps ) return log_nfa;
1827
1828 /* try finer precisions */
1829 rect_copy(rec,&r);
1830 for(n=0; n<5; n++)
1831 {
1832 r.p /= 2.0;
1833 r.prec = r.p * M_PI;
1835 if( log_nfa_new > log_nfa )
1836 {
1838 rect_copy(&r,rec);
1839 }
1840 }
1841
1842 if( log_nfa > log_eps ) return log_nfa;
1843
1844 /* try to reduce width */
1845 rect_copy(rec,&r);
1846 for(n=0; n<5; n++)
1847 {
1848 if( (r.width - delta) >= 0.5 )
1849 {
1850 r.width -= delta;
1852 if( log_nfa_new > log_nfa )
1853 {
1854 rect_copy(&r,rec);
1856 }
1857 }
1858 }
1859
1860 if( log_nfa > log_eps ) return log_nfa;
1861
1862 /* try to reduce one side of the rectangle */
1863 rect_copy(rec,&r);
1864 for(n=0; n<5; n++)
1865 {
1866 if( (r.width - delta) >= 0.5 )
1867 {
1868 r.x1 += -r.dy * delta_2;
1869 r.y1 += r.dx * delta_2;
1870 r.x2 += -r.dy * delta_2;
1871 r.y2 += r.dx * delta_2;
1872 r.width -= delta;
1874 if( log_nfa_new > log_nfa )
1875 {
1876 rect_copy(&r,rec);
1878 }
1879 }
1880 }
1881
1882 if( log_nfa > log_eps ) return log_nfa;
1883
1884 /* try to reduce the other side of the rectangle */
1885 rect_copy(rec,&r);
1886 for(n=0; n<5; n++)
1887 {
1888 if( (r.width - delta) >= 0.5 )
1889 {
1890 r.x1 -= -r.dy * delta_2;
1891 r.y1 -= r.dx * delta_2;
1892 r.x2 -= -r.dy * delta_2;
1893 r.y2 -= r.dx * delta_2;
1894 r.width -= delta;
1896 if( log_nfa_new > log_nfa )
1897 {
1898 rect_copy(&r,rec);
1900 }
1901 }
1902 }
1903
1904 if( log_nfa > log_eps ) return log_nfa;
1905
1906 /* try even finer precisions */
1907 rect_copy(rec,&r);
1908 for(n=0; n<5; n++)
1909 {
1910 r.p /= 2.0;
1911 r.prec = r.p * M_PI;
1913 if( log_nfa_new > log_nfa )
1914 {
1916 rect_copy(&r,rec);
1917 }
1918 }
1919
1920 return log_nfa;
1921}
1922
1923/*----------------------------------------------------------------------------*/
1928static int reduce_region_radius( struct point * reg, int * reg_size,
1930 double prec, double p, struct rect * rec,
1932 double density_th )
1933{
1934 double density,radius1,radius2,rad,xc,yc;
1935 int i;
1936
1937 /* check parameters */
1938 if( reg == NULL ) error("reduce_region_radius: invalid pointer 'reg'.");
1939 if( reg_size == NULL )
1940 error("reduce_region_radius: invalid pointer 'reg_size'.");
1941 if( prec < 0.0 ) error("reduce_region_radius: 'prec' must be positive.");
1942 if( rec == NULL ) error("reduce_region_radius: invalid pointer 'rec'.");
1943 if( used == NULL || used->data == NULL )
1944 error("reduce_region_radius: invalid image 'used'.");
1945 if( angles == NULL || angles->data == NULL )
1946 error("reduce_region_radius: invalid image 'angles'.");
1947
1948 /* compute region points density */
1949 density = (double) *reg_size /
1950 ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
1951
1952 /* if the density criterion is satisfied there is nothing to do */
1953 if( density >= density_th ) return TRUE;
1954
1955 /* compute region's radius */
1956 xc = (double) reg[0].x;
1957 yc = (double) reg[0].y;
1958 radius1 = dist( xc, yc, rec->x1, rec->y1 );
1959 radius2 = dist( xc, yc, rec->x2, rec->y2 );
1961
1962 /* while the density criterion is not satisfied, remove farther pixels */
1963 while( density < density_th )
1964 {
1965 rad *= 0.75; /* reduce region's radius to 75% of its value */
1966
1967 /* remove points from the region and update 'used' map */
1968 for(i=0; i<*reg_size; i++)
1969 if( dist( xc, yc, (double) reg[i].x, (double) reg[i].y ) > rad )
1970 {
1971 /* point not kept, mark it as NOTUSED */
1972 used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
1973 /* remove point from the region */
1974 reg[i].x = reg[*reg_size-1].x; /* if i==*reg_size-1 copy itself */
1975 reg[i].y = reg[*reg_size-1].y;
1976 --(*reg_size);
1977 --i; /* to avoid skipping one point */
1978 }
1979
1980 /* reject if the region is too small.
1981 2 is the minimal region size for 'region2rect' to work. */
1982 if( *reg_size < 2 ) return FALSE;
1983
1984 /* re-compute rectangle */
1986
1987 /* re-compute region points density */
1988 density = (double) *reg_size /
1989 ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
1990 }
1991
1992 /* if this point is reached, the density criterion is satisfied */
1993 return TRUE;
1994}
1995
1996/*----------------------------------------------------------------------------*/
2006static int refine( struct point * reg, int * reg_size, image_double modgrad,
2007 double reg_angle, double prec, double p, struct rect * rec,
2009{
2010 double angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
2011 int i,n;
2012
2013 /* check parameters */
2014 if( reg == NULL ) error("refine: invalid pointer 'reg'.");
2015 if( reg_size == NULL ) error("refine: invalid pointer 'reg_size'.");
2016 if( prec < 0.0 ) error("refine: 'prec' must be positive.");
2017 if( rec == NULL ) error("refine: invalid pointer 'rec'.");
2018 if( used == NULL || used->data == NULL )
2019 error("refine: invalid image 'used'.");
2020 if( angles == NULL || angles->data == NULL )
2021 error("refine: invalid image 'angles'.");
2022
2023 /* compute region points density */
2024 density = (double) *reg_size /
2025 ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
2026
2027 /* if the density criterion is satisfied there is nothing to do */
2028 if( density >= density_th ) return TRUE;
2029
2030 /*------ First try: reduce angle tolerance ------*/
2031
2032 /* compute the new mean angle and tolerance */
2033 xc = (double) reg[0].x;
2034 yc = (double) reg[0].y;
2035 ang_c = angles->data[ reg[0].x + reg[0].y * angles->xsize ];
2036 sum = s_sum = 0.0;
2037 n = 0;
2038 for(i=0; i<*reg_size; i++)
2039 {
2040 used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
2041 if( dist( xc, yc, (double) reg[i].x, (double) reg[i].y ) < rec->width )
2042 {
2043 angle = angles->data[ reg[i].x + reg[i].y * angles->xsize ];
2044 ang_d = angle_diff_signed(angle,ang_c);
2045 sum += ang_d;
2046 s_sum += ang_d * ang_d;
2047 ++n;
2048 }
2049 }
2050
2051 /* should not happen */
2052 if(n == 0) return FALSE;
2053
2054 mean_angle = sum / (double) n;
2055 tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (double) n
2056 + mean_angle*mean_angle ); /* 2 * standard deviation */
2057
2058 /* find a new region from the same starting point and new angle tolerance */
2060
2061 /* if the region is too small, reject */
2062 if( *reg_size < 2 ) return FALSE;
2063
2064 /* re-compute rectangle */
2066
2067 /* re-compute region points density */
2068 density = (double) *reg_size /
2069 ( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
2070
2071 /*------ Second try: reduce region radius ------*/
2072 if( density < density_th )
2074 rec, used, angles, density_th );
2075
2076 /* if this point is reached, the density criterion is satisfied */
2077 return TRUE;
2078}
2079
2080
2081/*----------------------------------------------------------------------------*/
2082/*-------------------------- Line Segment Detector ---------------------------*/
2083/*----------------------------------------------------------------------------*/
2084
2085/*----------------------------------------------------------------------------*/
2088static double * LineSegmentDetection( int * n_out,
2089 double * img, int X, int Y,
2090 double scale, double sigma_scale, double quant,
2091 double ang_th, double log_eps, double density_th,
2092 int n_bins,
2093 int ** reg_img, int * reg_x, int * reg_y )
2094{
2095 image_double image;
2097 double * return_value;
2099 image_char used;
2101 struct coorlist * list_p;
2102 void * mem_p;
2103 struct rect rec;
2104 struct point * reg;
2106 unsigned int xsize,ysize;
2107 double rho,reg_angle,prec,p,log_nfa,logNT;
2108 int ls_count = 0; /* line segments are numbered 1,2,3,... */
2109
2110
2111 /* check parameters */
2112 if( img == NULL || X <= 0 || Y <= 0 ) error("invalid image input.");
2113 if( scale <= 0.0 ) error("'scale' value must be positive.");
2114 if( sigma_scale <= 0.0 ) error("'sigma_scale' value must be positive.");
2115 if( quant < 0.0 ) error("'quant' value must be positive.");
2116 if( ang_th <= 0.0 || ang_th >= 180.0 )
2117 error("'ang_th' value must be in the range (0,180).");
2119 error("'density_th' value must be in the range [0,1].");
2120 if( n_bins <= 0 ) error("'n_bins' value must be positive.");
2121
2122
2123 /* angle tolerance */
2124 prec = M_PI * ang_th / 180.0;
2125 p = ang_th / 180.0;
2126 rho = quant / sin(prec); /* gradient magnitude threshold */
2127
2128
2129 /* load and scale image (if necessary) and compute angle at each pixel */
2130 image = new_image_double_ptr( (unsigned int) X, (unsigned int) Y, img );
2131 if( scale != 1.0 )
2132 {
2133 scaled_image = gaussian_sampler( image, scale, sigma_scale );
2135 &modgrad, (unsigned int) n_bins );
2137 }
2138 else
2139 angles = ll_angle( image, rho, &list_p, &mem_p, &modgrad,
2140 (unsigned int) n_bins );
2141 xsize = angles->xsize;
2142 ysize = angles->ysize;
2143
2144 /* Number of Tests - NT
2145
2146 The theoretical number of tests is Np.(XY)^(5/2)
2147 where X and Y are number of columns and rows of the image.
2148 Np corresponds to the number of angle precisions considered.
2149 As the procedure 'rect_improve' tests 5 times to halve the
2150 angle precision, and 5 more times after improving other factors,
2151 11 different precision values are potentially tested. Thus,
2152 the number of tests is
2153 11 * (X*Y)^(5/2)
2154 whose logarithm value is
2155 log10(11) + 5/2 * (log10(X) + log10(Y)).
2156 */
2157 logNT = 5.0 * ( log10( (double) xsize ) + log10( (double) ysize ) ) / 2.0
2158 + log10(11.0);
2159 min_reg_size = (int) (-logNT/log10(p)); /* minimal number of points in region
2160 that can give a meaningful event */
2161
2162
2163 /* initialize some structures */
2164 if( reg_img != NULL && reg_x != NULL && reg_y != NULL ) /* save region data */
2165 region = new_image_int_ini(angles->xsize,angles->ysize,0);
2166 used = new_image_char_ini(xsize,ysize,NOTUSED);
2167 reg = (struct point *) calloc( (size_t) (xsize*ysize), sizeof(struct point) );
2168 if( reg == NULL ) error("not enough memory!");
2169
2170
2171 /* search for line segments */
2172 for(; list_p != NULL; list_p = list_p->next )
2173 if( used->data[ list_p->x + list_p->y * used->xsize ] == NOTUSED &&
2174 angles->data[ list_p->x + list_p->y * angles->xsize ] != NOTDEF )
2175 /* there is no risk of double comparison problems here
2176 because we are only interested in the exact NOTDEF value */
2177 {
2178 /* find the region of connected point and ~equal angle */
2180 &reg_angle, used, prec );
2181
2182 /* reject small regions */
2183 if( reg_size < min_reg_size ) continue;
2184
2185 /* construct rectangular approximation for the region */
2187
2188 /* Check if the rectangle exceeds the minimal density of
2189 region points. If not, try to improve the region.
2190 The rectangle will be rejected if the final one does
2191 not fulfill the minimal density condition.
2192 This is an addition to the original LSD algorithm published in
2193 "LSD: A Fast Line Segment Detector with a False Detection Control"
2194 by R. Grompone von Gioi, J. Jakubowicz, J.M. Morel, and G. Randall.
2195 The original algorithm is obtained with density_th = 0.0.
2196 */
2198 prec, p, &rec, used, angles, density_th ) ) continue;
2199
2200 /* compute NFA value */
2202 if( log_nfa <= log_eps ) continue;
2203
2204 /* A New Line Segment was found! */
2205 ++ls_count; /* increase line segment counter */
2206
2207 /*
2208 The gradient was computed with a 2x2 mask, its value corresponds to
2209 points with an offset of (0.5,0.5), that should be added to output.
2210 The coordinates origin is at the center of pixel (0,0).
2211 */
2212 rec.x1 += 0.5; rec.y1 += 0.5;
2213 rec.x2 += 0.5; rec.y2 += 0.5;
2214
2215 /* scale the result values if a subsampling was performed */
2216 if( scale != 1.0 )
2217 {
2218 rec.x1 /= scale; rec.y1 /= scale;
2219 rec.x2 /= scale; rec.y2 /= scale;
2220 rec.width /= scale;
2221 }
2222
2223 /* add line segment found to output */
2224 add_7tuple( out, rec.x1, rec.y1, rec.x2, rec.y2,
2225 rec.width, rec.p, log_nfa );
2226
2227 /* add region number to 'region' image if needed */
2228 if( region != NULL )
2229 for(i=0; i<reg_size; i++)
2230 region->data[ reg[i].x + reg[i].y * region->xsize ] = ls_count;
2231 }
2232
2233
2234 /* free memory */
2235 dt_free(image); /* only the double_image structure should be freed,
2236 the data pointer was provided to this functions
2237 and should not be destroyed. */
2240 free_image_char(used);
2241 dt_free(reg);
2242 dt_free(mem_p);
2243
2244 /* return the result */
2245 if( reg_img != NULL && reg_x != NULL && reg_y != NULL )
2246 {
2247 if( region == NULL ) error("'region' should be a valid image.");
2248 *reg_img = region->data;
2249 if( region->xsize > (unsigned int) INT_MAX ||
2250 region->ysize > (unsigned int) INT_MAX )
2251 error("region image to big to fit in INT sizes.");
2252 *reg_x = (int) (region->xsize);
2253 *reg_y = (int) (region->ysize);
2254
2255 /* free the 'region' structure.
2256 we cannot use the function 'free_image_int' because we need to keep
2257 the memory with the image data to be returned by this function. */
2258 dt_free(region);
2259 }
2260 if( out->size > (unsigned int) INT_MAX )
2261 error("too many detections to fit in an INT.");
2262 *n_out = (int) (out->size);
2263
2264 return_value = out->values;
2265 dt_free(out); /* only the 'ntuple_list' structure must be freed,
2266 but the 'values' pointer must be keep to return
2267 as a result. */
2268
2269 return return_value;
2270}
2271#if 0
2272/*----------------------------------------------------------------------------*/
2275static double * lsd_scale_region( int * n_out,
2276 double * img, int X, int Y, double scale,
2277 int ** reg_img, int * reg_x, int * reg_y )
2278{
2279 /* LSD parameters */
2280 double sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
2281 sigma = sigma_scale/scale. */
2282 double quant = 2.0; /* Bound to the quantization error on the
2283 gradient norm. */
2284 double ang_th = 22.5; /* Gradient angle tolerance in degrees. */
2285 double log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
2286 double density_th = 0.7; /* Minimal density of region points in rectangle. */
2287 int n_bins = 1024; /* Number of bins in pseudo-ordering of gradient
2288 modulus. */
2289
2290 return LineSegmentDetection( n_out, img, X, Y, scale, sigma_scale, quant,
2292 reg_img, reg_x, reg_y );
2293}
2294
2295/*----------------------------------------------------------------------------*/
2298static double * lsd_scale(int * n_out, double * img, int X, int Y, double scale)
2299{
2300 return lsd_scale_region(n_out,img,X,Y,scale,NULL,NULL,NULL);
2301}
2302
2303/*----------------------------------------------------------------------------*/
2306static double * lsd(int * n_out, double * img, int X, int Y)
2307{
2308 /* LSD parameters */
2309 double scale = 0.8; /* Scale the image by Gaussian filter to 'scale'. */
2310
2311 return lsd_scale(n_out,img,X,Y,scale);
2312}
2313/*----------------------------------------------------------------------------*/
2314#endif
2315/*==================================================================================
2316 * end of LSD code
2317 *==================================================================================*/
2318
2319// clang-format on
2320
2321#undef NOTDEF
2322#undef NOTUSED
2323#undef USED
2324#undef RELATIVE_ERROR_FACTOR
2325#undef TABSIZE
2326
2327// clang-format off
2328// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
2329// vim: shiftwidth=2 expandtab tabstop=2 cindent
2330// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
2331// clang-format on
static image_int new_image_int(unsigned int xsize, unsigned int ysize)
Definition ashift_lsd.c:466
static ntuple_list new_ntuple_list(unsigned int dim)
Definition ashift_lsd.c:304
static void region2rect(struct point *reg, int reg_size, image_double modgrad, double reg_angle, double prec, double p, struct rect *rec)
Definition ashift_lsd.c:1670
static double get_theta(struct point *reg, int reg_size, double x, double y, image_double modgrad, double reg_angle, double prec)
Definition ashift_lsd.c:1627
static double * LineSegmentDetection(int *n_out, double *img, int X, int Y, double scale, double sigma_scale, double quant, double ang_th, double log_eps, double density_th, int n_bins, int **reg_img, int *reg_x, int *reg_y)
Definition ashift_lsd.c:2088
#define NOTDEF
Definition ashift_lsd.c:166
static double dist(double x1, double y1, double x2, double y2)
Definition ashift_lsd.c:250
static void enlarge_ntuple_list(ntuple_list n_tuple)
Definition ashift_lsd.c:330
static int ri_end(rect_iter *i)
Definition ashift_lsd.c:1384
static void region_grow(int x, int y, image_double angles, struct point *reg, int *reg_size, double *reg_angle, image_char used, double prec)
Definition ashift_lsd.c:1763
static void free_ntuple_list(ntuple_list in)
Definition ashift_lsd.c:292
static image_double ll_angle(image_double in, double threshold, struct coorlist **list_p, void **mem_p, image_double *modgrad, unsigned int n_bins)
Definition ashift_lsd.c:795
struct image_double_s * image_double
static double angle_diff(double a, double b)
Definition ashift_lsd.c:974
static double log_gamma_windschitl(double x)
Definition ashift_lsd.c:1057
static image_double gaussian_sampler(image_double in, double scale, double sigma_scale)
Definition ashift_lsd.c:654
static image_char new_image_char(unsigned int xsize, unsigned int ysize)
Definition ashift_lsd.c:406
#define RELATIVE_ERROR_FACTOR
Definition ashift_lsd.c:211
static rect_iter * ri_ini(struct rect *r)
Definition ashift_lsd.c:1470
static image_int new_image_int_ini(unsigned int xsize, unsigned int ysize, int fill_value)
Definition ashift_lsd.c:490
static double rect_improve(struct rect *rec, image_double angles, double logNT, double log_eps)
Definition ashift_lsd.c:1815
#define TABSIZE
Definition ashift_lsd.c:1073
static void add_7tuple(ntuple_list out, double v1, double v2, double v3, double v4, double v5, double v6, double v7)
Definition ashift_lsd.c:348
static image_double new_image_double(unsigned int xsize, unsigned int ysize)
Definition ashift_lsd.c:532
static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
Definition ashift_lsd.c:591
struct ntuple_list_s * ntuple_list
struct image_int_s * image_int
static int refine(struct point *reg, int *reg_size, image_double modgrad, double reg_angle, double prec, double p, struct rect *rec, image_char used, image_double angles, double density_th)
Definition ashift_lsd.c:2006
#define NOTUSED
Definition ashift_lsd.c:175
static void rect_copy(struct rect *in, struct rect *out)
Definition ashift_lsd.c:1242
static double rect_nfa(struct rect *rec, image_double angles, double logNT)
Definition ashift_lsd.c:1541
#define M_2__PI
Definition ashift_lsd.c:172
static double nfa(int n, int k, double p, double logNT)
Definition ashift_lsd.c:1134
static void error(char *msg)
Definition ashift_lsd.c:202
static image_char new_image_char_ini(unsigned int xsize, unsigned int ysize, unsigned char fill_value)
Definition ashift_lsd.c:431
static void ri_del(rect_iter *iter)
Definition ashift_lsd.c:1373
static double * inv
Definition ashift_lsd.c:1077
static void free_image_char(image_char i)
Definition ashift_lsd.c:395
static double inter_hi(double x, double x1, double y1, double x2, double y2)
Definition ashift_lsd.c:1358
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
static double angle_diff_signed(double a, double b)
Definition ashift_lsd.c:986
#define USED
Definition ashift_lsd.c:178
static image_double new_image_double_ptr(unsigned int xsize, unsigned int ysize, double *data)
Definition ashift_lsd.c:556
static double inter_low(double x, double x1, double y1, double x2, double y2)
Definition ashift_lsd.c:1336
struct image_char_s * image_char
static double log_gamma_lanczos(double x)
Definition ashift_lsd.c:1023
static void free_image_double(image_double i)
Definition ashift_lsd.c:521
static int double_equal(double a, double b)
Definition ashift_lsd.c:224
static int isaligned(int x, int y, image_double angles, double theta, double prec)
Definition ashift_lsd.c:936
#define M_3_2_PI
Definition ashift_lsd.c:169
static int reduce_region_radius(struct point *reg, int *reg_size, image_double modgrad, double reg_angle, double prec, double p, struct rect *rec, image_char used, image_double angles, double density_th)
Definition ashift_lsd.c:1928
static void ri_inc(rect_iter *i)
Definition ashift_lsd.c:1400
#define log_gamma(x)
Definition ashift_lsd.c:1068
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:315
static float kernel(const float *x, const float *y)
Definition colorchecker.c:469
const float i
Definition colorspaces_inline_conversions.h:669
const float h
Definition colorspaces_inline_conversions.h:1366
const float g
Definition colorspaces_inline_conversions.h:925
const float threshold
Definition colorspaces_inline_conversions.h:340
static const dt_colormatrix_t M
Definition colorspaces_inline_conversions.h:933
const float r
Definition colorspaces_inline_conversions.h:1324
const float b
Definition colorspaces_inline_conversions.h:1326
const float a
Definition colorspaces_inline_conversions.h:1292
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
const float n
Definition colorspaces_inline_conversions.h:929
const float delta
Definition colorspaces_inline_conversions.h:722
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Multi-tap smudge source sample with directional jitter.
Definition darktable.h:448
#define dt_free(ptr)
Definition darktable.h:380
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:33
static const float x
Definition iop_profile.h:239
#define M_LN10
Definition math.h:40
#define M_PI
Definition math.h:45
#define N
Definition noiseprofile.c:159
Definition ashift_lsd.c:184
int x
Definition ashift_lsd.c:185
int y
Definition ashift_lsd.c:185
struct coorlist * next
Definition ashift_lsd.c:186
Definition ashift_lsd.c:387
unsigned int xsize
Definition ashift_lsd.c:389
unsigned int ysize
Definition ashift_lsd.c:389
unsigned char * data
Definition ashift_lsd.c:388
Definition ashift_lsd.c:513
unsigned int xsize
Definition ashift_lsd.c:515
unsigned int ysize
Definition ashift_lsd.c:515
double * data
Definition ashift_lsd.c:514
Definition ashift_lsd.c:458
unsigned int xsize
Definition ashift_lsd.c:460
unsigned int ysize
Definition ashift_lsd.c:460
int * data
Definition ashift_lsd.c:459
Definition ashift_lsd.c:282
unsigned int dim
Definition ashift_lsd.c:285
unsigned int size
Definition ashift_lsd.c:283
double * values
Definition ashift_lsd.c:286
unsigned int max_size
Definition ashift_lsd.c:284
Definition ashift_lsd.c:192
int y
Definition ashift_lsd.c:192
int x
Definition ashift_lsd.c:192
Definition ashift_lsd.c:1319
int x
Definition ashift_lsd.c:1323
double ye
Definition ashift_lsd.c:1322
Definition ashift_lsd.c:1229
double dx
Definition ashift_lsd.c:1234
double theta
Definition ashift_lsd.c:1233
double dy
Definition ashift_lsd.c:1234
double y2
Definition ashift_lsd.c:1230
double x1
Definition ashift_lsd.c:1230
double x2
Definition ashift_lsd.c:1230
double y1
Definition ashift_lsd.c:1230
double p
Definition ashift_lsd.c:1236
double x
Definition ashift_lsd.c:1232
double width
Definition ashift_lsd.c:1231
double prec
Definition ashift_lsd.c:1235
double y
Definition ashift_lsd.c:1232
typedef double((*spd)(unsigned long int wavelength, double TempK))