b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
1
2
3
|
#include <stim/image/image.h>
#include <cmath>
#include <stim/visualization/colormap.h>
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
4
5
6
|
#define PI 3.1415926
|
40d11588
Tianshu Cheng
2D inseparable co...
|
7
8
9
10
|
void conv2(float* img, float* mask, float* cpu_copy, unsigned int w, unsigned int h, unsigned int M);
void array_abs(float* img, unsigned int N);
void array_multiply(float* lhs, float rhs, unsigned int N);
|
7fab7a98
Tianshu Cheng
a neat version of...
|
11
|
/// This function evaluates the gaussian derivative gradient given an one-channel image
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
12
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
13
14
|
/// @param img is the one-channel image
/// @param r is an array of radii for different scaled discs(filters)
|
6dcc460e
Tianshu Cheng
cPb+tPb
|
15
|
/// @param sigma_n is the number of standard deviations used to define the sigma
|
7fab7a98
Tianshu Cheng
a neat version of...
|
16
|
/// @param theta is angle used for computing the gradient
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
17
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
18
|
stim::image<float> gaussian_derivative_filter_odd(stim::image<float> image, int r, unsigned int sigma_n, float theta){
|
e166b01b
Tianshu Cheng
simple mask test
|
19
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
20
21
22
23
24
|
unsigned int w = image.width(); // get the width of picture
unsigned int h = image.height(); // get the height of picture
unsigned N = w * h; // get the number of pixels of picture
int winsize = 2 * r + 1; // set the winsdow size of disc(filter)
float sigma = float(r)/float(sigma_n); // calculate the sigma used in gaussian function
|
e166b01b
Tianshu Cheng
simple mask test
|
25
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
26
27
28
29
|
stim::image<float> mask_x(winsize, winsize); // allocate space for x-axis-oriented filter
stim::image<float> mask_y(winsize, winsize); // allocate space for y-axis-oriented filter
stim::image<float> mask_theta(winsize, winsize);// allocate space for theta-oriented filter
stim::image<float> derivative_theta(w, h); // allocate space for theta-oriented gradient
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
30
|
|
6dcc460e
Tianshu Cheng
cPb+tPb
|
31
32
33
|
stim::image<float> mask_r;
|
7fab7a98
Tianshu Cheng
a neat version of...
|
34
|
float theta_r = (theta * PI)/180; //change angle unit from degree to rad
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
35
|
|
6dcc460e
Tianshu Cheng
cPb+tPb
|
36
|
//*************inseparable convolution****************
|
7fab7a98
Tianshu Cheng
a neat version of...
|
37
38
|
for (int j = 0; j < winsize; j++){
for (int i = 0; i< winsize; i++){
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
39
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
40
41
|
int x = i - r; //range of x
int y = j - r; //range of y
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
42
43
|
// create the x-oriented gaussian derivative filter mask_x
|
7fab7a98
Tianshu Cheng
a neat version of...
|
44
|
mask_x.data()[j*winsize + i] = (-1) * x * exp((-1)*(pow(x, 2))/(2*pow(sigma, 2))) * exp((-1)*(pow(y, 2))/(2*pow(sigma, 2)));
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
45
|
// create the y-oriented gaussian derivative filter mask_y
|
7fab7a98
Tianshu Cheng
a neat version of...
|
46
|
mask_y.data()[j*winsize + i] = (-1) * y * exp((-1)*(pow(y, 2))/(2*pow(sigma, 2))) * exp((-1)*(pow(x, 2))/(2*pow(sigma, 2)));
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
47
|
// create the mask_theta
|
7fab7a98
Tianshu Cheng
a neat version of...
|
48
|
mask_theta.data()[j*winsize + i] = cos(theta_r) * mask_x.data()[j*winsize + i] + sin(theta_r) * mask_y.data()[j*winsize + i] ;
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
49
50
51
52
|
}
}
|
6dcc460e
Tianshu Cheng
cPb+tPb
|
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
mask_r = mask_x.rotate(90, r, r);
stim::cpu2image(mask_r.data(), "data_output/mask_r90_0915.bmp", winsize, winsize, stim::cmBrewer);
//stim::cpu2image(mask_theta.data(), "data_output/mask_0911_2.bmp", winsize, winsize, stim::cmBrewer); // (optional) show the mask result
// do the 2D convolution with image and mask
conv2(image.data(), mask_theta.data(), derivative_theta.data(), w, h, winsize);
//*********************************************************/
/*************separable convolution****************
for (int i = 0; i < winsize; i++){
int x = i - r; //range of x
int y = i - r; //range of y
// create the 1D x-oriented gaussian derivative filter array_x
array_x[i] = exp((-1)*(pow(x, 2))/(2*pow(sigma, 2)));
// create the 1D y-oriented gaussian derivative filter array_y
array_y[i] = (-1) * y * exp((-1)*(pow(y, 2))/(2*pow(sigma, 2)));
}
|
7fab7a98
Tianshu Cheng
a neat version of...
|
75
|
//stim::cpu2image(mask_theta.data(), "data_output/mask_0911_2.bmp", winsize, winsize, stim::cmBrewer); // (optional) show the mask result
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
76
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
77
78
|
// do the 2D convolution with image and mask
conv2(image.data(), mask_theta.data(), derivative_theta.data(), w, h, winsize);
|
6dcc460e
Tianshu Cheng
cPb+tPb
|
79
|
//*********************************************************/
|
40d11588
Tianshu Cheng
2D inseparable co...
|
80
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
81
|
array_abs(derivative_theta.data(), N); // get the absolute value for each pixel (why slower than the "for loop" method sometimes?)
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
82
|
|
6dcc460e
Tianshu Cheng
cPb+tPb
|
83
|
float max = derivative_theta.maxv(); // get the maximum of gradient used for normalization
|
7fab7a98
Tianshu Cheng
a neat version of...
|
84
|
array_multiply(derivative_theta.data(), 1/max, N); // normalize the gradient
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
85
|
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
86
|
|
7fab7a98
Tianshu Cheng
a neat version of...
|
87
|
//stim::cpu2image(derivative_theta.data(), "data_output/derivative_theta_0911.bmp", w, h, stim::cmBrewer); // (optional) show the gradient result
|
b71cc8bb
Tianshu Cheng
mPb using 3 channels
|
88
89
90
|
return derivative_theta;
|
abaf5630
David Mayerich
fixed the signed/...
|
91
|
}
|