-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRegularizer.cpp
More file actions
114 lines (92 loc) · 3.31 KB
/
Copy pathRegularizer.cpp
File metadata and controls
114 lines (92 loc) · 3.31 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "Regularizer.h"
Regularizer::Regularizer(){
}
Regularizer::~Regularizer(){
}
void Regularizer::Start(int s){
//size means number of pixels in the image
size = s;
A.resize(size, size);
alphas.resize(size, 0);
B.resize(s);
}
void Regularizer::Regularize(Mat raw_depth, Mat& depth, float beta, int Iteration){
int rows = raw_depth.rows;
int cols = raw_depth.cols;
depth = Mat(rows, cols, CV_32FC1);
LoadCoefficients(raw_depth, beta);
VectorXf x(rows * cols);
VectorXf guess(rows * cols);
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
guess[r * cols + c] = raw_depth.at<float>(r,c);
}
}
//**** RowMajor Here is important *****
ConjugateGradient<SparseMatrix<float,RowMajor>, Lower|Upper> cg;
cg.setMaxIterations(15);
cg.compute(A);
x = cg.solveWithGuess(B,guess);
// std::cout << "#iterations: " << cg.iterations() << std::endl;
// std::cout << "estimated error: " << cg.error() << std::endl;
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
int index = cols * r + c;
depth.at<float>(r,c) = x[index];
}
}
}
/* Loading the alpha according to the passing alpha
* If the value of alpha is less than 0 or somehow
* meaningless (-nan) then just set as 0
*/
void Regularizer::LoadAlphas(int pos, float alpha){
alphas[pos] = (alpha < 0 || isnan(alpha))? 0:alpha;
}
void Regularizer::LoadCoefficients(Mat raw_depth, float beta){
//when load coefficients is called, we can suppose alphas finished loading
float neighbor_diff_threshold = 4.0;
A.setZero();
int rows = raw_depth.rows;
int cols = raw_depth.cols;
//ignore the edge
for(int r = 1; r < rows-1; r++){
for(int c = 1; c < cols-1; c++){
int index = cols * r + c;
int val_o = raw_depth.at<float>(r,c);
//if depth value of current pixel is 0 then set b to 0 and ignore
if(val_o == 0){
B[index] = 0;
continue;
}
A.coeffRef(index,index) = 2 * alphas[index];
/* if depth value of neighbor pixels is 0 or
* the absolute different is larger than threshold,
* then set weight to 0 (dismiss the loop)
*/
for(int i = 0; i < 4; i++){
int up = (i==0)?1:0;
int dw = (i==1)?1:0;
int lf = (i==2)?1:0;
int rt = (i==3)?1:0;
int new_r = r + up - dw;
int new_c = c + rt - lf;
float val_n = raw_depth.at<float>(new_r,new_c);
float f_abs = fabs(val_n - val_o);
if(val_n == 0 || f_abs > neighbor_diff_threshold){
continue;
}
//add to diagonal
float weight = 1.0/(1 + beta * f_abs);
A.coeffRef(index,index) += 2 * 2 * weight;
/* set coefficient of sparse matrix of same row with
* column number correponds to the position of neighboring
* pixels
*/
int new_index = new_r * cols + new_c;
A.coeffRef(index, new_index) = -2 * 2 * weight;
}
B[index] = 2 * val_o * alphas[index];
}
}
}