1+ """
2+ PCLines transform for line detection
3+
4+ This package implements the method from
5+ Dubska et al, PCLines - Line detection with parallel coordinates, CVPR 2011
6+
7+ """
8+
9+ import numpy as np
10+ import numba as nb
11+ from skimage .feature import peak_local_max
12+ from skimage .morphology .grey import erosion , dilation
13+
14+
15+ def linear_transform (src , dst ):
16+ (s0 , s1 ), (d0 ,d1 ) = src , dst
17+ w = (d1 - d0 ) / (s1 - s0 )
18+ b = d0 - w * s0
19+ return w , b
20+
21+
22+ class Normalizer :
23+ def __init__ (self , src_range , dst_range = (0 ,1 )):
24+ self .w , self .b = linear_transform (src_range , dst_range )
25+ self .wi , self .bi = linear_transform (dst_range , src_range )
26+
27+ def transform (self , x ):
28+ """ src -> dst """
29+ return self .w * x + self .b
30+
31+ def inverse (self , x ):
32+ """ dst -> src """
33+ return self .wi * x + self .bi
34+
35+ __call__ = transform
36+
37+
38+ def accumulate (x , bbox = None , d = 256 ):
39+ """
40+ Accumulate observation in PCLines space
41+
42+ bbox : tuple
43+ (x,y,w,h) format
44+ """
45+ # Create accumulator
46+ acc_shape = d ,2 * d - 1
47+ A = np .zeros (acc_shape , "f" ) # The accumulator
48+
49+ if bbox is None :
50+ # autodetection of bbox
51+ pass
52+
53+ # Normalizers
54+ def normalizers ():
55+ x ,y ,w ,h = bbox
56+ shape = (w ,h )
57+ ranges = d * np .array (shape )/ max (shape )
58+ ofs = (d - ranges ) / 2
59+ (x0 ,y0 ),(x1 ,y1 ) = ofs , (ranges - 1 )+ ofs
60+ print (bbox )
61+ norm0 = Normalizer ((y ,y + h ), (y0 , y1 ))
62+ norm1 = Normalizer ((x ,x + w ), (x0 , x1 ))
63+ norm2 = Normalizer ((y ,y + h ), (y1 , y0 ))
64+ return norm0 , norm1 , norm2
65+
66+ norm0 , norm1 , norm2 = normalizers ()
67+
68+ x = [
69+ norm0 (x [:,1 ]),
70+ norm1 (x [:,0 ]),
71+ norm2 (x [:,1 ])
72+ ]
73+
74+ for a ,b ,c in zip (* x ):
75+ t_part = np .linspace (a ,b ,d )
76+ s_part = np .linspace (b ,c ,d )
77+ c = np .arange (2 * d - 1 ,dtype = "i" )
78+ r = np .concatenate ([t_part , s_part [1 :]]).astype ("i" )
79+ #print(r,c)
80+ A [r ,c ] += 1
81+
82+ return A
83+
84+
85+ def lines_parameters (shape , d , peaks ):
86+ P = [u ,v ]
87+ #centrovanie
88+ u = u - (d - 1 )
89+ m = max (shape ) - 1
90+ normV = Normalizer ((0 ,d - 1 ),(- m / 2 , m / 2 ))
91+ v = normV .transform (v )
92+
93+ if (u < d ):
94+ l = [d - u , u , - v * d ]
95+ else :
96+ l = [d + u , u , - v * d ]
97+
98+
99+
100+
101+ # @nb.njit("(f4[:,:],f4[:,:])")
102+ # def rasterize_lines(lines, acc):
103+ # """
104+ # """
105+ # d = acc.shape[1]
106+ # for i in range(lines.shape[0]):
107+ # y0, y1 = lines[i]
108+ # dy = (y1 - y0) / (d-1)
109+ # y = y0
110+ # for x in range(d):
111+ # acc[x,y] += 1
112+ # y += dy
113+
114+
115+
116+ def find_peaks (A , t ):
117+ prominence = dilation (A + 1 )/ erosion (A + 1 )
118+ peaks = peak_local_max (A , threshold_abs = t )
119+ c ,r = peaks [:,0 ], peaks [:,1 ]
120+ value = A [r ,c ]
121+ valid = prominence [r ,c ] > 1.5
122+ return peaks [valid ], value [valid ]
123+
0 commit comments