Subversion Repositories seema-scanner

Rev

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

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