Subversion Repositories seema-scanner

Rev

Rev 190 | Rev 195 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 190 Rev 192
1
//
1
//
2
// Two Frequency Phase Shifting using the Heterodyne Principle
2
// Two Frequency Phase Shifting using the Heterodyne Principle
3
//
3
//
4
// This implementation follows "Reich, Ritter, Thesing, White light heterodyne principle for 3D-measurement", SPIE (1997)
4
// This implementation follows "Reich, Ritter, Thesing, White light heterodyne principle for 3D-measurement", SPIE (1997)
5
// Different from the paper, it uses only two different frequencies.
5
// Different from the paper, it uses only two different frequencies.
6
//
6
//
7
// The number of periods in the primary frequency can be chosen freely, but small changes can have a considerable impact on quality.
7
// The number of periods in the primary frequency can be chosen freely, but small changes can have a considerable impact on quality.
8
// The number of phase shifts can be chosen freely (min. 3), and higher values reduce the effects of image noise. They also allow us to filter bad points based on energy at non-primary frequencies.
8
// The number of phase shifts can be chosen freely (min. 3), and higher values reduce the effects of image noise. They also allow us to filter bad points based on energy at non-primary frequencies.
9
//
9
//
10
 
10
 
11
#include "AlgorithmPhaseShiftTwoFreq.h"
11
#include "AlgorithmPhaseShiftTwoFreq.h"
12
#include <math.h>
12
#include <math.h>
13
 
13
 
14
#include "cvtools.h"
14
#include "cvtools.h"
15
#include "algorithmtools.h"
15
#include "algorithmtools.h"
16
 
16
 
17
#ifndef M_PI
-
 
18
    #define M_PI 3.14159265358979323846
-
 
19
#endif
-
 
20
 
-
 
21
static unsigned int nStepsPrimary = 16; // number of shifts/steps in primary
17
static unsigned int nStepsPrimary = 16; // number of shifts/steps in primary
22
static unsigned int nStepsSecondary = 8; // number of shifts/steps in secondary
18
static unsigned int nStepsSecondary = 8; // number of shifts/steps in secondary
23
static float nPeriodsPrimary = 40; // primary period
19
static float nPeriodsPrimary = 40; // primary period
24
 
20
 
