Subversion Repositories seema-scanner

Rev

Rev 27 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 27 Rev 36
1
#include "CodecPhaseShift.h"
1
#include "CodecPhaseShift.h"
2
#include <math.h>
2
#include <math.h>
3
 
3
 
4
#include "cvtools.h"
4
#include "cvtools.h"
5
 
5
 
6
#ifndef M_PI
6
#ifndef M_PI
7
    #define M_PI 3.14159265358979323846
7
    #define M_PI 3.14159265358979323846
8
#endif
8
#endif
9
 
9
 
10
static unsigned int nPhases = 8;
10
static unsigned int nPhases = 8;
11
 
11
 
12
// Encoder
12
// Encoder
13
static cv::Mat computePhaseVector(unsigned int length, float phase, float pitch){
13
static cv::Mat computePhaseVector(unsigned int length, float phase, float pitch){
14
 
14
 
15
    cv::Mat phaseVector(length, 1, CV_8UC3);
15
    cv::Mat phaseVector(length, 1, CV_8UC3);
16
    //phaseVector.setTo(0);
16
    //phaseVector.setTo(0);
17
 
17
 
18
    const float pi = M_PI;
18
    const float pi = M_PI;
19
 
19
 
20
    // Loop through vector
20
    // Loop through vector
21
    for(int i=0; i<phaseVector.rows; i++){
21
    for(int i=0; i<phaseVector.rows; i++){
22
        // Amplitude of channels
22
        // Amplitude of channels
23
        float amp = 0.5*(1+cos(2*pi*i/pitch + phase));
23
        float amp = 0.5*(1+cos(2*pi*i/pitch + phase));
24
        phaseVector.at<cv::Vec3b>(i, 0) = cv::Vec3b(255.0*amp,255.0*amp,255.0*amp);
24
        phaseVector.at<cv::Vec3b>(i, 0) = cv::Vec3b(255.0*amp,255.0*amp,255.0*amp);
25
    }
25
    }
26
 
26
 
27
    return phaseVector;
27
    return phaseVector;
28
}
28
}
29
 
29
 
