Line 37... |
Line 37... |
37 |
static bool getBit(int decimal, int N){
|
37 |
static bool getBit(int decimal, int N){
|
38 |
|
38 |
|
39 |
return decimal & 1 << (N-1);
|
39 |
return decimal & 1 << (N-1);
|
40 |
}
|
40 |
}
|
41 |
|
41 |
|
42 |
/*
|
42 |
///*
|
43 |
* Return the number of bits set in an integer
|
43 |
// * Return the number of bits set in an integer
|
44 |
*/
|
44 |
// */
|
45 |
static int countBits(int n) {
|
45 |
//static int countBits(int n) {
|
46 |
unsigned int c; // c accumulates the total bits set in v
|
46 |
// unsigned int c; // c accumulates the total bits set in v
|
47 |
for (c = 0; n>0; c++)
|
47 |
// for (c = 0; n>0; c++)
|
48 |
n &= n - 1; // clear the least significant bit set
|
48 |
// n &= n - 1; // clear the least significant bit set
|
49 |
return c;
|
49 |
// return c;
|
50 |
}
|
50 |
//}
|
51 |
|
51 |
|
52 |
/*
|
52 |
/*
|
53 |
* Return the position of the least significant bit that is set
|
53 |
* Return the position of the least significant bit that is set
|
54 |
*/
|
54 |
*/
|
55 |
static int leastSignificantBitSet(int x){
|
55 |
static int leastSignificantBitSet(int x){
|
Line 164... |
Line 164... |
164 |
std::vector<cv::Vec4i>::iterator it;
|
164 |
std::vector<cv::Vec4i>::iterator it;
|
165 |
it = std::unique(edges.begin(), edges.end(), sortingEqual);
|
165 |
it = std::unique(edges.begin(), edges.end(), sortingEqual);
|
166 |
edges.resize(std::distance(edges.begin(),it));
|
166 |
edges.resize(std::distance(edges.begin(),it));
|
167 |
}
|
167 |
}
|
168 |
|
168 |
|
169 |
static cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt){
|
169 |
//static cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt){
|
170 |
assert(!img.empty());
|
170 |
// assert(!img.empty());
|
171 |
assert(img.channels() == 3);
|
171 |
// assert(img.channels() == 3);
|
172 |
|
172 |
|
173 |
int x = (int)pt.x;
|
173 |
// int x = (int)pt.x;
|
174 |
int y = (int)pt.y;
|
174 |
// int y = (int)pt.y;
|
175 |
|
175 |
|
176 |
int x0 = cv::borderInterpolate(x, img.cols, cv::BORDER_REFLECT_101);
|
176 |
// int x0 = cv::borderInterpolate(x, img.cols, cv::BORDER_REFLECT_101);
|
177 |
int x1 = cv::borderInterpolate(x+1, img.cols, cv::BORDER_REFLECT_101);
|
177 |
// int x1 = cv::borderInterpolate(x+1, img.cols, cv::BORDER_REFLECT_101);
|
178 |
int y0 = cv::borderInterpolate(y, img.rows, cv::BORDER_REFLECT_101);
|
178 |
// int y0 = cv::borderInterpolate(y, img.rows, cv::BORDER_REFLECT_101);
|
179 |
int y1 = cv::borderInterpolate(y+1, img.rows, cv::BORDER_REFLECT_101);
|
179 |
// int y1 = cv::borderInterpolate(y+1, img.rows, cv::BORDER_REFLECT_101);
|
180 |
|
180 |
|
181 |
float a = pt.x - (float)x;
|
181 |
// float a = pt.x - (float)x;
|
182 |
float c = pt.y - (float)y;
|
182 |
// float c = pt.y - (float)y;
|
183 |
|
183 |
|
184 |
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)
|
184 |
// 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)
|
185 |
+ (img.at<cv::Vec3b>(y1, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[0] * a) * c);
|
185 |
// + (img.at<cv::Vec3b>(y1, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[0] * a) * c);
|
186 |
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)
|
186 |
// 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)
|
187 |
+ (img.at<cv::Vec3b>(y1, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[1] * a) * c);
|
187 |
// + (img.at<cv::Vec3b>(y1, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[1] * a) * c);
|
188 |
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)
|
188 |
// 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)
|
189 |
+ (img.at<cv::Vec3b>(y1, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[2] * a) * c);
|
189 |
// + (img.at<cv::Vec3b>(y1, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[2] * a) * c);
|
190 |
|
190 |
|
191 |
return cv::Vec3b(b, g, r);
|
191 |
// return cv::Vec3b(b, g, r);
|
192 |
}
|
192 |
//}
|
193 |
|
193 |
|
194 |
void AlgorithmGrayCode::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){
|
194 |
void AlgorithmGrayCode::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){
|
195 |
|
195 |
|
196 |
assert(frames0.size() == N);
|
196 |
assert(frames0.size() == N);
|
197 |
assert(frames1.size() == N);
|
197 |
assert(frames1.size() == N);
|
Line 223... |
Line 223... |
223 |
cv::initUndistortRectifyMap(calibration.K1, calibration.k1, R1, P1, frameSize, CV_32F, map1X, map1Y);
|
223 |
cv::initUndistortRectifyMap(calibration.K1, calibration.k1, R1, P1, frameSize, CV_32F, map1X, map1Y);
|
224 |
|
224 |
|
225 |
// gray-scale and remap
|
225 |
// gray-scale and remap
|
226 |
std::vector<cv::Mat> frames0Rect(N);
|
226 |
std::vector<cv::Mat> frames0Rect(N);
|
227 |
std::vector<cv::Mat> frames1Rect(N);
|
227 |
std::vector<cv::Mat> frames1Rect(N);
|
228 |
for(int i=0; i<N; i++){
|
228 |
for(unsigned int i=0; i<N; i++){
|
229 |
cv::Mat temp;
|
229 |
cv::Mat temp;
|
230 |
cv::cvtColor(frames0[i], temp, CV_BayerBG2GRAY);
|
230 |
cv::cvtColor(frames0[i], temp, CV_BayerBG2GRAY);
|
231 |
cv::remap(temp, frames0Rect[i], map0X, map0Y, CV_INTER_LINEAR);
|
231 |
cv::remap(temp, frames0Rect[i], map0X, map0Y, CV_INTER_LINEAR);
|
232 |
cv::cvtColor(frames1[i], temp, CV_BayerBG2GRAY);
|
232 |
cv::cvtColor(frames1[i], temp, CV_BayerBG2GRAY);
|
233 |
cv::remap(temp, frames1Rect[i], map1X, map1Y, CV_INTER_LINEAR);
|
233 |
cv::remap(temp, frames1Rect[i], map1X, map1Y, CV_INTER_LINEAR);
|
Line 320... |
Line 320... |
320 |
// decode patterns
|
320 |
// decode patterns
|
321 |
cv::Mat code0Rect(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
321 |
cv::Mat code0Rect(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
322 |
cv::Mat code1Rect(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
322 |
cv::Mat code1Rect(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
323 |
|
323 |
|
324 |
// into gray code
|
324 |
// into gray code
|
325 |
for(int i=0; i<Nbits; i++){
|
325 |
for(unsigned int i=0; i<Nbits; i++){
|
326 |
cv::Mat temp, bit0, bit1;
|
326 |
cv::Mat temp, bit0, bit1;
|
327 |
|
327 |
|
328 |
cv::compare(frames0Rect[i*2+2], frames0Rect[i*2+3], temp, cv::CMP_GT);
|
328 |
cv::compare(frames0Rect[i*2+2], frames0Rect[i*2+3], temp, cv::CMP_GT);
|
329 |
temp.convertTo(bit0, CV_32S, 1.0/255.0);
|
329 |
temp.convertTo(bit0, CV_32S, 1.0/255.0);
|
330 |
cv::add(code0Rect, bit0*twopowi(Nbits-i-1), code0Rect, cv::noArray(), CV_32S);
|
330 |
cv::add(code0Rect, bit0*twopowi(Nbits-i-1), code0Rect, cv::noArray(), CV_32S);
|
Line 389... |
Line 389... |
389 |
getEdgeLabels(code0Rect.row(row), Nbits, edges0);
|
389 |
getEdgeLabels(code0Rect.row(row), Nbits, edges0);
|
390 |
getEdgeLabels(code1Rect.row(row), Nbits, edges1);
|
390 |
getEdgeLabels(code1Rect.row(row), Nbits, edges1);
|
391 |
|
391 |
|
392 |
// match edges
|
392 |
// match edges
|
393 |
std::vector<cv::Vec4i> matchedEdges0, matchedEdges1;
|
393 |
std::vector<cv::Vec4i> matchedEdges0, matchedEdges1;
|
394 |
int i=0, j=0;
|
394 |
unsigned int i=0, j=0;
|
395 |
while(i<edges0.size() && j<edges1.size()){
|
395 |
while(i<edges0.size() && j<edges1.size()){
|
396 |
|
396 |
|
397 |
if(edges0[i][3] == edges1[j][3]){
|
397 |
if(edges0[i][3] == edges1[j][3]){
|
398 |
matchedEdges0.push_back(edges0[i]);
|
398 |
matchedEdges0.push_back(edges0[i]);
|
399 |
matchedEdges1.push_back(edges1[j]);
|
399 |
matchedEdges1.push_back(edges1[j]);
|
Line 406... |
Line 406... |
406 |
}
|
406 |
}
|
407 |
}
|
407 |
}
|
408 |
|
408 |
|
409 |
// crude subpixel refinement
|
409 |
// crude subpixel refinement
|
410 |
// finds the intersection of linear interpolants in the positive/negative pattern
|
410 |
// finds the intersection of linear interpolants in the positive/negative pattern
|
411 |
for(int i=0; i<matchedEdges0.size(); i++){
|
411 |
for(unsigned int i=0; i<matchedEdges0.size(); i++){
|
412 |
|
412 |
|
413 |
int level = Nbits - leastSignificantBitSet(matchedEdges0[i][1]^matchedEdges0[i][2]);
|
413 |
int level = Nbits - leastSignificantBitSet(matchedEdges0[i][1]^matchedEdges0[i][2]);
|
414 |
|
414 |
|
415 |
// refine for camera 0
|
415 |
// refine for camera 0
|
416 |
float c0 = matchedEdges0[i][0];
|
416 |
float c0 = matchedEdges0[i][0];
|