diff options
Diffstat (limited to 'SD-VBS/benchmarks/sift/src/c/siftlocalmax.c')
-rw-r--r-- | SD-VBS/benchmarks/sift/src/c/siftlocalmax.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/SD-VBS/benchmarks/sift/src/c/siftlocalmax.c b/SD-VBS/benchmarks/sift/src/c/siftlocalmax.c new file mode 100644 index 0000000..d75bcbd --- /dev/null +++ b/SD-VBS/benchmarks/sift/src/c/siftlocalmax.c | |||
@@ -0,0 +1,247 @@ | |||
1 | #include "sift.h" | ||
2 | |||
3 | /** | ||
4 | SIFTLOCALMAX Find local maximizers | ||
5 | Returns the indexes of the local maximizers of | ||
6 | the 3-dimensional array F. | ||
7 | |||
8 | Say, we have a Q-dimensional array F. | ||
9 | A local maximizer is an element whose value is greater than the | ||
10 | value of all its neighbors. The neighbors of an element i1...iQ | ||
11 | are the subscripts j1...jQ such that iq-1 <= jq <= iq (excluding | ||
12 | i1...iQ itself). For example, if Q=1 the neighbors of an element | ||
13 | are its predecessor and successor in the linear order; if Q=2, its | ||
14 | neighbors are the elements immediately to its north, south, west, | ||
15 | est, north-west, north-est, south-west and south-est | ||
16 | (8-neighborhood). | ||
17 | |||
18 | Points on the boundary of F are ignored (and never selected as | ||
19 | local maximizers). | ||
20 | |||
21 | SEL=SIFTLOCALMAX(F,THRESH) accepts an element as a mazimizer only | ||
22 | if it is at least THRES greater than all its neighbors. | ||
23 | |||
24 | SEL=SIFTLOCALMAX(F,THRESH,P) look for neighbors only in the first | ||
25 | P dimensions of the Q-dimensional array F. This is useful to | ||
26 | process F in ``slices''. | ||
27 | |||
28 | REMARK. Matrices (2-array) with a singleton dimension are | ||
29 | interpreted as vectors (1-array). So for example SIFTLOCALMAX([0 1 | ||
30 | 0]) and SIFTLOCALMAX([0 1 0]') both return 2 as an aswer. However, | ||
31 | if [0 1 0] is to be interpreted as a 1x2 matrix, then the correct | ||
32 | answer is the empty set, as all elements are on the boundary. | ||
33 | Unfortunately MATLAB does not distinguish between vectors and | ||
34 | 2-matrices with a singleton dimension. To forece the | ||
35 | interpretation of all matrices as 2-arrays, use | ||
36 | SIFTLOCALMAX(F,TRESH,2) (but note that in this case the result is | ||
37 | always empty!). | ||
38 | **/ | ||
39 | |||
40 | #define NDIMS 3 | ||
41 | |||
42 | F2D* siftlocalmax(F2D* in, float thresh, int intervals, int M, int N) | ||
43 | { | ||
44 | int ndims, ptoffset=0, maxIter = 0; | ||
45 | int offsets[NDIMS]; | ||
46 | int midx[NDIMS]; | ||
47 | int dims[NDIMS]; | ||
48 | I2D* neighbors ; | ||
49 | int nneighbors ; | ||
50 | F2D* out; | ||
51 | |||
52 | /** | ||
53 | We pass dogss[o], which has >1 intervals | ||
54 | If >1 intervals, then the dimensions of in[F] will be 1 x intervals | ||
55 | If =1 interval, then the dimensions of in[F] will be the size of the dogss[o] image | ||
56 | We will check for this condition. | ||
57 | **/ | ||
58 | |||
59 | ndims = NDIMS; /* Since we have intervals number of images of size M x N */ | ||
60 | dims[0] = M; | ||
61 | dims[1] = N; | ||
62 | dims[2] = intervals-1; | ||
63 | |||
64 | /* | ||
65 | If there are only two dimensions and if one is singleton, then | ||
66 | assume that a vector has been provided as input (and treat this | ||
67 | as a COLUMN matrix with p=1). We do this because Matlab does not | ||
68 | distinguish between vectors and 1xN or Mx1 matrices and because | ||
69 | the cases 1xN and Mx1 are trivial (the result is alway empty). | ||
70 | */ | ||
71 | |||
72 | |||
73 | |||
74 | /* ------------------------------------------------------------------ | ||
75 | * Do the job | ||
76 | * --------------------------------------------------------------- */ | ||
77 | int maxima_size = M*N ; | ||
78 | |||
79 | I2D* maxima_start = iMallocHandle(1, maxima_size); | ||
80 | int* maxima_iterator = maxima_start->data ; | ||
81 | int* maxima_end = maxima_start->data + maxima_size ; | ||
82 | |||
83 | int i,h,o,j; | ||
84 | F2D* pt; | ||
85 | |||
86 | pt = in; | ||
87 | |||
88 | /* Compute the offsets between dimensions. */ | ||
89 | offsets[0] = 1 ; | ||
90 | for(i = 1 ; i < ndims ; ++i) | ||
91 | { | ||
92 | offsets[i] = offsets[i-1]*dims[i-1] ; | ||
93 | } | ||
94 | |||
95 | /* Multi-index. */ | ||
96 | for(i = 0 ; i < ndims ; ++i) | ||
97 | midx[i] = 1 ; | ||
98 | |||
99 | /* Neighbors. */ | ||
100 | nneighbors = 1 ; | ||
101 | o=0 ; | ||
102 | for(i = 0 ; i < ndims ; ++i) | ||
103 | { | ||
104 | nneighbors *= 3 ; | ||
105 | midx[i] = -1 ; | ||
106 | o -= offsets[i] ; | ||
107 | } | ||
108 | nneighbors -= 1 ; | ||
109 | neighbors = iMallocHandle(1,nneighbors); | ||
110 | |||
111 | /* Precompute offsets from offset(-1,...,-1,0,...0) to | ||
112 | * offset(+1,...,+1,0,...,0). */ | ||
113 | i = 0 ; | ||
114 | |||
115 | while(1) | ||
116 | { | ||
117 | if(o != 0) | ||
118 | { | ||
119 | asubsref(neighbors, i) = o ; | ||
120 | i++; | ||
121 | } | ||
122 | h = 0 ; | ||
123 | while( o += offsets[h], (++midx[h]) > 1 ) | ||
124 | { | ||
125 | o -= 3*offsets[h] ; | ||
126 | midx[h] = -1 ; | ||
127 | if(++h >= ndims) | ||
128 | goto stop ; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | stop: ; | ||
133 | |||
134 | /* Starts at the corner (1,1,...,1,0,0,...0) */ | ||
135 | for(h = 0 ; h < ndims ; ++h) | ||
136 | { | ||
137 | midx[h] = 1 ; | ||
138 | ptoffset += offsets[h] ; | ||
139 | } | ||
140 | |||
141 | |||
142 | /* --------------------------------------------------------------- | ||
143 | * Loop | ||
144 | * ------------------------------------------------------------ */ | ||
145 | |||
146 | /* | ||
147 | If any dimension in the first P is less than 3 elements wide | ||
148 | then just return the empty matrix (if we proceed without doing | ||
149 | anything we break the carry reporting algorithm below). | ||
150 | */ | ||
151 | |||
152 | for(h=0 ; h < ndims ; ++h) | ||
153 | if(dims[h] < 3) | ||
154 | goto end ; | ||
155 | |||
156 | while(1) | ||
157 | { | ||
158 | /* Propagate carry along multi index midx */ | ||
159 | |||
160 | h = 0 ; | ||
161 | while(midx[h] >= dims[h] - 1) | ||
162 | { | ||
163 | midx[h] = 1 ; | ||
164 | if(++h >= ndims) | ||
165 | goto next_layer ; | ||
166 | ++midx[h] ; | ||
167 | } | ||
168 | |||
169 | /* Scan neighbors */ | ||
170 | { | ||
171 | float v = asubsref(pt, ptoffset); //*pt ; | ||
172 | int is_greater = (v>=thresh) ? 1 : 0; | ||
173 | |||
174 | assert(ptoffset < pt->width*pt->height); | ||
175 | |||
176 | i = 0 ; | ||
177 | while(is_greater && i < nneighbors) | ||
178 | { | ||
179 | if(v > asubsref(pt, ptoffset + asubsref(neighbors,i))) | ||
180 | is_greater *= 1; | ||
181 | else | ||
182 | is_greater *= 0; | ||
183 | i = i+1; | ||
184 | } | ||
185 | |||
186 | /* Add the local maximum */ | ||
187 | if(is_greater) | ||
188 | { | ||
189 | /* Need more space? */ | ||
190 | if( &(maxima_iterator[maxIter]) == maxima_end) | ||
191 | { | ||
192 | int *temp, i, j; | ||
193 | maxima_size += M*N ; | ||
194 | |||
195 | free(maxima_start); | ||
196 | maxima_start = iMallocHandle(1, maxima_size); | ||
197 | |||
198 | maxima_end = maxima_start->data + maxima_size ; | ||
199 | maxima_iterator = maxima_end - M*N ; | ||
200 | maxIter = 0; | ||
201 | } | ||
202 | |||
203 | maxima_iterator[maxIter] = ptoffset + 1; | ||
204 | maxIter++; | ||
205 | } | ||
206 | |||
207 | /* Go to next element */ | ||
208 | ptoffset += 1 ; | ||
209 | ++midx[0] ; | ||
210 | continue ; | ||
211 | |||
212 | next_layer: ; | ||
213 | if( h >= ndims ) | ||
214 | goto end ; | ||
215 | |||
216 | while((++midx[h]) >= dims[h]) | ||
217 | { | ||
218 | midx[h] = 0 ; | ||
219 | if(++h >= ndims) | ||
220 | goto end ; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | end:; | ||
226 | /* Return. */ | ||
227 | { | ||
228 | int i=0; | ||
229 | out = fMallocHandle(1, maxIter); | ||
230 | |||
231 | for(i=0; i<maxIter; i++) | ||
232 | asubsref(out,i) = maxima_iterator[i] ; | ||
233 | } | ||
234 | |||
235 | /* Release space. */ | ||
236 | free(neighbors) ; | ||
237 | free(maxima_start); | ||
238 | |||
239 | return out; | ||
240 | } | ||
241 | |||
242 | |||
243 | |||
244 | |||
245 | |||
246 | |||
247 | |||