30
EncoderPhaseShift::EncoderPhaseShift(unsigned int _screenCols, unsigned int _screenRows, CodecDir _dir) : Encoder(_screenCols, _screenRows, _dir){
30
EncoderPhaseShift::EncoderPhaseShift(unsigned int _screenCols, unsigned int _screenRows, CodecDir _dir) : Encoder(_screenCols, _screenRows, _dir){
31
 
31
 
32
    // Set N
32
    // Set N
33
    if(dir == CodecDirBoth)
33
    if(dir == CodecDirBoth)
34
        this->N = 12;
34
        this->N = 12;
35
    else
35
    else
36
        this->N = 6;
36
        this->N = 6;
37
 
37
 
38
    // Precompute encoded patterns
38
    // Precompute encoded patterns
39
    const float pi = M_PI;
39
    const float pi = M_PI;
40
 
40
 
41
    if(dir & CodecDirHorizontal){
41
    if(dir & CodecDirHorizontal){
42
        // Horizontally encoding patterns
42
        // Horizontally encoding patterns
43
        for(unsigned int i=0; i<3; i++){
43
        for(unsigned int i=0; i<3; i++){
44
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
44
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
45
            float pitch = (float)screenCols/(float)nPhases;
45
            float pitch = (float)screenCols/(float)nPhases;
46
            cv::Mat patternI(1,1,CV_8U);
46
            cv::Mat patternI(1,1,CV_8U);
47
            patternI = computePhaseVector(screenCols, phase, pitch);
47
            patternI = computePhaseVector(screenCols, phase, pitch);
48
            patternI = patternI.t();
48
            patternI = patternI.t();
49
            patterns.push_back(patternI);
49
            patterns.push_back(patternI);
50
        }
50
        }
51
 
51
 
52
        // Phase cue patterns
52
        // Phase cue patterns
53
        for(unsigned int i=0; i<3; i++){
53
        for(unsigned int i=0; i<3; i++){
54
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
54
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
55
            float pitch = screenCols;
55
            float pitch = screenCols;
56
            cv::Mat patternI;
56
            cv::Mat patternI;
57
            patternI = computePhaseVector(screenCols, phase, pitch);
57
            patternI = computePhaseVector(screenCols, phase, pitch);
58
            patternI = patternI.t();
58
            patternI = patternI.t();
59
            patterns.push_back(patternI);
59
            patterns.push_back(patternI);
60
        }
60
        }
61
    }
61
    }
62
    if(dir & CodecDirVertical){
62
    if(dir & CodecDirVertical){
63
        // Precompute vertically encoding patterns
63
        // Precompute vertically encoding patterns
64
        for(unsigned int i=0; i<3; i++){
64
        for(unsigned int i=0; i<3; i++){
65
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
65
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
66
            float pitch = (float)screenRows/(float)nPhases;
66
            float pitch = (float)screenRows/(float)nPhases;
67
            cv::Mat patternI;
67
            cv::Mat patternI;
68
            patternI = computePhaseVector(screenRows, phase, pitch);
68
            patternI = computePhaseVector(screenRows, phase, pitch);
69
            patterns.push_back(patternI);
69
            patterns.push_back(patternI);
70
        }
70
        }
71
 
71
 
72
        // Precompute vertically phase cue patterns
72
        // Precompute vertically phase cue patterns
73
        for(unsigned int i=0; i<3; i++){
73
        for(unsigned int i=0; i<3; i++){
74
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
74
            float phase = 2.0*pi/3.0 * (1.0 - (float)i);
75
            float pitch = screenRows;
75
            float pitch = screenRows;
76
            cv::Mat patternI;
76
            cv::Mat patternI;
77
            patternI = computePhaseVector(screenRows, phase, pitch);
77
            patternI = computePhaseVector(screenRows, phase, pitch);
78
            patterns.push_back(patternI);
78
            patterns.push_back(patternI);
79
        }
79
        }
80
    }
80
    }
81
}
81
}
82
 
82
 
83
cv::Mat EncoderPhaseShift::getEncodingPattern(unsigned int depth){
83
cv::Mat EncoderPhaseShift::getEncodingPattern(unsigned int depth){
84
    return patterns[depth];
84
    return patterns[depth];
85
}
85
}
86
 
86
 
87
// Decoder
87
// Decoder
88
DecoderPhaseShift::DecoderPhaseShift(CodecDir _dir) : Decoder(_dir){
88
DecoderPhaseShift::DecoderPhaseShift(CodecDir _dir, int _screenCols, int _screenRows) : Decoder(_dir, _screenRows, _screenCols){
89
 
89
 
90
}
90
}
91
 
91
 
92
static cv::Mat absolutePhase(cv::Mat _I1, cv::Mat _I2, cv::Mat _I3){
92
static cv::Mat absolutePhase(cv::Mat _I1, cv::Mat _I2, cv::Mat _I3){
93
 
93
 
94
    const float pi = M_PI;
94
    const float pi = M_PI;
95
 
95
 
96
    // Mat_ wrapper for easier indexing
96
    // Mat_ wrapper for easier indexing
97
    cv::Mat_<float> I1(_I1);
97
    cv::Mat_<float> I1(_I1);
98
    cv::Mat_<float> I2(_I2);
98
    cv::Mat_<float> I2(_I2);
99
    cv::Mat_<float> I3(_I3);
99
    cv::Mat_<float> I3(_I3);
100
 
100
 
101
    cv::Mat absPhase(I1.size(), CV_32F);
101
    cv::Mat absPhase(I1.size(), CV_32F);
102
 
102
 
103
    for(int i = 0; i < absPhase.rows; i++){
103
    for(int i = 0; i < absPhase.rows; i++){
104
        for(int j = 0; j < absPhase.cols; j++){
104
        for(int j = 0; j < absPhase.cols; j++){
105
            float phase = atan2(sqrt(3.0) * (I1(i,j)-I3(i,j)), I1(i,j) + I3(i,j) - 2.0*I2(i,j)) + pi;
105
            float phase = atan2(sqrt(3.0) * (I1(i,j)-I3(i,j)), I1(i,j) + I3(i,j) - 2.0*I2(i,j)) + pi;
106
            absPhase.at<float>(i,j) = phase;
106
            absPhase.at<float>(i,j) = phase;
107
        }
107
        }
108
    }
108
    }
109
 
109
 
110
    //absPhase.addref();
110
    //absPhase.addref();
111
    return absPhase;
111
    return absPhase;
112
}
112
}
113
 