25
AlgorithmPhaseShiftTwoFreq::AlgorithmPhaseShiftTwoFreq(unsigned int _screenCols, unsigned int _screenRows) : Algorithm(_screenCols, _screenRows){
21
AlgorithmPhaseShiftTwoFreq::AlgorithmPhaseShiftTwoFreq(unsigned int _screenCols, unsigned int _screenRows) : Algorithm(_screenCols, _screenRows){
26
 
22
 
27
    // Set N
23
    // Set N
28
    N = 2+nStepsPrimary+nStepsSecondary;
24
    N = 2+nStepsPrimary+nStepsSecondary;
29
 
25
 
30
    // Determine the secondary (wider) period to fulfill the heterodyne condition
26
    // Determine the secondary (wider) period to fulfill the heterodyne condition
31
    float nPeriodsSecondary = nPeriodsPrimary + 1;
27
    float nPeriodsSecondary = nPeriodsPrimary + 1;
32
 
28
 
33
    // all on pattern
29
    // all on pattern
34
    cv::Mat allOn(1, screenCols, CV_8UC3, cv::Scalar::all(255));
30
    cv::Mat allOn(1, screenCols, CV_8UC3, cv::Scalar::all(255));
35
    patterns.push_back(allOn);
31
    patterns.push_back(allOn);
36
 
32
 
37
    // all off pattern
33
    // all off pattern
38
    cv::Mat allOff(1, screenCols, CV_8UC3, cv::Scalar::all(0));
34
    cv::Mat allOff(1, screenCols, CV_8UC3, cv::Scalar::all(0));
39
    patterns.push_back(allOff);
35
    patterns.push_back(allOff);
40
 
36
 
41
    // Precompute encoded patterns
-
 
42
    const float pi = M_PI;
-
 
43
 
-
 
44
    // Primary encoding patterns
37
    // Primary encoding patterns
45
    for(unsigned int i=0; i<nStepsPrimary; i++){
38
    for(unsigned int i=0; i<nStepsPrimary; i++){
46
        float phase = 2.0*pi/nStepsPrimary * i;
39
        float phase = 2.0*CV_PI/nStepsPrimary * i;
47
        float pitch = screenCols/nPeriodsPrimary;
40
        float pitch = screenCols/nPeriodsPrimary;
48
        cv::Mat patternI(1,1,CV_8U);
41
        cv::Mat patternI(1,1,CV_8U);
49
        patternI = computePhaseVector(screenCols, phase, pitch);
42
        patternI = computePhaseVector(screenCols, phase, pitch);
50
        patterns.push_back(patternI.t());
43
        patterns.push_back(patternI.t());
51
    }
44
    }
52
 
45
 
53
    // Secondary encoding patterns
46
    // Secondary encoding patterns
54
    for(unsigned int i=0; i<nStepsSecondary; i++){
47
    for(unsigned int i=0; i<nStepsSecondary; i++){
55
        float phase = 2.0*pi/nStepsSecondary * i;
48
        float phase = 2.0*CV_PI/nStepsSecondary * i;
56
        float pitch = screenCols/nPeriodsSecondary;
49
        float pitch = screenCols/nPeriodsSecondary;
57
        cv::Mat patternI(1,1,CV_8U);
50
        cv::Mat patternI(1,1,CV_8U);
58
        patternI = computePhaseVector(screenCols, phase, pitch);
51
        patternI = computePhaseVector(screenCols, phase, pitch);
59
        patterns.push_back(patternI.t());
52
        patterns.push_back(patternI.t());
60
    }
53
    }
61
 
54
 
62
 
55
 
63
}
56
}
64
 
57
 
65
cv::Mat AlgorithmPhaseShiftTwoFreq::getEncodingPattern(unsigned int depth){
58
cv::Mat AlgorithmPhaseShiftTwoFreq::getEncodingPattern(unsigned int depth){
66
    return patterns[depth];
59
    return patterns[depth];
67
}
60
}
68
 
61
 
