summaryrefslogtreecommitdiffstats
path: root/SD-VBS/benchmarks/sift/src
diff options
context:
space:
mode:
authorLeo Chan <leochanj@live.unc.edu>2020-10-22 01:53:21 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2020-10-22 01:56:35 -0400
commitd17b33131c14864bd1eae275f49a3f148e21cf29 (patch)
tree0d8f77922e8d193cb0f6edab83018f057aad64a0 /SD-VBS/benchmarks/sift/src
parent601ed25a4c5b66cb75315832c15613a727db2c26 (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')
-rw-r--r--SD-VBS/benchmarks/sift/src/c/diffss.c53
-rw-r--r--SD-VBS/benchmarks/sift/src/c/doubleSize.c55
-rw-r--r--SD-VBS/benchmarks/sift/src/c/filterBoundaryPoints.c61
-rw-r--r--SD-VBS/benchmarks/sift/src/c/gaussianss.c185
-rw-r--r--SD-VBS/benchmarks/sift/src/c/halveSize.c35
-rw-r--r--SD-VBS/benchmarks/sift/src/c/imsmooth.c104
-rw-r--r--SD-VBS/benchmarks/sift/src/c/script_sift.c83
-rw-r--r--SD-VBS/benchmarks/sift/src/c/sift.c314
-rw-r--r--SD-VBS/benchmarks/sift/src/c/sift.h27
-rw-r--r--SD-VBS/benchmarks/sift/src/c/siftlocalmax.c247
-rw-r--r--SD-VBS/benchmarks/sift/src/c/siftrefinemx.c196
11 files changed, 1360 insertions, 0 deletions
diff --git a/SD-VBS/benchmarks/sift/src/c/diffss.c b/SD-VBS/benchmarks/sift/src/c/diffss.c
new file mode 100644
index 0000000..683cbe7
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/diffss.c
@@ -0,0 +1,53 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include "sift.h"
6
7/**
8 DIFFSS Difference of scale space
9 Returns a scale space DSS obtained by subtracting
10 consecutive levels of the scale space SS.
11
12 In SIFT, this function is used to compute the difference of
13 Gaussian scale space from the Gaussian scale space of an image.
14**/
15
16F2D** diffss(F2D** ss, int num, int intervals)
17{
18 F2D** dss;
19 int o, sizeM, sizeN, s, i, j;
20 F2D *current, *in1, *in2;
21
22 dss = malloc(num*intervals*sizeof(F2D*));
23
24 for(o=0; o<num; o++)
25 {
26 for(s=0; s<(intervals-1); s++)
27 {
28 sizeM = ss[o*intervals+s]->height;
29 sizeN = ss[o*intervals+s]->width;
30
31 dss[o*intervals+s] = fMallocHandle(sizeM, sizeN);
32
33 current = dss[o*intervals+s];
34 in1 = ss[o*intervals+s+1];
35 in2 = ss[o*intervals+s];
36
37 for(i=0; i<sizeM; i++)
38 {
39 for(j=0; j<sizeN; j++)
40 {
41 subsref(current,i,j) = subsref(in1,i,j) - subsref(in2,i,j);
42 }
43 }
44 }
45 }
46
47 return dss;
48
49}
50
51
52
53
diff --git a/SD-VBS/benchmarks/sift/src/c/doubleSize.c b/SD-VBS/benchmarks/sift/src/c/doubleSize.c
new file mode 100644
index 0000000..dd17f77
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/doubleSize.c
@@ -0,0 +1,55 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include "sift.h"
6
7F2D* doubleSize(F2D* I)
8{
9 F2D *J;
10 int M, N, i, j;
11
12 M = I->height;
13 N = I->width;
14 J = fSetArray(2*M, 2*N, 0);
15
16 for(i=0; i<M; i++)
17 {
18 for(j=0; j<N; j++)
19 {
20 subsref(J,2*i,j*2) = subsref(I,i,j);
21 }
22 }
23
24 for(i=0; i<M-1; i++)
25 {
26 for(j=0; j<N-1; j++)
27 {
28 subsref(J,i*2+1,j*2+1) = (0.25 * (subsref(I,i,j) + subsref(I,i+1,j) + subsref(I,i,j+1) + subsref(I,(i+1),j+1)));
29 }
30 }
31
32 for(i=0; i<M-1; i++)
33 {
34 for(j=0; j<N; j++)
35 {
36 subsref(J,i*2+1,j*2) = (0.5 * (subsref(I,i,j) + subsref(I,i+1,j)));
37 }
38 }
39
40 for(i=0; i<M; i++)
41 {
42 for(j=0; j<N-1; j++)
43 {
44 subsref(J,i*2,j*2+1) = (0.5 * (subsref(I,i,j) + subsref(I,i,j+1)));
45 }
46 }
47
48 return J;
49}
50
51
52
53
54
55
diff --git a/SD-VBS/benchmarks/sift/src/c/filterBoundaryPoints.c b/SD-VBS/benchmarks/sift/src/c/filterBoundaryPoints.c
new file mode 100644
index 0000000..c68e717
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/filterBoundaryPoints.c
@@ -0,0 +1,61 @@
1#include "sift.h"
2
3/**
4 Filter out points on the boundaries.
5 The function returns oframes, which
6 contains the row, col and the interval number
7**/
8
9F2D* filterBoundaryPoints(int M, int N, F2D* oframes)
10{
11 int i, k=0, m=0;
12 int cnt;
13 I2D* sel;
14 F2D *ret;
15
16 cnt = 0;
17 for(i=0; i<oframes->width; i++)
18 {
19 if(asubsref(oframes,i)>3 && asubsref(oframes,i)<(N-3) &&
20 subsref(oframes,1,i)>3 && subsref(oframes,1,i)<(M-3))
21 {
22 cnt++;
23 }
24 }
25
26 sel = iSetArray(cnt, 1, 0);
27 for(i=0; i<oframes->width; i++)
28 {
29 if(asubsref(oframes,i)>3 && asubsref(oframes,i)<(N-3) &&
30 subsref(oframes,1,i)>3 && subsref(oframes,1,i)<(M-3))
31 {
32 asubsref(sel,k) = i;
33 k++;
34 }
35 m++;
36 }
37
38 if( sel->height > 0)
39 {
40 ret = fSetArray(oframes->height, sel->height, 0);
41 {
42 for(i=0; i<sel->height; i++)
43 {
44 subsref(ret,0,i) = subsref(oframes,0,asubsref(sel,i));
45 subsref(ret,1,i) = subsref(oframes,1,asubsref(sel,i));
46 subsref(ret,2,i) = subsref(oframes,2,asubsref(sel,i));
47 }
48 }
49 }
50 else
51 ret = fSetArray(1,1,0);
52
53 iFreeHandle(sel);
54 return ret;
55}
56
57
58
59
60
61
diff --git a/SD-VBS/benchmarks/sift/src/c/gaussianss.c b/SD-VBS/benchmarks/sift/src/c/gaussianss.c
new file mode 100644
index 0000000..52dd95b
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/gaussianss.c
@@ -0,0 +1,185 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include "sift.h"
6
7F2D* resizeArray(F2D* array, int omin)
8{
9 F2D* prev = NULL;
10 F2D* current = array;
11 int o;
12 if(omin<0)
13 {
14 for(o=1; o>=-omin; o--)
15 {
16 prev = current;
17 current = doubleSize(current);
18 fFreeHandle(prev);
19 }
20 }
21 if(omin>0)
22 {
23 for(o=1; o<= omin; o++)
24 {
25 prev = current;
26 current = halveSize(current);
27 fFreeHandle(prev);
28 }
29 }
30 return current;
31}
32
33/**
34 Returns the Gaussian scale space of image I. Image I is assumed to be
35 pre-smoothed at level SIGMAN. O,S,OMIN,SMIN,SMAX,SIGMA0 are the
36 parameters of the scale space.
37**/
38
39F2D** gaussianss(F2D* array, float sigman, int O, int S, int omin, int smin, int smax, float sigma0)
40{
41 /* We compute the following items in the function
42 1. Smooth input image per octave
43 2. Smooth each octave for different intervals
44 3. Subtract each "interval-1" smooth image from "interval" image per octave. So, per octave, we have "interval" * DOG images.
45 4. So, octave * intervals * image
46 5. Note: At each octave, the image is scaled down in both x and y directions
47 */
48
49 float k, dsigma0, dsigma;
50 int s, i, j, o, so, M, N, sbest;
51 int intervals = smax-smin+1;
52 float temp, target_sigma, prev_sigma;
53 F2D *TMP, **gss;
54 F2D* I = array;
55
56 // Scale multiplicative step
57 k = pow(2, (1.0/S));
58 dsigma0 = sigma0 * sqrt(1-(1.0/pow(k,2))); // Scale step factor
59
60 // If omin < 0, multiply the size of the image.
61 I = resizeArray(I, omin);
62 M = I->height;
63 N = I->width;
64 so = -smin+1; // Index offset
65
66 gss = malloc(O*intervals*sizeof(F2D*));
67 if(gss == NULL)
68 {
69 printf("Could not allocate memory\n");
70 return NULL;
71 }
72
73/**
74 First octave
75--------------------------------------------------------------------
76
77The first level of the first octave has scale index (o,s) =
78(omin,smin) and scale coordinate
79
80 sigma(omin,smin) = sigma0 2^omin k^smin
81
82The input image I is at nominal scale sigman. Thus in order to get
83the first level of the pyramid we need to apply a smoothing of
84
85 sqrt( (sigma0 2^omin k^smin)^2 - sigman^2 ).
86
87As we have pre-scaled the image omin octaves (up or down,
88depending on the sign of omin), we need to correct this value
89by dividing by 2^omin, getting
90
91 sqrt( (sigma0 k^smin)^2 - (sigman/2^omin)^2 )
92
93**/
94
95 temp = sqrt(pow((sigma0*pow(k,smin)),2) - pow((sigman/pow(2,omin)),2));
96
97 {
98 gss[0] = fSetArray(I->height, I->width, 0);
99 imsmooth(I, temp, gss[0] );
100 }
101
102 for(s=smin; s<smax; s++)
103 {
104
105 /**
106 Here we go from (omin,s-1) to (omin,s). The extra smoothing
107 standard deviation is
108
109 (sigma0 2^omin 2^(s/S) )^2 - (simga0 2^omin 2^(s/S-1/S) )^2
110
111 After dividing by 2^omin (to take into account the fact
112 that the image has been pre-scaled omin octaves), the
113 standard deviation of the smoothing kernel is
114
115 dsigma = sigma0 k^s sqrt(1-1/k^2)
116 **/
117
118 dsigma = pow(k,s+1) * dsigma0;
119 gss[s+so] = fSetArray(gss[s+so-1]->height, gss[s+so-1]->width, 0);
120 imsmooth( gss[(s+so-1)] , dsigma, gss[(s+so)] );
121 }
122
123 /** Other octaves **/
124
125 for(o=1; o<O; o++)
126 {
127 /**
128 We need to initialize the first level of octave (o,smin) from
129 the closest possible level of the previous octave. A level (o,s)
130 in this octave corrsponds to the level (o-1,s+S) in the previous
131 octave. In particular, the level (o,smin) correspnds to
132 (o-1,smin+S). However (o-1,smin+S) might not be among the levels
133 (o-1,smin), ..., (o-1,smax) that we have previously computed.
134 The closest pick is
135
136 / smin+S if smin+S <= smax
137 (o-1,sbest) , sbest = |
138 \ smax if smin+S > smax
139
140 The amount of extra smoothing we need to apply is then given by
141
142 ( sigma0 2^o 2^(smin/S) )^2 - ( sigma0 2^o 2^(sbest/S - 1) )^2
143
144 As usual, we divide by 2^o to cancel out the effect of the
145 downsampling and we get
146
147 ( sigma 0 k^smin )^2 - ( sigma0 2^o k^(sbest - S) )^2
148 **/
149
150 sbest = MIN(smin+S-1, smax-1);
151 TMP = halveSize( gss[(o-1)*intervals+sbest+so]);
152 target_sigma = sigma0 * pow(k,smin);
153 prev_sigma = sigma0 * pow(k, (sbest+1)-S);
154
155 temp = sqrt(pow(target_sigma,2) - pow(prev_sigma, 2));
156 if(target_sigma > prev_sigma)
157 {
158 gss[o*intervals] = fSetArray(TMP->height, TMP->width, 0);
159 imsmooth(TMP, temp, gss[o*intervals] );
160 }
161 else
162 {
163 int i;
164 gss[o*intervals] = fSetArray(TMP->height, TMP->width, 0);
165 for(i=0; i<(TMP->height*TMP->width); i++)
166 asubsref(gss[o*intervals],i) = asubsref(TMP,i);
167 }
168
169 M = TMP->height;
170 N = TMP->width;
171
172 fFreeHandle(TMP);
173
174 for(s=smin; s<smax; s++)
175 {
176 // The other levels are determined as above for the first octave.
177 dsigma = pow(k,s+1) * dsigma0;
178 gss[o*intervals+s+so] = fSetArray(gss[o*intervals+s-1+so]->height, gss[o*intervals+s-1+so]->width, 0);
179 imsmooth( gss[o*intervals+s-1+so] , dsigma, gss[o*intervals+s+so]);
180 }
181 }
182
183 fFreeHandle(I);
184 return gss;
185}
diff --git a/SD-VBS/benchmarks/sift/src/c/halveSize.c b/SD-VBS/benchmarks/sift/src/c/halveSize.c
new file mode 100644
index 0000000..fe1e536
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/halveSize.c
@@ -0,0 +1,35 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include <stdio.h>
6#include <stdlib.h>
7#include "sift.h"
8
9F2D* halveSize(F2D* I)
10{
11 F2D *J;
12 int i, j, k;
13 int hM, hN;
14 int M, N;
15
16 M = I->height;
17 N = I->width;
18
19 hM = (M+1)/2;
20 hN = (N+1)/2;
21
22 J = fSetArray(hM, hN, 0.0);
23
24 k = 0;
25 for(i=0; i<M; i+=2)
26 {
27 for(j=0; j<N; j+=2)
28 {
29 asubsref(J,k++) = subsref(I,i,j);
30 }
31 }
32
33 return J;
34}
35
diff --git a/SD-VBS/benchmarks/sift/src/c/imsmooth.c b/SD-VBS/benchmarks/sift/src/c/imsmooth.c
new file mode 100644
index 0000000..d901418
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/imsmooth.c
@@ -0,0 +1,104 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include "sift.h"
6#include <math.h>
7#include <assert.h>
8const double win_factor = 1.5 ;
9const int nbins = 36 ;
10const float threshold = 0.01;
11
12/**
13 This function is similar to imageBlur in common/c folder.
14 Here, we can specify the sigma value for the gaussian filter
15 function.
16**/
17
18void imsmooth(F2D* array, float dsigma, F2D* out)
19{
20 int M,N ;
21 int i,j,k;
22 float s ;
23
24 /* ------------------------------------------------------------------
25 ** Check the arguments
26 ** --------------------------------------------------------------- */
27
28 M = array->height;
29 N = array->width;
30 s = dsigma;
31
32 /* ------------------------------------------------------------------
33 ** Do the job
34 ** --------------------------------------------------------------- */
35 if(s > threshold)
36 {
37 int W = (int) ceil(4*s) ;
38 float temp[2*W+1];
39 F2D* buffer;
40 float acc = 0.0;
41
42 buffer = fSetArray(M,N,0);
43
44 for(j = 0 ; j < (2*W+1) ; ++j)
45 {
46 temp[j] = (float)(expf(-0.5 * (j - W)*(j - W)/(s*s))) ;
47 acc += temp[j];
48 }
49
50 for(j = 0 ; j < (2*W+1) ; ++j)
51 {
52 temp[j] /= acc ;
53 }
54
55 /*
56 ** Convolve along the columns
57 **/
58
59 for(j = 0 ; j < M ; ++j)
60 {
61 for(i = 0 ; i < N ; ++i)
62 {
63 int startCol = MAX(i-W,0);
64 int endCol = MIN(i+W, N-1);
65 int filterStart = MAX(0, W-i);
66
67 assert(j < array->height);
68 assert(j < buffer->height);
69 assert(i < buffer->width);
70 for(k=startCol; k<=endCol; k++) {
71 assert(k < array->width);
72 assert(filterStart < 2*W+1);
73 subsref(buffer,j,i) += subsref(array, j, k) * temp[filterStart++];
74 }
75 }
76 }
77
78 /*
79 ** Convolve along the rows
80 **/
81 for(j = 0 ; j < M ; ++j)
82 {
83 for(i = 0 ; i < N ; ++i)
84 {
85 int startRow = MAX(j-W,0);
86 int endRow = MIN(j+W, M-1);
87 int filterStart = MAX(0, W-j);
88 for(k=startRow; k<=endRow; k++)
89 subsref(out,j,i) += subsref(buffer,k,i) * temp[filterStart++];
90 }
91 }
92
93 fFreeHandle(buffer);
94
95 }
96 else
97 {
98 for(i=0;i<M*N;i++)
99 asubsref(out, i) = asubsref(array, i);
100 }
101
102
103 return;
104}
diff --git a/SD-VBS/benchmarks/sift/src/c/script_sift.c b/SD-VBS/benchmarks/sift/src/c/script_sift.c
new file mode 100644
index 0000000..0b2f106
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/script_sift.c
@@ -0,0 +1,83 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include <stdio.h>
6#include <stdlib.h>
7#include "sift.h"
8#include <malloc.h>
9#include "extra.h"
10#define SIFT_MEM 1<<29
11void normalizeImage(F2D* image)
12{
13 int i;
14 int rows;
15 int cols;
16
17 int tempMin = 10000, tempMax = -1;
18 rows = image->height;
19 cols = image->width;
20
21 for(i=0; i<(rows*cols); i++)
22 if(tempMin > asubsref(image,i))
23 tempMin = asubsref(image,i);
24
25 for(i=0; i<(rows*cols); i++)
26 asubsref(image,i) = asubsref(image,i) - tempMin;
27
28 for(i=0; i<(rows*cols); i++)
29 if(tempMax < asubsref(image,i))
30 tempMax = asubsref(image,i);
31
32 for(i=0; i<(rows*cols); i++)
33 asubsref(image,i) = ( asubsref(image,i) / (tempMax+0.0) );
34}
35
36int main(int argc, char* argv[])
37{
38 SET_UP
39 mallopt(M_TOP_PAD, SIFT_MEM);
40 mallopt(M_MMAP_MAX, 0);
41 I2D* im;
42 F2D *image;
43 int rows, cols, i, j;
44 F2D* frames;
45 unsigned int* startTime, *endTime, *elapsed;
46
47 char imSrc[100];
48 printf("Input image: ");
49 scanf("%s", imSrc);
50 im = readImage(imSrc);
51 image = fiDeepCopy(im);
52 rows = image->height;
53 cols = image->width;
54
55
56 printf("start\n");
57 for_each_job{
58 image = fiDeepCopy(im);
59 normalizeImage(image);
60 /** Extract sift features for the normalized image **/
61 frames = sift(image);
62 }
63 printf("end..\n");
64
65#ifdef CHECK
66 {
67 int ret=0;
68 float tol = 0.2;
69#ifdef GENERATE_OUTPUT
70 fWriteMatrix(frames, argv[1]);
71#endif
72 ret = fSelfCheck(frames, "expected_C.txt", tol);
73 if (ret == -1)
74 printf("Error in SIFT\n");
75 }
76#endif
77
78 iFreeHandle(im);
79 fFreeHandle(frames);
80 WRITE_TO_FILE
81 return 0;
82}
83
diff --git a/SD-VBS/benchmarks/sift/src/c/sift.c b/SD-VBS/benchmarks/sift/src/c/sift.c
new file mode 100644
index 0000000..ea0d308
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/sift.c
@@ -0,0 +1,314 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#include <math.h>
6#include "sift.h"
7
8/** SIFT- Scale Invariant Feature Transform. This algorithm is based on
9 David Lowe's implementation of sift. So, we will use the parameter
10 values from Lowe's implementation.
11 See: http://www.cs.ubc.ca/~lowe/keypoints/
12
13 SIFT extracts from an image a collection of frames or keypoints. These
14 are oriented disks attacked to blob-like structures of the image. As
15 the image translates, rotates and scales, the frames track these blobs
16 and the deformation.
17
18 'BoundaryPoint' [bool]
19 If set to 1, frames too close to the image boundaries are discarded.
20
21 'Sigma0' [pixels]
22 Smoothing of the level 0 of octave 0 of the scale space.
23 (Note that Lowe's 1.6 value refers to the level -1 of octave 0.)
24
25 'SigmaN' [pixels]
26 Nominal smoothing of the input image. Typically set to 0.5.
27
28 'Threshold'
29 Threshold used to eliminate weak keypoints. Typical values for
30 intensity images in the range [0,1] are around 0.01. Smaller
31 values mean more keypoints.
32
33**/
34
35F2D* sift(F2D* I)
36{
37 int rows, cols, K;
38 int subLevels, omin, Octaves, r, NBP, NBO, smin, smax, intervals, o;
39 float sigma, sigman, sigma0, thresh, magnif;
40 int discardBoundaryPoints;
41 F2D *descriptors;
42 F2D **gss, *tfr;
43 F2D **dogss;
44 I2D* i_, *j_, *s_;
45 F2D *oframes, *frames;
46 int i, j, k, m, startRow, startCol, endRow, endCol, firstIn=1;
47 float minVal;
48 I2D* tx1, *ty1, *ts1;
49 I2D* x1, *y1, *s1, *txys;
50
51 rows = I->height;
52 cols = I->width;
53
54 /**
55 Lowe's choices
56 Octaves - octave
57 subLevels - sub-level for image
58 sigma - sigma value for gaussian kernel, for smoothing the image
59 At each successive octave, the data is spatially downsampled by half
60 **/
61
62 subLevels = 3;
63 omin = -1;
64 minVal = log2f(MIN(rows,cols));
65 Octaves = (int)(floor(minVal))-omin-4; /* Upto 16x16 images */
66 sigma0 = 1.6 * pow(2, (1.0/subLevels));
67 sigman = 0.5;
68 thresh = (0.04/subLevels)/2;
69 r = 10;
70
71#ifdef test
72 subLevels = 1;
73 Octaves = 1;
74 sigma0 = pow(0.6 * 2, 1);
75 sigman = 1.0;
76 thresh = (1/subLevels)/2;
77 r = 1;
78#endif
79
80 NBP = 4;
81 NBO = 8 ;
82 magnif = 3.0 ;
83 discardBoundaryPoints = 1 ;
84
85 smin = -1;
86 smax = subLevels+1;
87 intervals = smax - smin + 1;
88
89 /**
90 We build gaussian pyramid for the input image. Given image I,
91 we sub-sample the image into octave 'Octaves' number of levels. At
92 each level, we smooth the image with varying sigman values.
93
94 Gaussiam pyramid can be assumed as a 2-D matrix, where each
95 element is an image. Number of rows corresponds to the number
96 of scales of the pyramid (octaves, "Octaves"). Row 0 (scale 0) is the
97 size of the actual image, Row 1 (scale 1) is half the actual
98 size and so on.
99
100 At each scale, the image is smoothened with different sigma values.
101 So, each row has "intervals" number of smoothened images, starting
102 with least blurred.
103
104 gss holds the entire gaussian pyramid.
105 **/
106
107 gss = gaussianss(I, sigman, Octaves, subLevels, omin, -1, subLevels+1, sigma0);
108
109 /**
110 Once we build the gaussian pyramid, we compute DOG, the
111 Difference of Gaussians. At every scale, we do:
112
113 dogss[fixedScale][0] = gss[fixedScale][1] - gss[fixedScale][0]
114
115 Difference of gaussian gives us edge information, at each scale.
116 In order to detect keypoints on the intervals per octave, we
117 inspect DOG images at highest and lowest scales of the octave, for
118 extrema detection.
119 **/
120
121 dogss = diffss(gss, Octaves, intervals);
122
123 /** The extraction of keypoints is carried one octave per time **/
124 for(o=0; o<Octaves; o++)
125 {
126 F2D *temp;
127 F2D *t;
128 F2D *negate;
129 F2D *idxf, *idxft;
130 I2D *idx;
131 int i1, j1;
132 I2D *s, *i, *j, *x, *y;
133 int sizeRows = dogss[o*intervals]->height;
134 int sizeCols = dogss[o*intervals]->width;
135
136 {
137 int i,j,k=0;
138 temp = fMallocHandle(intervals-1, sizeRows*sizeCols);
139 negate = fMallocHandle(intervals-1, sizeRows*sizeCols);
140
141 /**
142 Keypoints are detected as points of local extrema of the
143 DOG pyramid, at a given octave. In softlocalmax function, the
144 keypoints are extracted by looking at 9x9x9 neighborhood samples.
145
146 We populate temp and negate arrays with the values of the DOG
147 pyramid for a given octave, o. Since we are interested in both
148 local maxima and minima, we compute negate matrix, which is the
149 negated values of the DOG pyramid.
150
151 **/
152
153 for(i1=0; i1<(intervals-1); i1++)
154 {
155 for(j=0; j<sizeCols; j++)
156 {
157 for(i=0; i<sizeRows; i++)
158 {
159 asubsref(temp,k) = subsref(dogss[o*intervals+i1],i,j);
160 asubsref(negate,k++) = -subsref(dogss[o*intervals+i1],i,j);
161 }
162 }
163 }
164 }
165
166 /**
167 siftlocalmax returns indices k, that correspond to local maxima and
168 minima.
169 The 80% tricks discards early very weak points before refinement.
170 **/
171 idxf = siftlocalmax( temp, 0.8*thresh, intervals, sizeRows, sizeCols);
172 t = siftlocalmax( negate, 0.8*thresh, intervals, sizeRows, sizeCols);
173
174 idxft = fHorzcat(idxf, t);
175
176 /**
177 Since indices is the 1-D index of the temp/negate arrays, we compute
178 the x,y and intervals(s) co-ordinates corresponding to each index.
179 **/
180
181 idx = ifDeepCopy(idxft);
182
183 x = iSetArray(idx->height,idx->width,0);
184 y = iSetArray(idx->height,idx->width,0);
185 s_ = iSetArray(idx->height,idx->width,0);
186
187 {
188 int i, j;
189 for(i=0; i<idx->height; i++)
190 {
191 for(j=0; j<idx->width; j++)
192 {
193 int v, u, w, z;
194 w = subsref(idx,i,j);
195 v = ceil((w/(sizeRows*sizeCols)) + 0.5);
196 u = floor(w/(sizeRows*sizeCols));
197 z = w - (sizeRows*sizeCols*u);
198
199 /** v is the interval number, s **/
200 subsref(s_,i,j) = v;
201 /** row number of the index **/
202 subsref(y,i,j) = ceil((z / sizeRows)+0.5);
203 /** col number of the index **/
204 subsref(x,i,j) = z - (sizeCols * floor(z / sizeRows));
205 }
206 }
207 }
208
209 {
210
211 tx1 = isMinus(x, 1);
212 x1 = iReshape(tx1, 1, (tx1->height*tx1->width));
213
214 ty1 = isMinus(y, 1);
215 y1 = iReshape(ty1, 1, (ty1->height*ty1->width));
216
217 ts1 = isPlus(s_, (smin-1));
218 s1 = iReshape(ts1, 1, (ts1->height*ts1->width));
219
220 txys = iVertcat(y1, x1);
221 i_ = iVertcat(txys, s1);
222 }
223
224 /**
225 Stack all x,y,s into oframes.
226 Row 0 of oframes = x
227 Row 1 of oframes = y
228 Row 2 of oframes = s
229 **/
230 oframes = fiDeepCopy(i_);
231
232 {
233 int i,j;
234 F2D* temp;
235 temp = oframes;
236
237 /**
238 Remove points too close to the boundary
239 **/
240
241 if(discardBoundaryPoints)
242 oframes = filterBoundaryPoints(sizeRows, sizeCols, temp);
243 fFreeHandle(temp);
244 }
245
246 /**
247 Refine the location, threshold strength and remove points on edges
248 **/
249 if( asubsref(oframes,0) != 0)
250 {
251 F2D* temp_;
252 temp_ = fTranspose(oframes);
253 fFreeHandle(oframes);
254 oframes = siftrefinemx(temp_, temp, smin, thresh, r, sizeRows, sizeCols, intervals-1);
255 fFreeHandle(temp_);
256
257 if( firstIn == 0)
258 {
259 tfr = fDeepCopy(frames);
260 fFreeHandle(frames);
261 frames = fHorzcat(tfr, oframes);
262 fFreeHandle(tfr);
263 }
264 else
265 frames = fDeepCopy(oframes);
266 firstIn = 0;
267 }
268 else if(Octaves == 1)
269 frames = fDeepCopy(oframes);
270
271 fFreeHandle(oframes);
272 iFreeHandle(y);
273 iFreeHandle(x);
274 iFreeHandle(s_);
275 iFreeHandle(y1);
276 iFreeHandle(x1);
277 iFreeHandle(s1);
278 iFreeHandle(ty1);
279 iFreeHandle(tx1);
280 iFreeHandle(ts1);
281 iFreeHandle(txys);
282 iFreeHandle(i_);
283 iFreeHandle(idx);
284 fFreeHandle(idxf);
285 fFreeHandle(idxft);
286 fFreeHandle(temp);
287 fFreeHandle(t);
288 fFreeHandle(negate);
289 }
290
291 { int s;
292 for(o=0; o<Octaves; o++)
293 {
294 for(s=0; s<(intervals-1); s++)
295 {
296 fFreeHandle(dogss[o*intervals+s]);
297 }
298 }
299 for(o=0; o<Octaves; o++)
300 {
301 for(s=0; s<(intervals); s++)
302 {
303 fFreeHandle(gss[o*intervals+s]);
304 }
305 }
306 }
307 free(gss);
308 free(dogss);
309
310 return frames;
311}
312
313
314
diff --git a/SD-VBS/benchmarks/sift/src/c/sift.h b/SD-VBS/benchmarks/sift/src/c/sift.h
new file mode 100644
index 0000000..e8a4ee0
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/sift.h
@@ -0,0 +1,27 @@
1/********************************
2Author: Sravanthi Kota Venkata
3********************************/
4
5#ifndef _SIFT_
6#define _SIFT_
7
8#include "sdvbs_common.h"
9#include <assert.h>
10
11#define GREATER(a,b) ((a) > (b))
12#define MAX(a,b) (((a)>(b))?(a):(b))
13#define MIN(a,b) (((a)<(b))?(a):(b))
14
15F2D* sift(F2D* I);
16F2D* halveSize(F2D* I);
17F2D** gaussianss(F2D* I, float sigman, int O, int S, int omin, int smin, int smax, float sigma0);
18F2D** diffss(F2D** ss, int O, int intervals);
19F2D* doubleSize(F2D* I);
20void imsmooth(F2D* I_pt, float dsigma, F2D* out);
21F2D* siftlocalmax(F2D* in, float thresh, int intervals, int M, int N);
22F2D* filterBoundaryPoints(int M, int N, F2D* oframes);
23F2D* siftrefinemx(F2D* oframes, F2D* dogss, int smin, float thresh, int rin, int M, int N, int intervals);
24
25#endif
26
27
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
diff --git a/SD-VBS/benchmarks/sift/src/c/siftrefinemx.c b/SD-VBS/benchmarks/sift/src/c/siftrefinemx.c
new file mode 100644
index 0000000..2b10e9d
--- /dev/null
+++ b/SD-VBS/benchmarks/sift/src/c/siftrefinemx.c
@@ -0,0 +1,196 @@
1#include "sift.h"
2
3const int max_iter = 5 ;
4
5/**
6
7 SIFTREFINEMX Subpixel localization, thresholding and on-edge test
8 Q = SIFTREFINEMX(P, OCTAVE, SMIN) refines, thresholds and performs
9 the on-edge test for the SIFT frames P extracted from the DOG
10 octave OCTAVE with parameter SMIN (see GAUSSIANSS()).
11
12 Q = SIFTREFINEMX(P, OCTAVE, SMIN, THRESH, R) specifies custom
13 values for the local maximum strength threshold THRESH and the
14 local maximum peakedeness threshold R.
15
16 OCTAVE is an octave of the Difference Of Gaussian scale space. P
17 is a 3xK matrix specifying the indexes (X,Y,S) of the points of
18 extremum of the octave OCTAVE. The spatial indexes X,Y are integer
19 with base zero. The scale index S is integer with base SMIN and
20 represents a scale sublevel in the specified octave.
21
22 The function returns a matrix Q containing the refined keypoints.
23 The matrix has the same format as P, except that the indexes are
24 now fractional. The function drops the points that do not satisfy
25 the strength and peakedness tests.
26
27**/
28
29F2D* siftrefinemx(F2D* oframes, F2D* dogss, int smin, float thresh, int r, int M, int N, int intervals)
30{
31 int S,K ;
32 F2D* out;
33
34 /* -----------------------------------------------------------------
35 ** Check the arguments
36 ** -------------------------------------------------------------- */
37
38 S = intervals;
39 K = oframes->height;
40
41 /* If the input array is empty, then output an empty array as well. */
42 if( K == 0) {
43 out = fDeepCopy(oframes);
44 return out;
45 }
46
47 /* -----------------------------------------------------------------
48 * Do the job
49 * -------------------------------------------------------------- */
50 {
51 F2D* buffer = fMallocHandle(K,3);
52 int p ;
53 const int yo = 1 ;
54 const int xo = M ;
55 const int so = M*N;
56 int buffCounter = 0;
57 int pptcount = 0;
58
59 for(p = 0 ; p < K ; ++p)
60 {
61 float tx, ty, ts;
62 int x,y,s;
63 int iter ;
64 float b[3] ;
65
66 tx = asubsref(oframes, pptcount++);
67 ty = asubsref(oframes, pptcount++);
68 ts = asubsref(oframes, pptcount++);
69
70 x = ceil(tx);
71 y = ceil(ty);
72 s = ceil(ts) - smin;
73
74
75 /* Local maxima extracted from the DOG
76 * have coorrinates 1<=x<=N-2, 1<=y<=M-2
77 * and 1<=s-mins<=S-2. This is also the range of the points
78 * that we can refine.
79 */
80
81 if(x < 1 || x > N-2 ||
82 y < 1 || y > M-2 ||
83 s < 1 || s > S-2) {
84 continue ;
85 }
86
87#define at(dx,dy,ds) asubsref(dogss, (dx)*xo + (dy)*yo + (ds)*so)
88
89 {
90 float Dx=0,Dy=0,Ds=0,Dxx=0,Dyy=0,Dss=0,Dxy=0,Dxs=0,Dys=0 ;
91 int dx = 0 ;
92 int dy = 0 ;
93
94 for(iter = 0 ; iter < max_iter ; ++iter)
95 {
96
97 float A[3*3] ;
98
99#define Aat(i,j) (A[(i)+(j)*3])
100
101 x += dx ;
102 y += dy ;
103
104 /* Compute the gradient. */
105 Dx = 0.5 * (at(x+1,y+0,s+0) - at(x-1,y+0,s+0)) ;
106 Dy = 0.5 * (at(x+0,y+1,s+0) - at(x+0,y-1,s+0));
107 Ds = 0.5 * (at(x+0,y+0,s+1) - at(x+0,y+0,s-1)) ;
108
109 /* Compute the Hessian. */
110 Dxx = (at(x+1,y,s) + at(x-1,y,s) - 2.0 * at(x,y,s)) ;
111 Dyy = (at(x,y+1,s) + at(x,y-1,s) - 2.0 * at(x,y,s)) ;
112 Dss = (at(x,y,s+1) + at(x,y,s-1) - 2.0 * at(x,y,s)) ;
113
114 Dxy = 0.25 * ( at(x+1,y+1,s) + at(x-1,y-1,s) - at(x-1,y+1,s) - at(x+1,y-1,s) ) ;
115 Dxs = 0.25 * ( at(x+1,y,s+1) + at(x-1,y,s-1) - at(x-1,y,s+1) - at(x+1,y,s-1) ) ;
116 Dys = 0.25 * ( at(x,y+1,s+1) + at(x,y-1,s-1) - at(x,y-1,s+1) - at(x,y+1,s-1) ) ;
117
118 /* Solve linear system. */
119 Aat(0,0) = Dxx ;
120 Aat(1,1) = Dyy ;
121 Aat(2,2) = Dss ;
122 Aat(0,1) = Aat(1,0) = Dxy ;
123 Aat(0,2) = Aat(2,0) = Dxs ;
124 Aat(1,2) = Aat(2,1) = Dys ;
125
126 b[0] = - Dx ;
127 b[1] = - Dy ;
128 b[2] = - Ds ;
129
130 /* If the translation of the keypoint is big, move the keypoint
131 * and re-iterate the computation. Otherwise we are all set.
132 */
133 dx= ((b[0] > 0.6 && x < N-2) ? 1 : 0 )
134 + ((b[0] < -0.6 && x > 1 ) ? -1 : 0 ) ;
135
136 dy= ((b[1] > 0.6 && y < M-2) ? 1 : 0 )
137 + ((b[1] < -0.6 && y > 1 ) ? -1 : 0 ) ;
138
139 if( dx == 0 && dy == 0 )
140 break ;
141
142 }
143
144 {
145 float val = at(x,y,s) + 0.5 * (Dx * b[0] + Dy * b[1] + Ds * b[2]) ;
146 float score = (Dxx+Dyy)*(Dxx+Dyy) / (Dxx*Dyy - Dxy*Dxy) ;
147 float xn = x + b[0] ;
148 float yn = y + b[1] ;
149 float sn = s + b[2] ;
150
151 if(fabs(val) > thresh &&
152 score < (r+1)*(r+1)/r &&
153 score >= 0 &&
154 fabs(b[0]) < 1.5 &&
155 fabs(b[1]) < 1.5 &&
156 fabs(b[2]) < 1.5 &&
157 xn >= 0 &&
158 xn <= N-1 &&
159 yn >= 0 &&
160 yn <= M-1 &&
161 sn >= 0 &&
162 sn <= S-1)
163 {
164 asubsref(buffer,buffCounter++) = xn ;
165 asubsref(buffer,buffCounter++) = yn ;
166 asubsref(buffer,buffCounter++) = sn+smin ;
167 }
168 }
169 }
170 }
171
172 /* Copy the result into an array. */
173 {
174 int i, j, k=0;
175 int NL = buffCounter/3;
176 out = fMallocHandle(3, NL);
177
178 for(i=0; i<NL; i++)
179 {
180 for(j=0; j<3; j++)
181 {
182 subsref(out,j,i) = asubsref(buffer,k);
183 k++;
184 }
185 }
186 }
187 free(buffer) ;
188 }
189
190 return out;
191}
192
193
194
195
196