113
 
114
void DecoderPhaseShift::decodeFrames(const std::vector<cv::Mat> frames, cv::Mat &up, cv::Mat &vp, cv::Mat &mask, cv::Mat &shading){
114
void DecoderPhaseShift::getCorrespondences(const std::vector<cv::Mat>& frames0, const std::vector<cv::Mat>& frames1, std::vector<cv::Point2f>& q0, std::vector<cv::Point2f>& q1, std::vector<cv::Point3f>& color){
115
 
115
 
116
    const float pi = M_PI;
-
 
117
 
-
 
118
    if(dir & CodecDirHorizontal){
-
 
119
        std::vector<cv::Mat> framesHorz(frames.begin(), frames.begin()+6);
-
 
120
 
-
 
121
        // Horizontal decoding
-
 
122
        up = absolutePhase(framesHorz[0], framesHorz[1], framesHorz[2]);
-
 
123
 
-
 
124
        cv::Mat upPhaseCue = absolutePhase(framesHorz[3], framesHorz[4], framesHorz[5]);
-
 
125
        upPhaseCue = (upPhaseCue*nPhases-up)/(2*pi);
-
 
126
        upPhaseCue.convertTo(upPhaseCue, CV_8U);
-
 
127
        upPhaseCue.convertTo(upPhaseCue, CV_32F);
-
 
128
 
-
 
129
        // unwrap absolute phase using phase cue
-
 
130
        up += upPhaseCue*2*pi;
-
 
131
 
-
 
132
    }
-
 
133
    if(dir & CodecDirVertical){
-
 
134
        std::vector<cv::Mat> framesVert(frames.end()-6, frames.end());
-
 
135
 
-
 
136
        // Vertical decoding
-
 
137
        vp = absolutePhase(framesVert[0], framesVert[1], framesVert[2]);
-
 
138
 
-
 
139
        cv::Mat vpPhaseCue = absolutePhase(framesVert[3], framesVert[4], framesVert[5]);
-
 
140
        vpPhaseCue = (vpPhaseCue*nPhases-vp)/(2*pi);
-
 
141
        vpPhaseCue.convertTo(vpPhaseCue, CV_8U);
-
 
142
        vpPhaseCue.convertTo(vpPhaseCue, CV_32F);
-
 
143
 
-
 
144
        // unwrap absolute phase using phase cue
-
 
145
        vp += vpPhaseCue*2*pi;
-
 
146
 
-
 
147
    }
-
 
148
 
-
 
149
    // Calculate modulation
-
 
150
    cv::Mat I1, I2, I3;
-
 
151
    frames[3].convertTo(I1, CV_32F);
-
 
152
    frames[4].convertTo(I2, CV_32F);
-
 
153
    frames[5].convertTo(I3, CV_32F);
-
 
154
    cv::Mat modulation;
-
 
155
    modulation = 3.0*(I1-I3).mul(I1-I3) + (2.0*I2-I1-I3).mul(2.0*I2-I1-I3);
-
 
156
    cv::sqrt(modulation, modulation);
-
 
157
    modulation.convertTo(shading, CV_8U);
-
 
158
    //shading = (1.0/3.0)*(framesHorz[3]+framesHorz[4]+framesHorz[5]);
-
 
159
 
-
 
160
    // Threshold modulation image for mask
-
 
161
    mask = shading > 50;
-
 
162
 
-
 
163
    cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(7,7));
-
 
164
    cv::erode(mask, mask, element);
-
 
165
}
116
}
166
 
117