1414
1515type OctagonFilter <: BiFilter
1616
17- filter :: Array{Float64, 2}
18- m_out :: UInt8
19- m_in :: UInt8
20- n_out :: UInt8
21- n_in :: UInt8
17+ m_out :: Integer
18+ m_in :: Integer
19+ n_out :: Integer
20+ n_in :: Integer
21+ in_area :: Float64
22+ out_area :: Float64
23+ in_weight :: Float64
24+ out_weight :: Float64
2225
2326end
2427
@@ -33,33 +36,21 @@ type CENSURE <: Detector
3336
3437end
3538
36- function createFilter (OF:: OctagonFilter )
37- area_out = (OF. m_out + 2 * OF. n_out) ^ 2 - 2 * OF. n_out ^ 2
38- area_in = (OF. m_in + 2 * OF. n_in) ^ 2 - 2 * OF. n_in ^ 2
39- weight_out = 1.0 / (area_out - area_in)
40- weight_in = 1.0 / area_in
41- OF. filter[:, :] = weight_out
42- inner_start = Int (0.5 * ((OF. m_out + 2 * OF. n_out) - (OF. m_in + 2 * OF. n_in)))
43- OF. filter[inner_start + 1 : end - inner_start, inner_start + 1 : end - inner_start] = weight_in
44-
45- for i in 1 : OF. n_in
46- OF. filter[inner_start + i, inner_start + 1 : inner_start + OF. n_in - i + 1 ] = weight_out
47- OF. filter[inner_start + i, inner_start + OF. n_in + OF. m_in + i : inner_start + OF. m_in + 2 * OF. n_in] = weight_out
48- OF. filter[inner_start + OF. m_in + 2 * OF. n_in - i + 1 , inner_start + 1 : inner_start + OF. n_in - i + 1 ] = weight_out
49- OF. filter[inner_start + OF. m_in + 2 * OF. n_in - i + 1 , inner_start + OF. n_in + OF. m_in + i : inner_start + OF. m_in + 2 * OF. n_in] = weight_out
50- end
51-
52- for i in 1 : OF. n_out
53- OF. filter[i, 1 : OF. n_out - i + 1 ] = 0
54- OF. filter[i, OF. n_out + OF. m_out + i : OF. m_out + 2 * OF. n_out] = 0
55- OF. filter[OF. m_out + 2 * OF. n_out - i + 1 , 1 : OF. n_out - i + 1 ] = 0
56- OF. filter[OF. m_out + 2 * OF. n_out - i + 1 , OF. n_out + OF. m_out + i : OF. m_out + 2 * OF. n_out] = 0
57- end
58-
39+ function OctagonFilter (mo, mi, no, ni)
40+ OF = OctagonFilter (mo, mi, no, ni, 0.0 , 0.0 , 0.0 , 0.0 )
41+ OF. out_area = OF. m_out ^ 2 + 2 * OF. n_out ^ 2 + 4 * OF. m_out * OF. n_out
42+ OF. in_area = OF. m_in ^ 2 + 2 * OF. n_in ^ 2 + 4 * OF. m_in * OF. n_in
43+ OF. out_weight = 1.0 / (OF. out_area - OF. in_area)
44+ OF. in_weight = 1.0 / OF. in_area
45+ OF
5946end
6047
61- OctagonFilter (mo, mi, no, ni) = (OF = OctagonFilter (ones (Float64, mo + 2 * no, mo + 2 * no), mo, mi, no, ni); createFilter (OF); OF)
62- BoxFilter (s) = (BF = BoxFilter (s, 2 * s + 1 , 4 * s + 1 , (2 * s + 1 ) ^ 2 , (4 * s + 1 ) ^ 2 , 0.0 , 0.0 ); BF. in_weight = 1.0 / BF. in_area; BF. out_weight = 1.0 / (BF. out_area - BF. in_area); BF; )
48+ function BoxFilter (s)
49+ BF = BoxFilter (s, 2 * s + 1 , 4 * s + 1 , (2 * s + 1 ) ^ 2 , (4 * s + 1 ) ^ 2 , 0.0 , 0.0 )
50+ BF. in_weight = 1.0 / BF. in_area
51+ BF. out_weight = 1.0 / (BF. out_area - BF. in_area)
52+ BF
53+ end
6354
6455OctagonFilter_Kernels = [
6556 [5 , 3 , 2 , 0 ],
@@ -80,18 +71,45 @@ function getFilterStack(filter_type::Type, smallest::Integer, largest::Integer)
8071 filter_stack = map (f -> filter_type (f... ), k[smallest : largest])
8172end
8273
83- function filterResponse {T} (int_img:: AbstractArray{T, 2} , filter:: BoxFilter )
84- margin = filter. scale * 2
85- n = filter. scale
74+ getIntegralImage (img, filter_type:: BoxFilter ) = integral_image (img)
75+
76+ function getIntegralImage (img, filter_type:: OctagonFilter )
77+ img_shape = size (img)
78+ int_img = zeros (img_shape)
79+ right_slant_img = zeros (img_shape)
80+ left_slant_img = zeros (img_shape)
81+
82+ int_img[1 , :] = cumsum (img[1 , :])
83+ right_slant_img[1 , :] = int_img[1 , :]
84+ left_slant_img[1 , :] = int_img[1 , :]
85+
86+ for i in 2 : img_shape[1 ]
87+ sum = 0.0
88+ for j in 1 : img_shape[2 ]
89+ sum += img[i, j]
90+ int_img[i, j] = sum + int_img[i - 1 , j]
91+ left_slant_img[i, j] = sum
92+ right_slant_img[i, j] = sum
93+
94+ if j > 1 left_slant_img[i, j] += left_slant_img[i - 1 , j - 1 ] end
95+ right_slant_img[i, j] += j < img_shape[2 ] ? right_slant_img[i - 1 , j + 1 ] : right_slant_img[i - 1 , j]
96+ end
97+ end
98+ int_img, right_slant_img, left_slant_img
99+ end
100+
101+ function filterResponse {T} (int_img:: AbstractArray{T, 2} , BF:: BoxFilter )
102+ margin = BF. scale * 2
103+ n = BF. scale
86104 img_shape = size (int_img)
87105 response = zeros (img_shape)
88106 R = CartesianRange (CartesianIndex ((margin + 1 , margin + 1 )), CartesianIndex ((img_shape[1 ] - margin, img_shape[2 ] - margin)))
89107 in_sum = 0.0
90108 out_sum = 0.0
91109 for I in R
92110 topleft = I + CartesianIndex (- n - 1 , - n - 1 )
93- topright = I + CartesianIndex (n, - n - 1 )
94- bottomleft = I + CartesianIndex (- n - 1 , n )
111+ topright = I + CartesianIndex (- n - 1 , n )
112+ bottomleft = I + CartesianIndex (n, - n - 1 )
95113 bottomright = I + CartesianIndex (n, n)
96114 A = topleft >= CartesianIndex (1 , 1 ) ? int_img[topleft] : 0.0
97115 B = topright >= CartesianIndex (1 , 1 ) ? int_img[topright] : 0.0
@@ -100,52 +118,100 @@ function filterResponse{T}(int_img::AbstractArray{T, 2}, filter::BoxFilter)
100118 in_sum = A + D - B - C
101119
102120 topleft = I + CartesianIndex (- 2 * n - 1 , - 2 * n - 1 )
103- topright = I + CartesianIndex (2 * n, - 2 * n - 1 )
104- bottomleft = I + CartesianIndex (- 2 * n - 1 , 2 * n)
121+ topright = I + CartesianIndex (- 2 * n - 1 , 2 * n)
122+ bottomleft = I + CartesianIndex (2 * n, - 2 * n - 1 )
105123 bottomright = I + CartesianIndex (2 * n, 2 * n)
106124 A = topleft >= CartesianIndex (1 , 1 ) ? int_img[topleft] : 0.0
107125 B = topright >= CartesianIndex (1 , 1 ) ? int_img[topright] : 0.0
108126 C = bottomleft >= CartesianIndex (1 , 1 ) ? int_img[bottomleft] : 0.0
109127 D = bottomright >= CartesianIndex (1 , 1 ) ? int_img[bottomright] : 0.0
110128 out_sum = A + D - B - C - in_sum
111129
112- response[I] = in_sum * filter . in_weight - out_sum * filer . out_weight
130+ response[I] = in_sum * BF . in_weight - out_sum * BF . out_weight
113131 end
114132
115133 response
116134end
117135
118- function filterResponse (int_imgs:: Tuple , filter :: OctagonFilter )
136+ function filterResponse (int_imgs:: Tuple , OF :: OctagonFilter )
119137 int_img = int_imgs[1 ]
120138 rs_img = int_imgs[2 ]
121139 ls_img = int_imgs[3 ]
122- end
123140
124- getIntegralImage (img, filter_type:: BoxFilter ) = integral_image (img)
125-
126- function getIntegralImage (img, filter_type:: OctagonFilter )
127- img_shape = size (img)
128- int_img = zeros (img_shape)
129- right_slant_img = zeros (img_shape)
130- left_slant_img = zeros (img_shape)
141+ margin = Int (floor (OF. m_out / 2 + OF. n_out))
142+ m_in2 = Int (floor (OF. m_in / 2 ))
143+ m_out2 = Int (floor (OF. m_out / 2 ))
131144
132- int_img[1 , :] = cumsum (img[1 , :])
133- right_slant_img[1 , :] = int_img[1 , :]
134- left_slant_img[1 , :] = int_img[1 , :]
145+ img_shape = size (int_img)
146+ response = zeros (img_shape)
147+ R = CartesianRange (CartesianIndex ((margin + 1 , margin + 1 )), CartesianIndex ((img_shape[1 ] - margin, img_shape[2 ] - margin)))
148+
149+ for I in R
150+ topleft = I + CartesianIndex (- m_in2 - 1 , - m_in2 - OF. n_in - 1 )
151+ topright = I + CartesianIndex (m_in2, - m_in2 - OF. n_in - 1 )
152+ bottomleft = I + CartesianIndex (- m_in2 - 1 , m_in2 + OF. n_in)
153+ bottomright = I + CartesianIndex (m_in2, m_in2 + OF. n_in)
154+ A = topleft >= CartesianIndex (1 , 1 ) ? int_img[topleft] : 0.0
155+ B = topright >= CartesianIndex (1 , 1 ) ? int_img[topright] : 0.0
156+ C = bottomleft >= CartesianIndex (1 , 1 ) ? int_img[bottomleft] : 0.0
157+ D = bottomright >= CartesianIndex (1 , 1 ) ? int_img[bottomright] : 0.0
158+ in_sum = A + D - B - C
135159
136- for i in 2 : img_shape[1 ]
137- sum = 0.0
138- for j in 1 : img_shape[2 ]
139- sum += img[i, j]
140- int_img[i, j] = sum + int_img[i - 1 , j]
141- left_slant_img[i, j] = sum
142- right_slant_img[i, j] = sum
160+ trap_top_right = bottomright
161+ trap_bot_right = I + CartesianIndex (m_in2 + OF. n_in, m_in2)
162+ trap_top_left = I + CartesianIndex (m_in2, - m_in2 - OF. n_in)
163+ trap_bot_left = I + CartesianIndex (m_in2 + OF. n_in, - m_in2 - 1 )
164+ A = trap_top_left >= CartesianIndex (1 , 1 ) ? ls_img[trap_top_left] : 0.0
165+ B = trap_top_right >= CartesianIndex (1 , 1 ) ? rs_img[trap_top_right] : 0.0
166+ C = trap_bot_left >= CartesianIndex (1 , 1 ) ? ls_img[trap_bot_left] : 0.0
167+ D = trap_bot_right >= CartesianIndex (1 , 1 ) ? rs_img[trap_bot_right] : 0.0
168+ in_sum += A + D - B - C
169+
170+ trap_top_right = I + CartesianIndex (- m_in2 - OF. n_in - 1 , m_in2 - 1 )
171+ trap_top_left = I + CartesianIndex (- m_in2 - OF. n_in - 1 , - m_in2)
172+ trap_bot_right = I + CartesianIndex (- m_in2 - 1 , m_in2 + OF. n_in - 1 )
173+ trap_bot_left = I + CartesianIndex (- m_in2 - 1 , - m_in2 - OF. n_in)
174+ A = trap_top_left >= CartesianIndex (1 , 1 ) ? rs_img[trap_top_left] : 0.0
175+ B = trap_top_right >= CartesianIndex (1 , 1 ) ? ls_img[trap_top_right] : 0.0
176+ C = trap_bot_left >= CartesianIndex (1 , 1 ) ? rs_img[trap_bot_left] : 0.0
177+ D = trap_bot_right >= CartesianIndex (1 , 1 ) ? ls_img[trap_bot_right] : 0.0
178+ in_sum += A + D - B - C
179+
180+ topleft = I + CartesianIndex (- m_out2 - 1 , - m_out2 - OF. n_out - 1 )
181+ topright = I + CartesianIndex (m_out2, - m_out2 - OF. n_out - 1 )
182+ bottomleft = I + CartesianIndex (- m_out2 - 1 , m_out2 + OF. n_out)
183+ bottomright = I + CartesianIndex (m_out2, m_out2 + OF. n_out)
184+ A = topleft >= CartesianIndex (1 , 1 ) ? int_img[topleft] : 0.0
185+ B = topright >= CartesianIndex (1 , 1 ) ? int_img[topright] : 0.0
186+ C = bottomleft >= CartesianIndex (1 , 1 ) ? int_img[bottomleft] : 0.0
187+ D = bottomright >= CartesianIndex (1 , 1 ) ? int_img[bottomright] : 0.0
188+ out_sum = A + D - B - C
189+
190+ trap_top_right = bottomright
191+ trap_bot_right = I + CartesianIndex (m_out2 + OF. n_out, m_out2)
192+ trap_top_left = I + CartesianIndex (m_out2, - m_out2 - OF. n_out)
193+ trap_bot_left = I + CartesianIndex (m_out2 + OF. n_out, - m_out2 - 1 )
194+ A = trap_top_left >= CartesianIndex (1 , 1 ) ? ls_img[trap_top_left] : 0.0
195+ B = trap_top_right >= CartesianIndex (1 , 1 ) ? rs_img[trap_top_right] : 0.0
196+ C = trap_bot_left >= CartesianIndex (1 , 1 ) ? ls_img[trap_bot_left] : 0.0
197+ D = trap_bot_right >= CartesianIndex (1 , 1 ) ? rs_img[trap_bot_right] : 0.0
198+ out_sum += A + D - B - C
199+
200+ trap_top_right = I + CartesianIndex (- m_out2 - OF. n_out - 1 , m_out2 - 1 )
201+ trap_top_left = I + CartesianIndex (- m_out2 - OF. n_out - 1 , - m_out2)
202+ trap_bot_right = I + CartesianIndex (- m_out2 - 1 , m_out2 + OF. n_out - 1 )
203+ trap_bot_left = I + CartesianIndex (- m_out2 - 1 , - m_out2 - OF. n_out)
204+ A = trap_top_left >= CartesianIndex (1 , 1 ) ? rs_img[trap_top_left] : 0.0
205+ B = trap_top_right >= CartesianIndex (1 , 1 ) ? ls_img[trap_top_right] : 0.0
206+ C = trap_bot_left >= CartesianIndex (1 , 1 ) ? rs_img[trap_bot_left] : 0.0
207+ D = trap_bot_right >= CartesianIndex (1 , 1 ) ? ls_img[trap_bot_right] : 0.0
208+ out_sum += A + D - B - C
209+ out_sum = out_sum - in_sum
143210
144- if j > 1 left_slant_img[i, j] += left_slant_img[i - 1 , j - 1 ] end
145- right_slant_img[i, j] += j < img_shape[2 ] ? right_slant_img[i - 1 , j + 1 ] : right_slant_img[i - 1 , j]
146- end
147- end
148- int_img, right_slant_img, left_slant_img
211+ response[I] = in_sum * filter. in_weight - out_sum * filer. out_weight
212+ end
213+ response
214+
149215end
150216
151217CENSURE (; smallest:: Integer = 1 , largest:: Integer = 7 , filter:: Type = BoxFilter, responseThreshold:: Number = 0.15 , lineThreshold:: Number = 10 ) = CENSURE (smallest, largest, filter, getFilterStack (filter, smallest, largest), responseThreshold, lineThreshold)
0 commit comments