EG version upgrade to 1.3
[ealt-edge.git] / example-apps / PDD / pcb-defect-detection / libs / box_utils / cython_utils / bbox.pyx
1 # --------------------------------------------------------
2 # Fast R-CNN
3 # Copyright (c) 2015 Microsoft
4 # Licensed under The MIT License [see LICENSE for details]
5 # Written by Sergey Karayev
6 # --------------------------------------------------------
7
8 cimport cython
9 import numpy as np
10 cimport numpy as np
11
12 DTYPE = np.float
13 ctypedef np.float_t DTYPE_t
14
15 def bbox_overlaps_float(
16         np.ndarray[DTYPE_t, ndim=2] boxes,
17         np.ndarray[DTYPE_t, ndim=2] query_boxes):
18     """
19     Parameters
20     ----------
21     boxes: (N, 4) ndarray of float
22     query_boxes: (K, 4) ndarray of float
23     Returns
24     -------
25     overlaps: (N, K) ndarray of overlap between boxes and query_boxes
26     """
27     cdef unsigned int N = boxes.shape[0]
28     cdef unsigned int K = query_boxes.shape[0]
29     cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)
30     cdef DTYPE_t iw, ih, box_area
31     cdef DTYPE_t ua
32     cdef unsigned int k, n
33     for k in range(K):
34         box_area = (
35             (query_boxes[k, 2] - query_boxes[k, 0]) *
36             (query_boxes[k, 3] - query_boxes[k, 1])
37         )
38         for n in range(N):
39             iw = (
40                 min(boxes[n, 2], query_boxes[k, 2]) -
41                 max(boxes[n, 0], query_boxes[k, 0])
42             )
43             if iw > 0:
44                 ih = (
45                     min(boxes[n, 3], query_boxes[k, 3]) -
46                     max(boxes[n, 1], query_boxes[k, 1])
47                 )
48                 if ih > 0:
49                     ua = float(
50                         (boxes[n, 2] - boxes[n, 0]) *
51                         (boxes[n, 3] - boxes[n, 1]) +
52                         box_area - iw * ih
53                     )
54                     # if query_boxes[k, 4] == -1:
55                     #     ua = float((boxes[n, 2] - boxes[n, 0])
56                     #               *(boxes[n, 3] - boxes[n, 1]))
57                     # else:
58                     #     ua = float(
59                     #         (boxes[n, 2] - boxes[n, 0]) *
60                     #         (boxes[n, 3] - boxes[n, 1]) +
61                     #         box_area - iw * ih
62                     #     )
63                     overlaps[n, k] = iw * ih / ua
64     return overlaps
65
66 def bbox_overlaps(
67         np.ndarray[DTYPE_t, ndim=2] boxes,
68         np.ndarray[DTYPE_t, ndim=2] query_boxes):
69     """
70     Parameters
71     ----------
72     boxes: (N, 4) ndarray of float
73     query_boxes: (K, 4) ndarray of float
74     Returns
75     -------
76     overlaps: (N, K) ndarray of overlap between boxes and query_boxes
77     """
78     cdef unsigned int N = boxes.shape[0]
79     cdef unsigned int K = query_boxes.shape[0]
80     cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)
81     cdef DTYPE_t iw, ih, box_area
82     cdef DTYPE_t ua
83     cdef unsigned int k, n
84     for k in range(K):
85         box_area = (
86             (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
87             (query_boxes[k, 3] - query_boxes[k, 1] + 1)
88         )
89         for n in range(N):
90             iw = (
91                 min(boxes[n, 2], query_boxes[k, 2]) -
92                 max(boxes[n, 0], query_boxes[k, 0]) + 1
93             )
94             if iw > 0:
95                 ih = (
96                     min(boxes[n, 3], query_boxes[k, 3]) -
97                     max(boxes[n, 1], query_boxes[k, 1]) + 1
98                 )
99                 if ih > 0:
100                     ua = float(
101                         (boxes[n, 2] - boxes[n, 0] + 1) *
102                         (boxes[n, 3] - boxes[n, 1] + 1) +
103                         box_area - iw * ih
104                     )
105                     overlaps[n, k] = iw * ih / ua
106     return overlaps
107
108 def bbox_overlaps_self(
109         np.ndarray[DTYPE_t, ndim=2] boxes,
110         np.ndarray[DTYPE_t, ndim=2] query_boxes):
111     """
112     Parameters
113     ----------
114     boxes: (N, 4) ndarray of float
115     query_boxes: (K, 4) ndarray of float
116     Returns
117     -------
118     overlaps: (N, K) ndarray of overlap between boxes and query_boxes
119     """
120     cdef unsigned int N = boxes.shape[0]
121     cdef unsigned int K = query_boxes.shape[0]
122     cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)
123     cdef DTYPE_t iw, ih, box_area
124     cdef DTYPE_t ua
125     cdef unsigned int k, n
126     for k in range(K):
127         box_area = (
128             (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
129             (query_boxes[k, 3] - query_boxes[k, 1] + 1)
130         )
131         for n in range(N):
132             iw = (
133                 min(boxes[n, 2], query_boxes[k, 2]) -
134                 max(boxes[n, 0], query_boxes[k, 0]) + 1
135             )
136             if iw > 0:
137                 ih = (
138                     min(boxes[n, 3], query_boxes[k, 3]) -
139                     max(boxes[n, 1], query_boxes[k, 1]) + 1
140                 )
141                 if ih > 0:
142                     ua = float(box_area)
143                     overlaps[n, k] = iw * ih / ua
144     return overlaps
145
146
147 def bbox_overlaps_ignore(
148         np.ndarray[DTYPE_t, ndim=2] boxes,
149         np.ndarray[DTYPE_t, ndim=2] query_boxes):
150     """
151     Parameters
152     ----------
153     boxes: (N, 4) ndarray of float
154     query_boxes: (K, 4) ndarray of float
155     Returns
156     -------
157     overlaps: (N, K) ndarray of overlap between boxes and query_boxes
158     """
159     cdef unsigned int N = boxes.shape[0]
160     cdef unsigned int K = query_boxes.shape[0]
161     cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)
162     cdef DTYPE_t iw, ih, box_area
163     cdef DTYPE_t ua
164     cdef unsigned int k, n
165     for k in range(K):
166         box_area = (
167             (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
168             (query_boxes[k, 3] - query_boxes[k, 1] + 1)
169         )
170         for n in range(N):
171             iw = (
172                 min(boxes[n, 2], query_boxes[k, 2]) -
173                 max(boxes[n, 0], query_boxes[k, 0]) + 1
174             )
175             if iw > 0:
176                 ih = (
177                     min(boxes[n, 3], query_boxes[k, 3]) -
178                     max(boxes[n, 1], query_boxes[k, 1]) + 1
179                 )
180                 if ih > 0:
181                     if query_boxes[k, 4] == -1:
182                         ua = float((boxes[n, 2] - boxes[n, 0] + 1)
183                                   *(boxes[n, 3] - boxes[n, 1] + 1))
184                     else:
185                         ua = float(
186                             (boxes[n, 2] - boxes[n, 0] + 1) *
187                             (boxes[n, 3] - boxes[n, 1] + 1) +
188                             box_area - iw * ih
189                         )
190                     overlaps[n, k] = iw * ih / ua
191     return overlaps
192
193
194 def get_assignment_overlaps(
195         np.ndarray[DTYPE_t, ndim=2] boxes,
196         np.ndarray[DTYPE_t, ndim=2] query_boxes,
197         DTYPE_t FG_THRESH):
198     """ Used for proposal_target_layer_ignore
199     Parameters
200     ----------
201     boxes: (N, 4) ndarray of float
202     query_boxes: (K, 4) ndarray of float
203     Returns
204     -------
205     overlaps: (N, K) ndarray of overlap between boxes and query_boxes
206     """
207     cdef unsigned int N = boxes.shape[0]
208     cdef unsigned int K = query_boxes.shape[0]
209     cdef np.ndarray[long, ndim=1] gt_assignment = np.zeros((N,), dtype=np.int)
210     cdef np.ndarray[DTYPE_t, ndim=1] max_overlaps = np.zeros((N,), dtype=DTYPE) 
211     cdef DTYPE_t iw, ih, box_area
212     cdef DTYPE_t ua
213     cdef unsigned int k, n
214     for k in range(K):
215         box_area = (
216             (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
217             (query_boxes[k, 3] - query_boxes[k, 1] + 1)
218         )
219         for n in range(N):
220             iw = (
221                 min(boxes[n, 2], query_boxes[k, 2]) -
222                 max(boxes[n, 0], query_boxes[k, 0]) + 1
223             )
224             if iw > 0:
225                 ih = (
226                     min(boxes[n, 3], query_boxes[k, 3]) -
227                     max(boxes[n, 1], query_boxes[k, 1]) + 1
228                 )
229                 if ih > 0:
230                     if query_boxes[k, 4] == -1:
231                         ua = float((boxes[n, 2] - boxes[n, 0] + 1)
232                                   *(boxes[n, 3] - boxes[n, 1] + 1))
233                         overlap = iw * ih / ua
234                         if overlap > max_overlaps[n]:
235                             if query_boxes[gt_assignment[n], 4] == -1 or max_overlaps[n] < FG_THRESH:
236                                 max_overlaps[n] = overlap
237                                 gt_assignment[n] = k
238                     else:
239                         ua = float(
240                             (boxes[n, 2] - boxes[n, 0] + 1) *
241                             (boxes[n, 3] - boxes[n, 1] + 1) +
242                             box_area - iw * ih
243                         )
244                         overlap = iw * ih / ua
245                         if overlap > max_overlaps[n]:
246                             max_overlaps[n] = overlap
247                             gt_assignment[n] = k
248                     #overlaps[n, k] = overlap
249     return gt_assignment, max_overlaps