diff options
| author | Leo Chan <leochanj@live.unc.edu> | 2020-10-22 01:53:21 -0400 |
|---|---|---|
| committer | Joshua Bakita <jbakita@cs.unc.edu> | 2020-10-22 01:56:35 -0400 |
| commit | d17b33131c14864bd1eae275f49a3f148e21cf29 (patch) | |
| tree | 0d8f77922e8d193cb0f6edab83018f057aad64a0 /SD-VBS/benchmarks/sift/src/c/siftlocalmax.c | |
| parent | 601ed25a4c5b66cb75315832c15613a727db2c26 (diff) | |
Squashed commit of the sb-vbs branch.
Includes the SD-VBS benchmarks modified to:
- Use libextra to loop as realtime jobs
- Preallocate memory before starting their main computation
- Accept input via stdin instead of via argc
Does not include the SD-VBS matlab code.
Fixes libextra execution in LITMUS^RT.
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? */ | ||
| < | |||
