Subversion Repositories seema-scanner

Rev

Rev 187 | Rev 245 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
184 jakw 1
#ifndef ALGORITHMTOOLS_H
2
#define ALGORITHMTOOLS_H
3
 
4
#include <opencv2/opencv.hpp>
5
 
6
// Convert an unsigned binary number to reflected binary Gray code.
7
// Source: http://en.wikipedia.org/wiki/Gray_code
8
inline unsigned int binaryToGray(unsigned int num) {
9
    return (num >> 1) ^ num;
10
}
11
 
12
// Convert a reflected binary Gray code number to a binary number.
13
// Source: http://en.wikipedia.org/wiki/Gray_code
14
inline unsigned int grayToBinary(unsigned int num){
15
    unsigned int mask;
16
    for(mask = num >> 1; mask != 0; mask = mask >> 1)
17
        num = num ^ mask;
18
    return num;
19
}
20
 
21
// Return the Nth bit of an unsigned integer number
22
inline bool getBit(int decimal, int N){
23
 
24
    return decimal & 1 << (N-1);
25
}
26
 
27
// Return the position of the least significant bit that is set
28
inline int leastSignificantBitSet(int x){
29
  if(x == 0)
30
      return 0;
31
 
32
  int val = 1;
33
  while(x>>=1)
34
      val++;
35
 
36
  return val;
37
}
38
 
39
// Compute the power of a number (where the exponent is an integer)
40
inline unsigned int powi(int num, unsigned int exponent){
41
 
42
    if(exponent == 0)
43
        return 1;
44
 
45
    float res = num;
46
    for(unsigned int i=0; i<exponent-1; i++)
47
        res *= num;
48
 
49
    return res;
50
}
51
 
52
// Compute the power of a 2 (where the exponent is an integer)
53
inline unsigned int twopowi(unsigned int exponent){
54
    return 1 << exponent;
55
}
56
 
57
inline cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt){
58
    assert(!img.empty());
59
    assert(img.channels() == 3);
60
 
61
    int x = (int)pt.x;
62
    int y = (int)pt.y;
63
 
64
    int x0 = cv::borderInterpolate(x,   img.cols, cv::BORDER_REFLECT_101);
65
    int x1 = cv::borderInterpolate(x+1, img.cols, cv::BORDER_REFLECT_101);
66
    int y0 = cv::borderInterpolate(y,   img.rows, cv::BORDER_REFLECT_101);
67
    int y1 = cv::borderInterpolate(y+1, img.rows, cv::BORDER_REFLECT_101);
68
 
69
    float a = pt.x - (float)x;
70
    float c = pt.y - (float)y;
71
 
72
    uchar b = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[0] * a) * (1.f - c)
73
                           + (img.at<cv::Vec3b>(y1, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[0] * a) * c);
74
    uchar g = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[1] * a) * (1.f - c)
75
                           + (img.at<cv::Vec3b>(y1, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[1] * a) * c);
76
    uchar r = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[2] * a) * (1.f - c)
77
                           + (img.at<cv::Vec3b>(y1, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[2] * a) * c);
78
 
79
    return cv::Vec3b(b, g, r);
80
}
81
 
82
inline cv::Mat computePhaseVector(unsigned int length, float phase, float pitch){
83
 
84
    cv::Mat phaseVector(length, 1, CV_8UC3);
85
    //phaseVector.setTo(0);
86
 
87
    const float pi = M_PI;
88
 
89
    // Loop through vector
90
    for(int i=0; i<phaseVector.rows; i++){
91
        // Amplitude of channels
92
        float amp = 0.5*(1+cos(2*pi*i/pitch - phase));
93
        phaseVector.at<cv::Vec3b>(i, 0) = cv::Vec3b(255.0*amp,255.0*amp,255.0*amp);
94
    }
95
 
96
    return phaseVector;
97
}
98
 
99
inline cv::Mat getPhase(const cv::Mat I1, const cv::Mat I2, const cv::Mat I3){
100
 
101
    cv::Mat_<float> I1_(I1);
102
    cv::Mat_<float> I2_(I2);
103
    cv::Mat_<float> I3_(I3);
104
 
105
    cv::Mat phase;
106
 
107
    // One call approach
108
    cv::phase(2.0*I1_-I3_-I2_, sqrt(3.0)*(I2_-I3_), phase);
109
    return phase;
110
 
111
}
112
 
113
// Phase unwrapping by means of a phase cue
207 flgw 114
inline cv::Mat unwrapWithCue(const cv::Mat &up, const cv::Mat &upCue, float nPhases){
184 jakw 115
 
116
    const float pi = M_PI;
117
 
187 jakw 118
    // Determine fringe order
184 jakw 119
    cv::Mat P = (upCue*nPhases-up)/(2.0*pi);
120
 
121
    // Round to integers
122
    P.convertTo(P, CV_8U);
123
    P.convertTo(P, CV_32F);
124
 
125
    // Add to phase
126
    cv::Mat upUnwrapped = up + P*2*pi;
127
 
128
    // Scale to range [0; 2pi]
129
    upUnwrapped *= 1.0/nPhases;
130
 
131
    return upUnwrapped;
132
}
133
 
134
// Absolute phase and magnitude from N frames
207 flgw 135
inline std::vector<cv::Mat> getDFTComponents(const std::vector<cv::Mat> &frames){
184 jakw 136
 
137
    unsigned int N = frames.size();
138
 
139
//    std::vector<cv::Mat> framesReverse = frames;
140
//    std::reverse(framesReverse.begin(), framesReverse.end());
141
 
142
    // DFT approach
143
    cv::Mat I;
144
    cv::merge(frames, I);
145
    unsigned int w = I.cols;
146
    unsigned int h = I.rows;
147
    I = I.reshape(1, h*w);
148
    I.convertTo(I, CV_32F);
149
    cv::Mat fI;
150
    cv::dft(I, fI, cv::DFT_ROWS + cv::DFT_COMPLEX_OUTPUT);
151
    fI = fI.reshape(N*2, h);
152
 
153
    std::vector<cv::Mat> fIcomp;
154
    cv::split(fI, fIcomp);
155
 
156
    return fIcomp;
157
 
158
}
159
 
160
#endif // ALGORITHMTOOLS_H