-
Notifications
You must be signed in to change notification settings - Fork 20
/
mgm_weights.h
85 lines (75 loc) · 2.64 KB
/
mgm_weights.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* Copyright (C) 2015, Gabriele Facciolo <[email protected]>,
* Carlo de Franchis <[email protected]>,
* Enric Meinhardt <[email protected]>*/
#define __max(a,b) (((a) > (b)) ? (a) : (b))
#define __min(a,b) (((a) < (b)) ? (a) : (b))
// fast alternatives to: __min(a,__min(b,c))
// fastestest ?
#define fmin3_(x, y, z) \
(((x) < (y)) ? (((z) < (x)) ? (z) : (x)) : (((z) < (y)) ? (z) : (y)))
// fast and easy to understand
//static inline float fmin3(float a, float b, float c)
//{
// float m = a;
// if (m > b) m = b;
// if (m > c) m = c;
// return m;
//}
inline float fastexp(float x) {
int result = static_cast<int>(12102203 * x) + 1065353216;
result *= result > 0;
std::memcpy(&x, &result, sizeof(result));
return x;
}
inline float deltaImage(const struct Img &u, const Point p, const Point q)
{
float d = 0;
for (int c = 0; c < u.nch; c++){
float diff = val(u, p, c) - val(u, q, c);
// d += diff > 0 ? diff : -diff;
d += diff * diff;
// d = __max(d, fabs(val(u, p, c) - val(u, q, c))) ;
}
return d/u.nch;
}
inline float ws( float DeltaI, float aP3, float Thresh) {
if (fabs(DeltaI) < Thresh*Thresh) return aP3;
else return 1;
//// implements weights from "simple but effective tree structure for dynamic programming-based stereo matching" Blayer, Gelautz
// float T=30;
// float P3=4;
// if (fabs(DeltaI) < T) return P3;
// else return 1;
//
//// implements image adaptive weights from formula 1 of "Efficient High-Resolution Stereo Matching using Local Plane Sweeps"
// float sigmaI=128;
// float alpha=10;
// return (8 + alpha * fastexp( - fabs(DeltaI) / sigmaI))/32.0;
// return 8.0/32.0 + 1.0/__max(fabs(DeltaI),0.0001);
//
// return 1.;
}
// For a pixel p each image of the stack correspond the weights to
// int neighbouring pixels: W, E, S, N, (NW, NE, SE, SW)
struct Img compute_mgm_weights(struct Img &u, float aP, float aThresh)
{
int nx = u.nx;
int ny = u.ny;
// load the edge weights (or initialize them to 1: TODO)
struct Img w(nx, ny, 8);
Point scans[] = {Point(-1,0), Point(1,0), Point(0,1), Point(0,-1), Point(-1,-1), Point(1,-1), Point(1,1), Point(-1,1)};
for (int o = 0; o < 8 ; o++)
for (int j = 0; j < ny; j++)
for (int i = 0; i < nx; i++)
{
float wvalue = 1.0;
Point p(i,j); // current point
Point pr = p + scans[o]; // neighbor
if (check_inside_image(pr ,u)) {
float Delta = deltaImage(u,p,pr);
wvalue = ws(Delta, aP, aThresh);
}
w[i + j*nx + o*nx*ny] = wvalue;
}
return w;
}