69
void AlgorithmPhaseShiftTwoFreq::get3DPoints(SMCalibrationParameters calibration, const std::vector<cv::Mat>& frames0, const std::vector<cv::Mat>& frames1, std::vector<cv::Point3f>& Q, std::vector<cv::Vec3b>& color){
62
void AlgorithmPhaseShiftTwoFreq::get3DPoints(SMCalibrationParameters calibration, const std::vector<cv::Mat>& frames0, const std::vector<cv::Mat>& frames1, std::vector<cv::Point3f>& Q, std::vector<cv::Vec3b>& color){
70
 
63
 
71
    const float pi = M_PI;
-
 
72
 
-
 
73
    assert(frames0.size() == N);
64
    assert(frames0.size() == N);
74
    assert(frames1.size() == N);
65
    assert(frames1.size() == N);
75
 
66
 
76
    int frameRows = frames0[0].rows;
67
    int frameRows = frames0[0].rows;
77
    int frameCols = frames0[0].cols;
68
    int frameCols = frames0[0].cols;
78
 
69
 
79
    // Rectifying homographies (rotation+projections)
70
    // Rectifying homographies (rotation+projections)
80
    cv::Size frameSize(frameCols, frameRows);
71
    cv::Size frameSize(frameCols, frameRows);
81
    cv::Mat R, T;
72
    cv::Mat R, T;
82
    // stereoRectify segfaults unless R is double precision
73
    // stereoRectify segfaults unless R is double precision
83
    cv::Mat(calibration.R1).convertTo(R, CV_64F);
74
    cv::Mat(calibration.R1).convertTo(R, CV_64F);
84
    cv::Mat(calibration.T1).convertTo(T, CV_64F);
75
    cv::Mat(calibration.T1).convertTo(T, CV_64F);
85
    cv::Mat R0, R1, P0, P1, QRect;
76
    cv::Mat R0, R1, P0, P1, QRect;
86
    cv::stereoRectify(calibration.K0, calibration.k0, calibration.K1, calibration.k1, frameSize, R, T, R0, R1, P0, P1, QRect, 0);
77
    cv::stereoRectify(calibration.K0, calibration.k0, calibration.K1, calibration.k1, frameSize, R, T, R0, R1, P0, P1, QRect, 0);
87
 
78
 
88
    // Interpolation maps (lens distortion and rectification)
79
    // Interpolation maps (lens distortion and rectification)
89
    cv::Mat map0X, map0Y, map1X, map1Y;
80
    cv::Mat map0X, map0Y, map1X, map1Y;
90
    cv::initUndistortRectifyMap(calibration.K0, calibration.k0, R0, P0, frameSize, CV_32F, map0X, map0Y);
81
    cv::initUndistortRectifyMap(calibration.K0, calibration.k0, R0, P0, frameSize, CV_32F, map0X, map0Y);
91
    cv::initUndistortRectifyMap(calibration.K1, calibration.k1, R1, P1, frameSize, CV_32F, map1X, map1Y);
82
    cv::initUndistortRectifyMap(calibration.K1, calibration.k1, R1, P1, frameSize, CV_32F, map1X, map1Y);
92
 
83
 
93
    int frameRectRows = map0X.rows;
84
    int frameRectRows = map0X.rows;
94
    int frameRectCols = map0X.cols;
85
    int frameRectCols = map0X.cols;
95
 
86
 
96
    // Gray-scale and remap
87
    // Gray-scale and remap
97
    std::vector<cv::Mat> frames0Rect(N);
88
    std::vector<cv::Mat> frames0Rect(N);
98
    std::vector<cv::Mat> frames1Rect(N);
89
    std::vector<cv::Mat> frames1Rect(N);
99
    for(unsigned int i=0; i<N; i++){
90
    for(unsigned int i=0; i<N; i++){
100
        cv::Mat temp;
91
        cv::Mat temp;
101
        cv::cvtColor(frames0[i], temp, CV_BayerBG2GRAY);
92
        cv::cvtColor(frames0[i], temp, CV_BayerBG2GRAY);
102
        cv::remap(temp, frames0Rect[i], map0X, map0Y, CV_INTER_LINEAR);
93
        cv::remap(temp, frames0Rect[i], map0X, map0Y, CV_INTER_LINEAR);
103
        cv::cvtColor(frames1[i], temp, CV_BayerBG2GRAY);
94
        cv::cvtColor(frames1[i], temp, CV_BayerBG2GRAY);
104
        cv::remap(temp, frames1Rect[i], map1X, map1Y, CV_INTER_LINEAR);
95
        cv::remap(temp, frames1Rect[i], map1X, map1Y, CV_INTER_LINEAR);
105
    }
96
    }
106
 
97
 
107
    // Decode camera0
98
    // Decode camera0
108
    std::vector<cv::Mat> frames0Primary(frames0Rect.begin()+2, frames0Rect.begin()+2+nStepsPrimary);
99
    std::vector<cv::Mat> frames0Primary(frames0Rect.begin()+2, frames0Rect.begin()+2+nStepsPrimary);
109
    std::vector<cv::Mat> frames0Secondary(frames0Rect.begin()+2+nStepsPrimary, frames0Rect.end());
100
    std::vector<cv::Mat> frames0Secondary(frames0Rect.begin()+2+nStepsPrimary, frames0Rect.end());
110
 
101
 
111
    std::vector<cv::Mat> F0Primary = getDFTComponents(frames0Primary);
102
    std::vector<cv::Mat> F0Primary = getDFTComponents(frames0Primary);
112
    cv::Mat up0Primary;
103
    cv::Mat up0Primary;
113
    cv::phase(F0Primary[2], -F0Primary[3], up0Primary);
104
    cv::phase(F0Primary[2], -F0Primary[3], up0Primary);
114
 
105
 
115
    std::vector<cv::Mat> F0Secondary = getDFTComponents(frames0Secondary);
106
    std::vector<cv::Mat> F0Secondary = getDFTComponents(frames0Secondary);
116
    cv::Mat up0Secondary;
107
    cv::Mat up0Secondary;
117
    cv::phase(F0Secondary[2], -F0Secondary[3], up0Secondary);
108
    cv::phase(F0Secondary[2], -F0Secondary[3], up0Secondary);
118
 
109
 
119
    cv::Mat up0Equivalent = up0Secondary - up0Primary;
110
    cv::Mat up0Equivalent = up0Secondary - up0Primary;
120
    up0Equivalent = cvtools::modulo(up0Equivalent, 2.0*pi);
111
    up0Equivalent = cvtools::modulo(up0Equivalent, 2.0*CV_PI);
121
    cv::Mat up0 = unwrapWithCue(up0Primary, up0Equivalent, nPeriodsPrimary);
112
    cv::Mat up0 = unwrapWithCue(up0Primary, up0Equivalent, nPeriodsPrimary);
122
    up0 *= screenCols/(2.0*pi);
113
    up0 *= screenCols/(2.0*CV_PI);
123
    cv::Mat amplitude0;
114
    cv::Mat amplitude0;
124
    cv::magnitude(F0Primary[2], -F0Primary[3], amplitude0);
115
    cv::magnitude(F0Primary[2], -F0Primary[3], amplitude0);
125
 
116
 
126
    // Collected signal energy at higher frequencies
117
    // Collected signal energy at higher frequencies
127
    cv::Mat energy0Primary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
118
    cv::Mat energy0Primary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
128
    for(unsigned int i=0; i<nStepsPrimary-1; i++){
119
    for(unsigned int i=0; i<nStepsPrimary-1; i++){
129
        cv::Mat magnitude;
120
        cv::Mat magnitude;
130
        cv::magnitude(F0Primary[i*2 + 2], F0Primary[i*2 + 3], magnitude);
121
        cv::magnitude(F0Primary[i*2 + 2], F0Primary[i*2 + 3], magnitude);
131
        cv::add(energy0Primary, magnitude, energy0Primary, cv::noArray(), CV_32F);
122
        cv::add(energy0Primary, magnitude, energy0Primary, cv::noArray(), CV_32F);
132
    }
123
    }
133
 
124
 
134
    cv::Mat energy0Secondary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
125
    cv::Mat energy0Secondary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
135
    for(unsigned int i=0; i<nStepsSecondary-1; i++){
126
    for(unsigned int i=0; i<nStepsSecondary-1; i++){
136
        cv::Mat magnitude;
127
        cv::Mat magnitude;
137
        cv::magnitude(F0Secondary[i*2 + 2], F0Secondary[i*2 + 3], magnitude);
128
        cv::magnitude(F0Secondary[i*2 + 2], F0Secondary[i*2 + 3], magnitude);
138
        cv::add(energy0Secondary, magnitude, energy0Secondary, cv::noArray(), CV_32F);
129
        cv::add(energy0Secondary, magnitude, energy0Secondary, cv::noArray(), CV_32F);
139
    }
130
    }
140
 
131
 
141
    #ifdef QT_DEBUG
132
    #ifdef QT_DEBUG
142
        cvtools::writeMat(up0Primary, "up0Primary.mat", "up0Primary");
133
        cvtools::writeMat(up0Primary, "up0Primary.mat", "up0Primary");
143
        cvtools::writeMat(up0Secondary, "up0Secondary.mat", "up0Secondary");
134
        cvtools::writeMat(up0Secondary, "up0Secondary.mat", "up0Secondary");
144
        cvtools::writeMat(up0Equivalent, "up0Equivalent.mat", "up0Equivalent");
135
        cvtools::writeMat(up0Equivalent, "up0Equivalent.mat", "up0Equivalent");
145
        cvtools::writeMat(up0, "up0.mat", "up0");
136
        cvtools::writeMat(up0, "up0.mat", "up0");
146
        cvtools::writeMat(amplitude0, "amplitude0.mat", "amplitude0");
137
        cvtools::writeMat(amplitude0, "amplitude0.mat", "amplitude0");
147
        cvtools::writeMat(energy0Primary, "energy0Primary.mat", "energy0Primary");
138
        cvtools::writeMat(energy0Primary, "energy0Primary.mat", "energy0Primary");
148
        cvtools::writeMat(energy0Secondary, "energy0Secondary.mat", "energy0Secondary");
139
        cvtools::writeMat(energy0Secondary, "energy0Secondary.mat", "energy0Secondary");
149
    #endif
140
    #endif
150
 
141
 
151
    // Decode camera1
142
    // Decode camera1
152
    std::vector<cv::Mat> frames1Primary(frames1Rect.begin()+2, frames1Rect.begin()+2+nStepsPrimary);
143
    std::vector<cv::Mat> frames1Primary(frames1Rect.begin()+2, frames1Rect.begin()+2+nStepsPrimary);
153
    std::vector<cv::Mat> frames1Secondary(frames1Rect.begin()+2+nStepsPrimary, frames1Rect.end());
144
    std::vector<cv::Mat> frames1Secondary(frames1Rect.begin()+2+nStepsPrimary, frames1Rect.end());
154
 
145
 
155
    std::vector<cv::Mat> F1Primary = getDFTComponents(frames1Primary);
146
    std::vector<cv::Mat> F1Primary = getDFTComponents(frames1Primary);
156
    cv::Mat up1Primary;
147
    cv::Mat up1Primary;
157
    cv::phase(F1Primary[2], -F1Primary[3], up1Primary);
148
    cv::phase(F1Primary[2], -F1Primary[3], up1Primary);
158
 
149
 
159
    std::vector<cv::Mat> F1Secondary = getDFTComponents(frames1Secondary);
150
    std::vector<cv::Mat> F1Secondary = getDFTComponents(frames1Secondary);
160
    cv::Mat up1Secondary;
151
    cv::Mat up1Secondary;
161
    cv::phase(F1Secondary[2], -F1Secondary[3], up1Secondary);
152
    cv::phase(F1Secondary[2], -F1Secondary[3], up1Secondary);
162
 
153
 
163
    cv::Mat up1Equivalent = up1Secondary - up1Primary;
154
    cv::Mat up1Equivalent = up1Secondary - up1Primary;
164
    up1Equivalent = cvtools::modulo(up1Equivalent, 2.0*pi);
155
    up1Equivalent = cvtools::modulo(up1Equivalent, 2.0*CV_PI);
165
    cv::Mat up1 = unwrapWithCue(up1Primary, up1Equivalent, nPeriodsPrimary);
156
    cv::Mat up1 = unwrapWithCue(up1Primary, up1Equivalent, nPeriodsPrimary);
166
    up1 *= screenCols/(2.0*pi);
157
    up1 *= screenCols/(2.0*CV_PI);
167
    cv::Mat amplitude1;
158
    cv::Mat amplitude1;
168
    cv::magnitude(F1Primary[2], -F1Primary[3], amplitude1);
159
    cv::magnitude(F1Primary[2], -F1Primary[3], amplitude1);
169
 
160
 
170
    // Collected signal energy at higher frequencies
161
    // Collected signal energy at higher frequencies
171
    cv::Mat energy1Primary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
162
    cv::Mat energy1Primary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
172
    for(unsigned int i=0; i<nStepsPrimary-1; i++){
163
    for(unsigned int i=0; i<nStepsPrimary-1; i++){
173
        cv::Mat magnitude;
164
        cv::Mat magnitude;
174
        cv::magnitude(F1Primary[i*2 + 2], F1Primary[i*2 + 3], magnitude);
165
        cv::magnitude(F1Primary[i*2 + 2], F1Primary[i*2 + 3], magnitude);
175
        cv::add(energy1Primary, magnitude, energy1Primary, cv::noArray(), CV_32F);
166
        cv::add(energy1Primary, magnitude, energy1Primary, cv::noArray(), CV_32F);
176
    }
167
    }
177
 
168
 
178
    cv::Mat energy1Secondary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
169
    cv::Mat energy1Secondary(frameRectRows, frameRectCols, CV_32F, cv::Scalar(0.0));
179
    for(unsigned int i=0; i<nStepsSecondary-1; i++){
170
    for(unsigned int i=0; i<nStepsSecondary-1; i++){
180
        cv::Mat magnitude;
171
        cv::Mat magnitude;
181
        cv::magnitude(F1Secondary[i*2 + 2], F1Secondary[i*2 + 3], magnitude);
172
        cv::magnitude(F1Secondary[i*2 + 2], F1Secondary[i*2 + 3], magnitude);
182
        cv::add(energy1Secondary, magnitude, energy1Secondary, cv::noArray(), CV_32F);
173
        cv::add(energy1Secondary, magnitude, energy1Secondary, cv::noArray(), CV_32F);
183
    }
174
    }
184
 
175
 
185
    #ifdef QT_DEBUG
176
    #ifdef QT_DEBUG
186
        cvtools::writeMat(up1, "up1.mat", "up1");
177
        cvtools::writeMat(up1, "up1.mat", "up1");
187
    #endif
178
    #endif
188
 
179
 
189
    // color debayer and remap
180
    // color debayer and remap
190
    cv::Mat color0, color1;
181
    cv::Mat color0, color1;
191
    cv::cvtColor(frames0[0], color0, CV_BayerBG2RGB);
182
    cv::cvtColor(frames0[0], color0, CV_BayerBG2RGB);
192
    cv::remap(color0, color0, map0X, map0Y, CV_INTER_LINEAR);
183
    cv::remap(color0, color0, map0X, map0Y, CV_INTER_LINEAR);
193
 
184
 
194
    cv::cvtColor(frames1[0], color1, CV_BayerBG2RGB);
185
    cv::cvtColor(frames1[0], color1, CV_BayerBG2RGB);
195
    cv::remap(color1, color1, map1X, map1Y, CV_INTER_LINEAR);
186
    cv::remap(color1, color1, map1X, map1Y, CV_INTER_LINEAR);
196
 
187
 
197
    #ifdef QT_DEBUG
188
    #ifdef QT_DEBUG
198
        cvtools::writeMat(color0, "color0.mat", "color0");
189
        cvtools::writeMat(color0, "color0.mat", "color0");
199
        cvtools::writeMat(color1, "color1.mat", "color1");
190
        cvtools::writeMat(color1, "color1.mat", "color1");
200
    #endif
191
    #endif
201
 
192
 
202
    // Occlusion masks
193
    // Occlusion masks
203
    cv::Mat occlusion0, occlusion1;
194
    cv::Mat occlusion0, occlusion1;
204
    cv::subtract(frames0Rect[0], frames0Rect[1], occlusion0);
195
    cv::subtract(frames0Rect[0], frames0Rect[1], occlusion0);
205
    occlusion0 = (occlusion0 > 25) & (occlusion0 < 250);
196
    occlusion0 = (occlusion0 > 25) & (occlusion0 < 250);
206
    cv::subtract(frames1Rect[0], frames1Rect[1], occlusion1);
197
    cv::subtract(frames1Rect[0], frames1Rect[1], occlusion1);
207
    occlusion1 = (occlusion1 > 25) & (occlusion1 < 250);
198
    occlusion1 = (occlusion1 > 25) & (occlusion1 < 250);
208
 
199
 
209
    // Threshold on energy at primary frequency
200
    // Threshold on energy at primary frequency
210
    occlusion0 = occlusion0 & (amplitude0 > 5.0*nStepsPrimary);
201
    occlusion0 = occlusion0 & (amplitude0 > 5.0*nStepsPrimary);
211
    occlusion1 = occlusion1 & (amplitude1 > 5.0*nStepsPrimary);
202
    occlusion1 = occlusion1 & (amplitude1 > 5.0*nStepsPrimary);
212
 
203
 
213
    // Threshold on energy ratios
204
    // Threshold on energy ratios
214
    occlusion0 = occlusion0 & (amplitude0 > 0.85*energy0Primary);
205
    occlusion0 = occlusion0 & (amplitude0 > 0.85*energy0Primary);
215
    occlusion0 = occlusion0 & (amplitude0 > 0.85*energy0Secondary);
206
    occlusion0 = occlusion0 & (amplitude0 > 0.85*energy0Secondary);
216
 
207
 
217
    occlusion1 = occlusion1 & (amplitude1 > 0.85*energy1Primary);
208
    occlusion1 = occlusion1 & (amplitude1 > 0.85*energy1Primary);
218
    occlusion1 = occlusion1 & (amplitude1 > 0.85*energy1Secondary);
209
    occlusion1 = occlusion1 & (amplitude1 > 0.85*energy1Secondary);
219
 
210
 
220
//    // Erode occlusion masks
211
//    // Erode occlusion masks
221
//    cv::Mat strel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5,5));
212
//    cv::Mat strel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5,5));
222
//    cv::erode(occlusion0, occlusion0, strel);
213
//    cv::erode(occlusion0, occlusion0, strel);
223
//    cv::erode(occlusion1, occlusion1, strel);
214
//    cv::erode(occlusion1, occlusion1, strel);
224
 
215
 
225
    // Threshold on gradient of phase
216
    // Threshold on gradient of phase
226
    cv::Mat edges0;
217
    cv::Mat edges0;
227
    cv::Sobel(up0, edges0, -1, 1, 1, 5);
218
    cv::Sobel(up0, edges0, -1, 1, 1, 5);
228
    occlusion0 = occlusion0 & (abs(edges0) < 150);
219
    occlusion0 = occlusion0 & (abs(edges0) < 150);
229
 
220
 
230
    cv::Mat edges1;
221
    cv::Mat edges1;
231
    cv::Sobel(up1, edges1, -1, 1, 1, 5);
222
    cv::Sobel(up1, edges1, -1, 1, 1, 5);
232
    occlusion1 = occlusion1 & (abs(edges1) < 150);
223
    occlusion1 = occlusion1 & (abs(edges1) < 150);
233
 
224
 
234
    #ifdef QT_DEBUG
225
    #ifdef QT_DEBUG
235
        cvtools::writeMat(occlusion0, "occlusion0.mat", "occlusion0");
226
        cvtools::writeMat(occlusion0, "occlusion0.mat", "occlusion0");
236
        cvtools::writeMat(occlusion1, "occlusion1.mat", "occlusion1");
227
        cvtools::writeMat(occlusion1, "occlusion1.mat", "occlusion1");
237
    #endif
228
    #endif
238
 
229
 
239
    // Match phase maps
230
    // Match phase maps
240
 
231
 
241
    // camera0 against camera1
232
    // camera0 against camera1
242
    std::vector<cv::Vec2f> q0, q1;
233
    std::vector<cv::Vec2f> q0, q1;
243
    for(int row=0; row<frameRectRows; row++){
234
    for(int row=0; row<frameRectRows; row++){
244
        for(int col=0; col<frameRectCols; col++){
235
        for(int col=0; col<frameRectCols; col++){
245
 
236
 
246
            if(!occlusion0.at<char>(row,col))
237
            if(!occlusion0.at<char>(row,col))
247
                continue;
238
                continue;
248
 
239
 
249
            float up0i = up0.at<float>(row,col);
240
            float up0i = up0.at<float>(row,col);
250
            for(int col1=0; col1<up1.cols-1; col1++){
241
            for(int col1=0; col1<up1.cols-1; col1++){
251
 
242
 
252
                if(!occlusion1.at<char>(row,col1) || !occlusion1.at<char>(row,col1+1))
243
                if(!occlusion1.at<char>(row,col1) || !occlusion1.at<char>(row,col1+1))
253
                    continue;
244
                    continue;
254
 
245
 
255
                float up1Left = up1.at<float>(row,col1);
246
                float up1Left = up1.at<float>(row,col1);
256
                float up1Right = up1.at<float>(row,col1+1);
247
                float up1Right = up1.at<float>(row,col1+1);
257
 
248
 
258
                if((up1Left <= up0i) && (up0i <= up1Right) && (up0i-up1Left < 1.0) && (up1Right-up0i < 1.0) && (up1Right-up1Left > 0.1)){
249
                if((up1Left <= up0i) && (up0i <= up1Right) && (up0i-up1Left < 1.0) && (up1Right-up0i < 1.0) && (up1Right-up1Left > 0.1)){
259
 
250
 
260
                    float col1i = col1 + (up0i-up1Left)/(up1Right-up1Left);
251
                    float col1i = col1 + (up0i-up1Left)/(up1Right-up1Left);
261
 
252
 
262
                    q0.push_back(cv::Point2f(col, row));
253
                    q0.push_back(cv::Point2f(col, row));
263
                    q1.push_back(cv::Point2f(col1i, row));
254
                    q1.push_back(cv::Point2f(col1i, row));
264
 
255
 
265
                    break;
256
                    break;
266
                }
257
                }
267
            }
258
            }
268
        }
259
        }
269
    }
260
    }
270
 
261
 
271
 
262
 
272
    int nMatches = q0.size();
263
    int nMatches = q0.size();
273
 
264
 
274
    if(nMatches < 1){
265
    if(nMatches < 1){
275
        Q.resize(0);
266
        Q.resize(0);
276
        color.resize(0);
267
        color.resize(0);
277
 
268
 
278
        return;
269
        return;
279
    }
270
    }
280
 
271
 
281
    // Retrieve color information
272
    // Retrieve color information
282
    color.resize(nMatches);
273
    color.resize(nMatches);
283
    for(int i=0; i<nMatches; i++){
274
    for(int i=0; i<nMatches; i++){
284
 
275
 
285
        cv::Vec3b c0 = color0.at<cv::Vec3b>(q0[i][1], q0[i][0]);
276
        cv::Vec3b c0 = color0.at<cv::Vec3b>(q0[i][1], q0[i][0]);
286
        cv::Vec3b c1 = color1.at<cv::Vec3b>(q1[i][1], q1[i][0]);
277
        cv::Vec3b c1 = color1.at<cv::Vec3b>(q1[i][1], q1[i][0]);
287
 
278
 
288
        color[i] = 0.5*c0 + 0.5*c1;
279
        color[i] = 0.5*c0 + 0.5*c1;
289
    }
280
    }
290
 
281
 
291
    // Triangulate points
282
    // Triangulate points
292
    cv::Mat QMatHomogenous, QMat;
283
    cv::Mat QMatHomogenous, QMat;
293
    cv::triangulatePoints(P0, P1, q0, q1, QMatHomogenous);
284
    cv::triangulatePoints(P0, P1, q0, q1, QMatHomogenous);
294
    cvtools::convertMatFromHomogeneous(QMatHomogenous, QMat);
285
    cvtools::convertMatFromHomogeneous(QMatHomogenous, QMat);
295
 
286
 
296
    // Undo rectification
287
    // Undo rectification
297
    cv::Mat R0Inv;
288
    cv::Mat R0Inv;
298
    cv::Mat(R0.t()).convertTo(R0Inv, CV_32F);
289
    cv::Mat(R0.t()).convertTo(R0Inv, CV_32F);
299
    QMat = R0Inv*QMat;
290
    QMat = R0Inv*QMat;
300
 
291
 
301
    cvtools::matToPoints3f(QMat, Q);
292
    cvtools::matToPoints3f(QMat, Q);
302
 
293
 
303
}
294
}
304
 
295