9 void convolveSeparableGray(
unsigned char* I,
unsigned int width,
unsigned int height,
const int kernel[],
unsigned int size,
int divisor)
11 std::vector<unsigned char> buffer(width>height ? width : height);
17 for (i=height; i>0; i--) {
18 for (j=0;j<width-size+1;j++) {
20 for (m=0; m<size; m++)
21 sum += p[j+m] * kernel[m];
22 buffer[j] = (
unsigned char)(sum/divisor);
24 memcpy(p+size/2, &buffer.front(), width-size+1);
27 for (j=0;j<width-size+1;j++) {
28 p = I+j+(size/2)*width;
29 for (i=0; i<height;i++)
30 buffer[i] = I[i*width+j];
31 for (i=0;i<height-size+1;i++) {
33 for (m=0; m<size; m++)
34 sum += buffer[i+m] * kernel[m];
35 *p = (
unsigned char)(sum/divisor);
50 byte* end = src + w*(h-4);
52 int sum= (3571*(src[0]+src[4*w])
53 + 16004*(src[w]+src[3*w])
59 for (i=h-5;i>=0;i--) {
61 byte* end = src + w-4;
63 int sum= (3571*(src[0]+src[4])
64 + 16004*(src[1]+src[3])
66 *(src+2*w+2) = sum >> 16;
74 const double a = d[0];
75 const double b = d[1];
76 const double num = 2*(a*(a*(a-2) + 1 + b*b) - 2*b*b);
77 const double den1 = a*a - b*b -2*a + 1;
78 const double den2 = 2*(a-1)*b;
79 const double inv_den = 1.0/(den1*den1 + den2*den2);
81 const double inv_den3 = 1.0/((d[2]-1)*(d[2]-1));
83 return 2*(num * inv_den + d[2] * inv_den3);
88 const double a = d[0];
89 const double b = d[1];
90 const double num = 2*(a*(a*(a-2) + 1 + b*b) - 2*b*b);
91 const double den1 = a*a - b*b -2*a + 1;
92 const double den2 = 2*(a-1)*b;
93 const double inv_den = 1.0/(den1*den1 + den2*den2);
94 const double inv_den3 = 1.0/((d[2]-1)*(d[2]-1));
96 double N_D = num*inv_den;
97 J[0] = 2*inv_den * (2*(a*(3*a - 4) + (1+b*b)) - N_D * 4*(den1*(a-1) + den2*b));
98 J[1] = 2*inv_den * (4*b*(a - 2) - N_D * 4*(den2*(a-1) - den1*b));
99 J[2] = 2*inv_den3*(1 - d[2]*inv_den3*2*(d[2]-1));
101 return 2*(N_D + d[2] * inv_den3);
106 double rr = d[0]*d[0] + d[1]*d[1];
107 double lnr = 0.5 * log(rr);
108 double theta = atan2(d[1], d[0]);
109 J[0] = d[0]*lnr - d[1]*theta;
110 J[1] = d[0]*theta + d[1]*lnr;
111 J[2] = d[2]*log(d[2]);
116 double theta = atan2(d[1], d[0]);
117 double rr = d[0]*d[0] + d[1]*d[1];
118 double new_theta = theta*p;
119 double new_r = pow(rr, p*0.5);
120 d[0] = new_r * cos(new_theta);
121 d[1] = new_r * sin(new_theta);
133 const double A = 3.69892409013e-03;
134 const double B =-4.28967830150e-02;
135 const double C =-3.38065667167e-01;
136 const double D = 5.44264202732e-01;
138 double log_var = 2*log(sigma);
139 double log_p = D + log_var*(C + log_var*(B + log_var*A));
140 double predicted_p =
exp(log_p);
145 const double target_var = sigma*sigma;
149 for (
int i=0; i<5; ++i)
154 double step = v / (vj[0]*sj[0] + vj[1]*sj[1] + vj[2]*sj[2]);
155 if (CVD::abs<double>(step) < 1e-6)
157 double exp_step =
exp(std::min(std::max(step, -1.0), 1.0));
165 double B = 1.0/(d[2]*(d[0]*d[0] + d[1]*d[1]));
167 b[1] = B*(2*d[0] + d[2]);
168 b[0] = -B*(d[0]*d[0] + d[1]*d[1] + 2*(d[0] * d[2]));
180 const double a1= -b[0];
181 const double a2= -b[1];
182 const double a3= -b[2];
184 const double factor = 1.0/((1+a1-a2+a3)*
187 M[0][0] = factor*(1-a2-a1*a3-a3*a3);
188 M[0][1] = factor*(a3+a1)*(a2+a1*a3);
189 M[0][2] = factor*a3*(a1 + a2*a3);
190 M[1][0] = a1*M[0][0] + M[0][1];
191 M[1][1] = a2*M[0][0] + M[0][2];
192 M[1][2] = a3*M[0][0];
193 M[2][0] = a1*M[1][0] + M[1][1];
194 M[2][1] = a2*M[1][0] + M[1][2];
195 M[2][2] = a3*M[1][0];
198 inline void forward_to_backward(
const double M[][3],
const double i_plus,
const double inv_alpha,
double& y1,
double& y2,
double& y3)
200 const double u_plus = i_plus*inv_alpha;
201 const double v_plus = u_plus*inv_alpha;
202 double x1=y1-u_plus, x2=y2-u_plus, x3=y3-u_plus;
203 y1 = M[0][0]*x1 + M[0][1]*x2 + M[0][2]*x3 + v_plus;
204 y2 = M[1][0]*x1 + M[1][1]*x2 + M[1][2]*x3 + v_plus;
205 y3 = M[2][0]*x1 + M[2][1]*x2 + M[2][2]*x3 + v_plus;
208 template <
class T>
inline T
clamp01(T x) {
return x < 0 ? 0 : (x > 1 ? 1 : x); }
218 const int w = in.
size().
x;
219 const int h = in.
size().
y;
224 vector<double> tmp(w);
226 const double b0 = b[0];
227 const double b1 = b[1];
228 const double b2 = b[2];
231 const double alpha = 1 + b0 + b1 + b2;
232 const double inv_alpha = 1.0/alpha;
234 for (
int i=0; i<h; ++i) {
235 const float* p = in[i]+w-1;
238 y3 = y2 = y1 = inv_alpha* *p;
241 for (
int j=w-1; j-3>=0; j-=4, p-=4) {
242 double y0 = p[0] - (b0*y1 + b1*y2 + b2 * y3);
243 y3 = p[-1] - (b0*y0 + b1*y1 + b2 * y2);
244 y2 = p[-2] - (b0*y3 + b1*y0 + b2 * y1);
245 y1 = p[-3] - (b0*y2 + b1*y3 + b2 * y0);
252 for (
int j=rw-1; j>=0; --j, --p) {
253 double y0 = p[0] - (b0*y1 + b1*y2 + b2 * y3);
255 y3 = y2; y2 = y1; y1 = y0;
259 const double i_plus = p[1];
260 double y0 = i_plus - (b0*y1 + b1*y2 + b2*y3);
266 for (
int j=0; j+3<w; j+=4, o+=4) {
267 double y0 = tmp[j] - (b0*y1 + b1*y2 + b2 * y3);
268 y3 = tmp[j+1] - (b0*y0 + b1*y1 + b2 * y2);
269 y2 = tmp[j+2] - (b0*y3 + b1*y0 + b2 * y1);
270 y1 = tmp[j+3] - (b0*y2 + b1*y3 + b2 * y0);
277 for (
int j=w-rw; j<w; ++j, ++o) {
278 double y0 = tmp[j] - (b0*y1 + b1*y2 + b2 * y3);
280 y3 = y2; y2 = y1; y1 = y0;
287 const double alpha_fourth = alpha*alpha*alpha*alpha;
291 for (
int i=0; i<w; ++i) {
294 const float* in = out[h-1] + i;
295 y3 = y2 = y1 = inv_alpha* *in;
297 for (
int j=h-1; j-3>=0; j-=4, in -= stride) {
298 double y0 = in[0] - (b0*y1 + b1*y2 + b2 * y3);
300 y3 = in[0] - (b0*y0 + b1*y1 + b2 * y2);
302 y2 = in[0] - (b0*y3 + b1*y0 + b2 * y1);
304 y1 = in[0] - (b0*y2 + b1*y3 + b2 * y0);
311 for (
int j=rh-1; j>=0; --j, in-=stride) {
312 double y0 = in[0] - (b0*y1 + b1*y2 + b2 * y3);
314 y3 = y2; y2 = y1; y1 = y0;
318 const double i_plus = in[stride];
319 double y0 = i_plus - (b0*y1 + b1*y2 + b2*y3);
325 for (
int j=0; j+3<h; j+=4) {
326 double y0 = tmp[j] - (b0*y1 + b1*y2 + b2 * y3);
327 y3 = tmp[j+1] - (b0*y0 + b1*y1 + b2 * y2);
328 y2 = tmp[j+2] - (b0*y3 + b1*y0 + b2 * y1);
329 y1 = tmp[j+3] - (b0*y2 + b1*y3 + b2 * y0);
330 o[0] = (float)(alpha_fourth*y0);
332 o[0] = (float)(alpha_fourth*y3);
334 o[0] = (float)(alpha_fourth*y2);
336 o[0] = (float)(alpha_fourth*y1);
340 for (
int j=h-rh; j<h; ++j, o+=stride) {
341 double y0 = tmp[j] - (b0*y1 + b1*y2 + b2 * y3);
342 o[0] = (float)(alpha_fourth*y0);
343 y3 = y2; y2 = y1; y1 = y0;
void compute_van_vliet_scaled_d(double sigma, double d[])
int row_stride() const
What is the row stride of the image?
void compute_scaling_jacobian(const double d[], double J[])
void convolveGaussian5_1(Image< byte > &I)
Matrix< R, C, P > exp(const Matrix< R, C, P, B > &m)
ImageRef size() const
What is the size of this image?
double compute_van_vliet_variance(const double d[], double J[3])
const T * data() const
Returns the raw image data.
void convolveSeparableGray(unsigned char *I, unsigned int width, unsigned int height, const int kernel[], unsigned int size, int divisor)
void scale_d(double d[], double p)
void compute_triggs_M(const double b[], double M[][3])
void build_van_vliet_b(const double d[], double b[])
void compute_van_vliet_b(double sigma, double b[])
void van_vliet_blur(const double b[], const CVD::SubImage< float > in, CVD::SubImage< float > out)
void forward_to_backward(const double M[][3], const double i_plus, const double inv_alpha, double &y1, double &y2, double &y3)