Subversion Repositories seema-scanner

Rev

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

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