106 #define M_LN10 2.30258509299404568402
111 #define M_PI 3.14159265358979323846
123 #define NOTDEF -1024.0
126 #define M_3_2_PI 4.71238898038
129 #define M_2__PI 6.28318530718
161 fprintf(stderr,
"LSD Error: %s\n",msg);
168 #define RELATIVE_ERROR_FACTOR 100.0
183 double abs_diff,aa,bb,abs_max;
186 if( a == b )
return TRUE;
188 abs_diff =
fabs(a-b);
191 abs_max = aa > bb ? aa : bb;
198 if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
207 static double dist(
double x1,
double y1,
double x2,
double y2)
209 return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
251 if( in ==
NULL || in->values ==
NULL )
252 error(
"free_ntuple_list: invalid n-tuple input.");
253 free( (
void *) in->values );
266 if( dim == 0 )
error(
"new_ntuple_list: 'dim' must be positive.");
270 if( n_tuple ==
NULL )
error(
"not enough memory.");
278 n_tuple->
values = (
double *) malloc( dim*n_tuple->
max_size *
sizeof(
double) );
291 error(
"enlarge_ntuple_list: invalid n-tuple.");
297 n_tuple->
values = (
double *) realloc( (
void *) n_tuple->
values,
298 n_tuple->
dim * n_tuple->
max_size *
sizeof(double) );
306 double v4,
double v5,
double v6,
double v7 )
309 if( out ==
NULL )
error(
"add_7tuple: invalid n-tuple input.");
310 if( out->dim != 7 )
error(
"add_7tuple: the n-tuple must be a 7-tuple.");
314 if( out->values ==
NULL )
error(
"add_7tuple: invalid n-tuple input.");
317 out->values[ out->size * out->dim + 0 ] = v1;
318 out->values[ out->size * out->dim + 1 ] = v2;
319 out->values[ out->size * out->dim + 2 ] = v3;
320 out->values[ out->size * out->dim + 3 ] = v4;
321 out->values[ out->size * out->dim + 4 ] = v5;
322 out->values[ out->size * out->dim + 5 ] = v6;
323 out->values[ out->size * out->dim + 6 ] = v7;
355 error(
"free_image_char: invalid input image.");
356 free( (
void *) i->
data );
368 if( xsize == 0 || ysize == 0 )
error(
"new_image_char: invalid image size.");
373 image->data = (
unsigned char *) calloc( (
size_t) (xsize*ysize),
374 sizeof(
unsigned char) );
378 image->xsize = xsize;
379 image->ysize = ysize;
389 unsigned char fill_value )
392 unsigned int N = xsize*ysize;
397 error(
"new_image_char_ini: invalid image.");
400 for(i=0; i<N; i++)
image->data[i] = fill_value;
428 if( xsize == 0 || ysize == 0 )
error(
"new_image_int: invalid image size.");
433 image->data = (
int *) calloc( (
size_t) (xsize*ysize),
sizeof(
int) );
437 image->xsize = xsize;
438 image->ysize = ysize;
451 unsigned int N = xsize*ysize;
455 for(i=0; i<N; i++)
image->data[i] = fill_value;
481 error(
"free_image_double: invalid input image.");
482 free( (
void *) i->
data );
494 if( xsize == 0 || ysize == 0 )
error(
"new_image_double: invalid image size.");
499 image->data = (
double *) calloc( (
size_t) (xsize*ysize),
sizeof(
double) );
503 image->xsize = xsize;
504 image->ysize = ysize;
514 unsigned int ysize,
double * data )
519 if( xsize == 0 || ysize == 0 )
520 error(
"new_image_double_ptr: invalid image size.");
521 if( data ==
NULL )
error(
"new_image_double_ptr: NULL data pointer.");
528 image->xsize = xsize;
529 image->ysize = ysize;
556 error(
"gaussian_kernel: invalid n-tuple 'kernel'.");
557 if( sigma <= 0.0 )
error(
"gaussian_kernel: 'sigma' must be positive.");
562 for(i=0;i<kernel->
dim;i++)
564 val = ( (double) i - mean ) / sigma;
565 kernel->
values[i] = exp( -0.5 * val * val );
570 if( sum >= 0.0 )
for(i=0;i<kernel->
dim;i++) kernel->
values[i] /= sum;
616 unsigned int N,M,h,n,x,y,i;
617 int xc,yc,j,double_x_size,double_y_size;
618 double sigma,xx,yy,sum,prec;
621 if( in ==
NULL || in->data ==
NULL || in->xsize == 0 || in->ysize == 0 )
622 error(
"gaussian_sampler: invalid image.");
623 if( scale <= 0.0 )
error(
"gaussian_sampler: 'scale' must be positive.");
624 if( sigma_scale <= 0.0 )
625 error(
"gaussian_sampler: 'sigma_scale' must be positive.");
628 if( in->xsize * scale > (
double) UINT_MAX ||
629 in->ysize * scale > (
double) UINT_MAX )
630 error(
"gaussian_sampler: the output image size exceeds the handled size.");
631 N = (
unsigned int)
ceil( in->xsize * scale );
632 M = (
unsigned int)
ceil( in->ysize * scale );
637 sigma = scale < 1.0 ? sigma_scale / scale : sigma_scale;
647 h = (
unsigned int)
ceil( sigma * sqrt( 2.0 * prec * log(10.0) ) );
652 double_x_size = (int) (2 * in->xsize);
653 double_y_size = (int) (2 * in->ysize);
656 for(x=0;x<aux->
xsize;x++)
663 xx = (double) x / scale;
666 xc = (int)
floor( xx + 0.5 );
671 for(y=0;y<aux->
ysize;y++)
674 for(i=0;i<kernel->
dim;i++)
679 while( j < 0 ) j += double_x_size;
680 while( j >= double_x_size ) j -= double_x_size;
681 if( j >= (
int) in->xsize ) j = double_x_size-1-j;
683 sum += in->data[ j + y * in->xsize ] * kernel->
values[i];
690 for(y=0;y<out->ysize;y++)
697 yy = (double) y / scale;
700 yc = (int)
floor( yy + 0.5 );
705 for(x=0;x<out->xsize;x++)
708 for(i=0;i<kernel->
dim;i++)
713 while( j < 0 ) j += double_y_size;
714 while( j >= double_y_size ) j -= double_y_size;
715 if( j >= (
int) in->ysize ) j = double_y_size-1-j;
719 out->data[ x + y * out->xsize ] = sum;
753 struct coorlist ** list_p,
void ** mem_p,
757 unsigned int n,p,x,y,adr,i;
758 double com1,com2,gx,gy,norm,norm2;
767 double max_grad = 0.0;
770 if( in ==
NULL || in->data ==
NULL || in->xsize == 0 || in->ysize == 0 )
771 error(
"ll_angle: invalid image.");
772 if( threshold < 0.0 )
error(
"ll_angle: 'threshold' must be positive.");
773 if( list_p ==
NULL )
error(
"ll_angle: NULL pointer 'list_p'.");
774 if( mem_p ==
NULL )
error(
"ll_angle: NULL pointer 'mem_p'.");
775 if( modgrad ==
NULL )
error(
"ll_angle: NULL pointer 'modgrad'.");
776 if( n_bins == 0 )
error(
"ll_angle: 'n_bins' must be positive.");
789 list = (
struct coorlist *) calloc( (
size_t) (n*p),
sizeof(
struct coorlist) );
790 *mem_p = (
void *) list;
791 range_l_s = (
struct coorlist **) calloc( (
size_t) n_bins,
793 range_l_e = (
struct coorlist **) calloc( (
size_t) n_bins,
795 if( list ==
NULL || range_l_s ==
NULL || range_l_e ==
NULL )
796 error(
"not enough memory.");
797 for(i=0;i<n_bins;i++) range_l_s[i] = range_l_e[i] =
NULL;
820 com1 = in->data[adr+p+1] - in->data[adr];
821 com2 = in->data[adr+1] - in->data[adr+p];
826 norm = sqrt( norm2 / 4.0 );
828 (*modgrad)->data[adr] = norm;
830 if( norm <= threshold )
835 g->
data[adr] = atan2(gx,-gy);
838 if( norm > max_grad ) max_grad = norm;
846 norm = (*modgrad)->data[
y*p+
x];
849 i = (
unsigned int) (norm * (
double) n_bins / max_grad);
850 if( i >= n_bins ) i = n_bins-1;
851 if( range_l_e[i] ==
NULL )
852 range_l_s[i] = range_l_e[i] = list+list_count++;
855 range_l_e[i]->
next = list+list_count;
856 range_l_e[i] = list+list_count++;
858 range_l_e[i]->
x = (int)
x;
859 range_l_e[i]->
y = (int)
y;
868 for(i=n_bins-1; i>0 && range_l_s[i]==
NULL; i--);
869 start = range_l_s[i];
875 if( range_l_s[i] !=
NULL )
877 end->
next = range_l_s[i];
884 free( (
void *) range_l_s );
885 free( (
void *) range_l_e );
900 error(
"isaligned: invalid image 'angles'.");
901 if(
x < 0 || y < 0 || x >= (
int) angles->
xsize ||
y >= (
int) angles->
ysize )
902 error(
"isaligned: (x,y) out of the image.");
903 if( prec < 0.0 )
error(
"isaligned: 'prec' must be positive.");
918 if( theta < 0.0 ) theta = -theta;
922 if( theta < 0.0 ) theta = -theta;
925 return theta <= prec;
936 if( a < 0.0 ) a = -a;
982 static double q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
983 8687.24529705, 1168.92649479, 83.8676043424,
985 double a = (
x+0.5) * log(
x+5.5) - (
x+5.5);
991 a -= log(
x + (
double) n );
992 b += q[n] * pow(
x, (
double) n );
1016 return 0.918938533204673 + (
x-0.5)*log(
x) -
x
1017 + 0.5*
x*log(
x*sinh(1/
x) + 1/(810.0*pow(
x,6.0)) );
1025 #define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
1030 #define TABSIZE 100000
1074 static double nfa(
int n,
int k,
double p,
double logNT)
1077 double tolerance = 0.1;
1078 double log1term,term,bin_term,mult_term,bin_tail,err,p_term;
1082 if( n<0 || k<0 || k>n || p<=0.0 || p>=1.0 )
1083 error(
"nfa: wrong n, k or p values.");
1086 if( n==0 || k==0 )
return -logNT;
1087 if( n==k )
return -logNT - (double) n * log10(p);
1090 p_term = p / (1.0-p);
1102 + (double) k * log(p) + (double) (n-k) * log(1.0-p);
1103 term = exp(log1term);
1108 if( (
double) k > (
double) n * p )
1109 return -log1term /
M_LN10 - logNT;
1131 bin_term = (double) (n-i+1) * ( i<
TABSIZE ?
1132 ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (double) i ) ) :
1135 mult_term = bin_term * p_term;
1144 err = term * ( ( 1.0 - pow( mult_term, (
double) (n-i+1) ) ) /
1145 (1.0-mult_term) - 1.0 );
1155 if( err < tolerance *
fabs(-log10(bin_tail)-logNT) * bin_tail )
break;
1158 return -log10(bin_tail) - logNT;
1186 if( in ==
NULL || out ==
NULL )
error(
"rect_copy: invalid 'in' or 'out'.");
1193 out->width = in->width;
1196 out->theta = in->theta;
1199 out->prec = in->prec;
1277 static double inter_low(
double x,
double x1,
double y1,
double x2,
double y2)
1280 if( x1 > x2 || x < x1 || x > x2 )
1281 error(
"inter_low: unsuitable input, 'x1>x2' or 'x<x1' or 'x>x2'.");
1286 return y1 + (x-x1) * (y2-y1) / (x2-x1);
1299 static double inter_hi(
double x,
double x1,
double y1,
double x2,
double y2)
1302 if( x1 > x2 || x < x1 || x > x2 )
1303 error(
"inter_hi: unsuitable input, 'x1>x2' or 'x<x1' or 'x>x2'.");
1308 return y1 + (x-x1) * (y2-y1) / (x2-x1);
1316 if( iter ==
NULL )
error(
"ri_del: NULL iterator.");
1317 free( (
void *) iter );
1328 if( i ==
NULL )
error(
"ri_end: NULL iterator.");
1333 return (
double)(i->
x) > i->
vx[2];
1344 if( i ==
NULL )
error(
"ri_inc: NULL iterator.");
1353 while( (
double) (i->
y) > i->
ye && !
ri_end(i) )
1376 if( (
double) i->
x < i->
vx[3] )
1396 if( (
double)i->
x < i->
vx[1] )
1418 if( r ==
NULL )
error(
"ri_ini: invalid rectangle.");
1422 if( i ==
NULL )
error(
"ri_ini: Not enough memory.");
1469 i->
x = (int)
ceil(i->
vx[0]) - 1;
1471 i->
ys = i->
ye = -DBL_MAX;
1489 if( rec ==
NULL )
error(
"rect_nfa: invalid rectangle.");
1490 if( angles ==
NULL )
error(
"rect_nfa: invalid 'angles'.");
1494 if( i->
x >= 0 && i->
y >= 0 &&
1495 i->
x < (
int) angles->
xsize && i->
y < (int) angles->
ysize )
1503 return nfa(pts,alg,rec->
p,logNT);
1571 double lambda,theta,weight;
1578 if( reg ==
NULL )
error(
"get_theta: invalid region.");
1579 if( reg_size <= 1 )
error(
"get_theta: region size <= 1.");
1581 error(
"get_theta: invalid 'modgrad'.");
1582 if( prec < 0.0 )
error(
"get_theta: 'prec' must be positive.");
1585 for(i=0; i<reg_size; i++)
1587 weight = modgrad->
data[ reg[i].
x + reg[i].
y * modgrad->
xsize ];
1588 Ixx += ( (double) reg[i].y - y ) * ( (double) reg[i].y - y ) * weight;
1589 Iyy += ( (double) reg[i].x - x ) * ( (double) reg[i].x - x ) * weight;
1590 Ixy -= ( (double) reg[i].x - x ) * ( (double) reg[i].y - y ) * weight;
1593 error(
"get_theta: null inertia matrix.");
1596 lambda = 0.5 * ( Ixx + Iyy - sqrt( (Ixx-Iyy)*(Ixx-Iyy) + 4.0*Ixy*Ixy ) );
1599 theta =
fabs(Ixx)>
fabs(Iyy) ? atan2(lambda-Ixx,Ixy) : atan2(Ixy,lambda-Iyy);
1613 double prec,
double p,
struct rect * rec )
1615 double x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
1619 if( reg ==
NULL )
error(
"region2rect: invalid region.");
1620 if( reg_size <= 1 )
error(
"region2rect: region size <= 1.");
1622 error(
"region2rect: invalid image 'modgrad'.");
1623 if( rec ==
NULL )
error(
"region2rect: invalid 'rec'.");
1636 for(i=0; i<reg_size; i++)
1638 weight = modgrad->
data[ reg[i].
x + reg[i].
y * modgrad->
xsize ];
1639 x += (double) reg[i].x * weight;
1640 y += (double) reg[i].y * weight;
1643 if( sum <= 0.0 )
error(
"region2rect: weights sum equal to zero.");
1648 theta =
get_theta(reg,reg_size,x,y,modgrad,reg_angle,prec);
1664 l_min = l_max = w_min = w_max = 0.0;
1665 for(i=0; i<reg_size; i++)
1667 l = ( (double) reg[i].x - x) * dx + ( (double) reg[i].y - y) * dy;
1668 w = -( (double) reg[i].x - x) * dy + ( (double) reg[i].y - y) * dx;
1670 if( l > l_max ) l_max = l;
1671 if( l < l_min ) l_min = l;
1672 if( w > w_max ) w_max = w;
1673 if( w < w_min ) w_min = w;
1677 rec->
x1 = x + l_min * dx;
1678 rec->
y1 = y + l_min * dy;
1679 rec->
x2 = x + l_max * dx;
1680 rec->
y2 = y + l_max * dy;
1681 rec->
width = w_max - w_min;
1705 int * reg_size,
double * reg_angle,
image_char used,
1712 if( x < 0 || y < 0 || x >= (
int) angles->
xsize || y >= (
int) angles->
ysize )
1713 error(
"region_grow: (x,y) out of the image.");
1715 error(
"region_grow: invalid image 'angles'.");
1716 if( reg ==
NULL )
error(
"region_grow: invalid 'reg'.");
1717 if( reg_size ==
NULL )
error(
"region_grow: invalid pointer 'reg_size'.");
1718 if( reg_angle ==
NULL )
error(
"region_grow: invalid pointer 'reg_angle'.");
1720 error(
"region_grow: invalid image 'used'.");
1726 *reg_angle = angles->
data[x+y*angles->
xsize];
1727 sumdx = cos(*reg_angle);
1728 sumdy = sin(*reg_angle);
1732 for(i=0; i<*reg_size; i++)
1733 for(xx=reg[i].x-1; xx<=reg[i].
x+1; xx++)
1734 for(yy=reg[i].y-1; yy<=reg[i].
y+1; yy++)
1735 if( xx>=0 && yy>=0 && xx<(
int)used->
xsize && yy<(
int)used->
ysize &&
1737 isaligned(xx,yy,angles,*reg_angle,prec) )
1741 reg[*reg_size].
x = xx;
1742 reg[*reg_size].
y = yy;
1746 sumdx += cos( angles->
data[xx+yy*angles->
xsize] );
1747 sumdy += sin( angles->
data[xx+yy*angles->
xsize] );
1748 *reg_angle = atan2(sumdy,sumdx);
1757 double logNT,
double log_eps )
1760 double log_nfa,log_nfa_new;
1762 double delta_2 = delta / 2.0;
1765 log_nfa =
rect_nfa(rec,angles,logNT);
1767 if( log_nfa > log_eps )
return log_nfa;
1775 log_nfa_new =
rect_nfa(&r,angles,logNT);
1776 if( log_nfa_new > log_nfa )
1778 log_nfa = log_nfa_new;
1783 if( log_nfa > log_eps )
return log_nfa;
1789 if( (r.
width - delta) >= 0.5 )
1792 log_nfa_new =
rect_nfa(&r,angles,logNT);
1793 if( log_nfa_new > log_nfa )
1796 log_nfa = log_nfa_new;
1801 if( log_nfa > log_eps )
return log_nfa;
1807 if( (r.
width - delta) >= 0.5 )
1809 r.
x1 += -r.
dy * delta_2;
1810 r.
y1 += r.
dx * delta_2;
1811 r.
x2 += -r.
dy * delta_2;
1812 r.
y2 += r.
dx * delta_2;
1814 log_nfa_new =
rect_nfa(&r,angles,logNT);
1815 if( log_nfa_new > log_nfa )
1818 log_nfa = log_nfa_new;
1823 if( log_nfa > log_eps )
return log_nfa;
1829 if( (r.
width - delta) >= 0.5 )
1831 r.
x1 -= -r.
dy * delta_2;
1832 r.
y1 -= r.
dx * delta_2;
1833 r.
x2 -= -r.
dy * delta_2;
1834 r.
y2 -= r.
dx * delta_2;
1836 log_nfa_new =
rect_nfa(&r,angles,logNT);
1837 if( log_nfa_new > log_nfa )
1840 log_nfa = log_nfa_new;
1845 if( log_nfa > log_eps )
return log_nfa;
1853 log_nfa_new =
rect_nfa(&r,angles,logNT);
1854 if( log_nfa_new > log_nfa )
1856 log_nfa = log_nfa_new;
1871 double prec,
double p,
struct rect * rec,
1875 double density,rad1,rad2,rad,xc,yc;
1879 if( reg ==
NULL )
error(
"reduce_region_radius: invalid pointer 'reg'.");
1880 if( reg_size ==
NULL )
1881 error(
"reduce_region_radius: invalid pointer 'reg_size'.");
1882 if(
prec < 0.0 )
error(
"reduce_region_radius: 'prec' must be positive.");
1883 if( rec ==
NULL )
error(
"reduce_region_radius: invalid pointer 'rec'.");
1885 error(
"reduce_region_radius: invalid image 'used'.");
1887 error(
"reduce_region_radius: invalid image 'angles'.");
1890 density = (double) *reg_size /
1894 if( density >= density_th )
return TRUE;
1897 xc = (double) reg[0].
x;
1898 yc = (double) reg[0].
y;
1899 rad1 =
dist( xc, yc, rec->
x1, rec->
y1 );
1900 rad2 =
dist( xc, yc, rec->
x2, rec->
y2 );
1901 rad = rad1 > rad2 ? rad1 : rad2;
1904 while( density < density_th )
1909 for(i=0; i<*reg_size; i++)
1910 if(
dist( xc, yc, (
double) reg[i].
x, (
double) reg[i].
y ) > rad )
1915 reg[i].
x = reg[*reg_size-1].
x;
1916 reg[i].
y = reg[*reg_size-1].
y;
1923 if( *reg_size < 2 )
return FALSE;
1929 density = (double) *reg_size /
1948 double reg_angle,
double prec,
double p,
struct rect * rec,
1951 double angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
1955 if( reg ==
NULL )
error(
"refine: invalid pointer 'reg'.");
1956 if( reg_size ==
NULL )
error(
"refine: invalid pointer 'reg_size'.");
1957 if(
prec < 0.0 )
error(
"refine: 'prec' must be positive.");
1958 if( rec ==
NULL )
error(
"refine: invalid pointer 'rec'.");
1960 error(
"refine: invalid image 'used'.");
1962 error(
"refine: invalid image 'angles'.");
1965 density = (double) *reg_size /
1969 if( density >= density_th )
return TRUE;
1974 xc = (double) reg[0].
x;
1975 yc = (double) reg[0].
y;
1976 ang_c = angles->
data[ reg[0].
x + reg[0].
y * angles->
xsize ];
1979 for(i=0; i<*reg_size; i++)
1982 if(
dist( xc, yc, (
double) reg[i].
x, (double) reg[i].
y ) < rec->
width )
1984 angle = angles->
data[ reg[i].
x + reg[i].
y * angles->
xsize ];
1987 s_sum += ang_d * ang_d;
1991 mean_angle = sum / (double) n;
1992 tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (
double) n
1993 + mean_angle*mean_angle );
1996 region_grow(reg[0].
x,reg[0].
y,angles,reg,reg_size,®_angle,used,tau);
1999 if( *reg_size < 2 )
return FALSE;
2005 density = (double) *reg_size /
2009 if( density < density_th )
2011 rec, used, angles, density_th );
2026 double * img,
int X,
int Y,
2027 double scale,
double sigma_scale,
double quant,
2028 double ang_th,
double log_eps,
double density_th,
2030 int ** reg_img,
int * reg_x,
int * reg_y )
2034 double * return_value;
2042 int reg_size,min_reg_size,i;
2043 unsigned int xsize,ysize;
2044 double rho,reg_angle,prec,p,log_nfa,logNT;
2049 if( img ==
NULL ||
X <= 0 || Y <= 0 )
error(
"invalid image input.");
2050 if( scale <= 0.0 )
error(
"'scale' value must be positive.");
2051 if( sigma_scale <= 0.0 )
error(
"'sigma_scale' value must be positive.");
2052 if(
quant < 0.0 )
error(
"'quant' value must be positive.");
2053 if( ang_th <= 0.0 || ang_th >= 180.0 )
2054 error(
"'ang_th' value must be in the range (0,180).");
2055 if( density_th < 0.0 || density_th > 1.0 )
2056 error(
"'density_th' value must be in the range [0,1].");
2057 if( n_bins <= 0 )
error(
"'n_bins' value must be positive.");
2061 prec =
M_PI * ang_th / 180.0;
2063 rho =
quant / sin(prec);
2071 angles =
ll_angle( scaled_image, rho, &list_p, &mem_p,
2072 &modgrad, (
unsigned int) n_bins );
2077 (
unsigned int) n_bins );
2078 xsize = angles->
xsize;
2079 ysize = angles->
ysize;
2094 logNT = 5.0 * ( log10( (
double) xsize ) + log10( (
double) ysize ) ) / 2.0
2096 min_reg_size = (int) (-logNT/log10(p));
2101 if( reg_img !=
NULL && reg_x !=
NULL && reg_y !=
NULL )
2104 reg = (
struct point *) calloc( (
size_t) (xsize*ysize),
sizeof(
struct point) );
2105 if( reg ==
NULL )
error(
"not enough memory!");
2109 for(; list_p !=
NULL; list_p = list_p->
next )
2117 ®_angle, used, prec );
2120 if( reg_size < min_reg_size )
continue;
2123 region2rect(reg,reg_size,modgrad,reg_angle,prec,p,&rec);
2134 if( !
refine( reg, ®_size, modgrad, reg_angle,
2135 prec, p, &rec, used, angles, density_th ) )
continue;
2139 if( log_nfa <= log_eps )
continue;
2149 rec.
x1 += 0.5; rec.
y1 += 0.5;
2150 rec.
x2 += 0.5; rec.
y2 += 0.5;
2155 rec.
x1 /= scale; rec.
y1 /= scale;
2156 rec.
x2 /= scale; rec.
y2 /= scale;
2162 rec.
width, rec.
p, log_nfa );
2165 if( region !=
NULL )
2166 for(i=0; i<reg_size; i++)
2167 region->
data[ reg[i].
x + reg[i].
y * region->
xsize ] = ls_count;
2172 free( (
void *)
image );
2178 free( (
void *) reg );
2179 free( (
void *) mem_p );
2182 if( reg_img !=
NULL && reg_x !=
NULL && reg_y !=
NULL )
2184 if( region ==
NULL )
error(
"'region' should be a valid image.");
2185 *reg_img = region->
data;
2186 if( region->
xsize > (
unsigned int) INT_MAX ||
2187 region->
xsize > (
unsigned int) INT_MAX )
2188 error(
"region image to big to fit in INT sizes.");
2189 *reg_x = (int) (region->
xsize);
2190 *reg_y = (int) (region->
ysize);
2195 free( (
void *) region );
2197 if( out->size > (
unsigned int) INT_MAX )
2198 error(
"too many detections to fit in an INT.");
2199 *n_out = (int) (out->size);
2201 return_value = out->values;
2202 free( (
void *) out );
2206 return return_value;
2213 double * img,
int X,
int Y,
double scale,
2214 int ** reg_img,
int * reg_x,
int * reg_y )
2217 double sigma_scale = 0.6;
2221 double ang_th = 22.5;
2222 double log_eps = 0.0;
2223 double density_th = 0.7;
2228 ang_th, log_eps, density_th, n_bins,
2229 reg_img, reg_x, reg_y );
2235 double *
lsd_scale(
int * n_out,
double * img,
int X,
int Y,
double scale)
2243 double *
lsd(
int * n_out,
double * img,
int X,
int Y)
std::shared_ptr< core::Tensor > image
__host__ __device__ float2 fabs(float2 v)
static image_int new_image_int(unsigned int xsize, unsigned int ysize)
static ntuple_list new_ntuple_list(unsigned int dim)
static void region2rect(struct point *reg, int reg_size, image_double modgrad, double reg_angle, double prec, double p, struct rect *rec)
static double get_theta(struct point *reg, int reg_size, double x, double y, image_double modgrad, double reg_angle, double prec)
double * lsd_scale(int *n_out, double *img, int X, int Y, double scale)
static double dist(double x1, double y1, double x2, double y2)
static void enlarge_ntuple_list(ntuple_list n_tuple)
static rect_iter * ri_ini(struct rect *r)
static int ri_end(rect_iter *i)
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)
static void free_ntuple_list(ntuple_list in)
static image_double ll_angle(image_double in, double threshold, struct coorlist **list_p, void **mem_p, image_double *modgrad, unsigned int n_bins)
struct image_double_s * image_double
static double angle_diff(double a, double b)
static double log_gamma_windschitl(double x)
static image_double gaussian_sampler(image_double in, double scale, double sigma_scale)
static image_char new_image_char(unsigned int xsize, unsigned int ysize)
#define RELATIVE_ERROR_FACTOR
static image_int new_image_int_ini(unsigned int xsize, unsigned int ysize, int fill_value)
static double rect_improve(struct rect *rec, image_double angles, double logNT, double log_eps)
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)
static void add_7tuple(ntuple_list out, double v1, double v2, double v3, double v4, double v5, double v6, double v7)
double * lsd_scale_region(int *n_out, double *img, int X, int Y, double scale, int **reg_img, int *reg_x, int *reg_y)
static image_double new_image_double(unsigned int xsize, unsigned int ysize)
static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
struct ntuple_list_s * ntuple_list
double * lsd(int *n_out, double *img, int X, int Y)
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)
static void rect_copy(struct rect *in, struct rect *out)
static double rect_nfa(struct rect *rec, image_double angles, double logNT)
static double nfa(int n, int k, double p, double logNT)
static void error(char *msg)
static image_char new_image_char_ini(unsigned int xsize, unsigned int ysize, unsigned char fill_value)
static void ri_del(rect_iter *iter)
static void free_image_char(image_char i)
static double inter_hi(double x, double x1, double y1, double x2, double y2)
static double angle_diff_signed(double a, double b)
static image_double new_image_double_ptr(unsigned int xsize, unsigned int ysize, double *data)
static double inter_low(double x, double x1, double y1, double x2, double y2)
struct image_char_s * image_char
static double log_gamma_lanczos(double x)
static void free_image_double(image_double i)
static int double_equal(double a, double b)
static int isaligned(int x, int y, image_double angles, double theta, double prec)
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)
static void ri_inc(rect_iter *i)
T1::value_type quant(T1 &x, const T2 &q)
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)