summaryrefslogtreecommitdiffstats
path: root/SD-VBS/benchmarks/sift/src/c/siftlocalmax.c
diff options
context:
space:
mode:
Diffstat (limited to 'SD-VBS/benchmarks/sift/src/c/siftlocalmax.c')
-rw-r--r--SD-VBS/benchmarks/sift/src/c/siftlocalmax.c247
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
42F2D* 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