Line 6... |
Line 6... |
6 |
|
6 |
|
7 |
#ifndef log2f
|
7 |
#ifndef log2f
|
8 |
#define log2f(x) (log(x)/log(2.0))
|
8 |
#define log2f(x) (log(x)/log(2.0))
|
9 |
#endif
|
9 |
#endif
|
10 |
|
10 |
|
11 |
static unsigned int nLineShifts = 8; // number of columns over which each line is shifted
|
11 |
static unsigned int nLineShifts = 20; // number of columns over which each line is shifted
|
12 |
|
12 |
|
13 |
/*
|
13 |
/*
|
14 |
* The purpose of this function is to convert an unsigned
|
14 |
* The purpose of this function is to convert an unsigned
|
15 |
* binary number to reflected binary Gray code.
|
15 |
* binary number to reflected binary Gray code.
|
16 |
*
|
16 |
*
|
Line 83... |
Line 83... |
83 |
}
|
83 |
}
|
84 |
|
84 |
|
85 |
// Algorithm
|
85 |
// Algorithm
|
86 |
AlgorithmLineShift::AlgorithmLineShift(unsigned int _screenCols, unsigned int _screenRows) : Algorithm(_screenCols, _screenRows){
|
86 |
AlgorithmLineShift::AlgorithmLineShift(unsigned int _screenCols, unsigned int _screenRows) : Algorithm(_screenCols, _screenRows){
|
87 |
|
87 |
|
- |
|
88 |
int nTotalBits = ceilf(log2f((float)screenCols));
|
- |
|
89 |
|
88 |
nGrayBits = ceilf(log2f((float)screenCols)) - floorf(log2f((float)nLineShifts));
|
90 |
nGrayBits = nTotalBits - floorf(log2f((float)nLineShifts));
|
89 |
|
91 |
|
90 |
N = 2 + 2*nGrayBits + nLineShifts;
|
92 |
N = 2 + 2*nGrayBits + nLineShifts;
|
91 |
|
93 |
|
92 |
// all on pattern
|
94 |
// all on pattern
|
93 |
cv::Mat allOn(1, screenCols, CV_8UC3, cv::Scalar::all(255));
|
95 |
cv::Mat allOn(1, screenCols, CV_8UC3, cv::Scalar::all(255));
|
Line 105... |
Line 107... |
105 |
|
107 |
|
106 |
for(unsigned int j=0; j<screenCols; j++){
|
108 |
for(unsigned int j=0; j<screenCols; j++){
|
107 |
|
109 |
|
108 |
unsigned int jGray = binaryToGray(j);
|
110 |
unsigned int jGray = binaryToGray(j);
|
109 |
// Amplitude of channels
|
111 |
// Amplitude of channels
|
110 |
int bit = (int)getBit(jGray, nGrayBits-p);
|
112 |
int bit = (int)getBit(jGray, nTotalBits-p);
|
111 |
pattern.at<cv::Vec3b>(0,j) = cv::Vec3b(255.0*bit,255.0*bit,255.0*bit);
|
113 |
pattern.at<cv::Vec3b>(0,j) = cv::Vec3b(255.0*bit,255.0*bit,255.0*bit);
|
112 |
int invBit = bit^1;
|
114 |
int invBit = bit^1;
|
113 |
patternInv.at<cv::Vec3b>(0,j) = cv::Vec3b(255.0*invBit,255.0*invBit,255.0*invBit);
|
115 |
patternInv.at<cv::Vec3b>(0,j) = cv::Vec3b(255.0*invBit,255.0*invBit,255.0*invBit);
|
114 |
}
|
116 |
}
|
115 |
patterns.push_back(pattern);
|
117 |
patterns.push_back(pattern);
|
Line 160... |
Line 162... |
160 |
void getlineCenters(const cv::Mat& linesScanLine, const cv::Mat& codeScanLine, std::vector<cv::Vec2f>& lineCenters){
|
162 |
void getlineCenters(const cv::Mat& linesScanLine, const cv::Mat& codeScanLine, std::vector<cv::Vec2f>& lineCenters){
|
161 |
|
163 |
|
162 |
int nCols = linesScanLine.cols;
|
164 |
int nCols = linesScanLine.cols;
|
163 |
|
165 |
|
164 |
// fourth order derivative filtering
|
166 |
// fourth order derivative filtering
|
165 |
cv::Mat der(1, nCols, CV_8U);
|
167 |
cv::Mat der(1, nCols, CV_32F);
|
166 |
for(int i=2; i<nCols-2; i++)
|
168 |
for(int i=2; i<nCols-2; i++)
|
167 |
der.at<unsigned char>(0, i) = linesScanLine.at<unsigned char>(0, i-2)+linesScanLine.at<unsigned char>(0, i-1)-
|
169 |
der.at<float>(0, i) = linesScanLine.at<unsigned char>(0, i-2)+linesScanLine.at<unsigned char>(0, i-1)-
|
168 |
linesScanLine.at<unsigned char>(0, i+1)-linesScanLine.at<unsigned char>(0, i+2);
|
170 |
linesScanLine.at<unsigned char>(0, i+1)-linesScanLine.at<unsigned char>(0, i+2);
|
- |
|
171 |
|
- |
|
172 |
// cvtools::writeMat(codeScanLine, "codeScanLine.mat", "codeScanLine");
|
- |
|
173 |
// cvtools::writeMat(linesScanLine, "linesScanLine.mat", "linesScanLine");
|
- |
|
174 |
// cvtools::writeMat(der, "der.mat", "der");
|
169 |
|
175 |
|
170 |
for(int i=0; i<nCols; i++){
|
176 |
for(int i=0; i<nCols; i++){
|
171 |
|
177 |
|
172 |
if(der.at<unsigned char>(0, i) > 0 && der.at<unsigned char>(0, i+1) < 0){
|
178 |
if(der.at<float>(0, i) < 0.0 && der.at<unsigned char>(0, i+1) > 0.0){
|
173 |
|
179 |
|
174 |
lineCenters.push_back(cv::Vec2f(i, codeScanLine.at<unsigned char>(0, i)));
|
180 |
lineCenters.push_back(cv::Vec2f(i, codeScanLine.at<unsigned char>(0, i)));
|
175 |
// TODO: subpixel interpolation, non-max suppression
|
181 |
// TODO: subpixel interpolation, non-max suppression
|
176 |
}
|
182 |
}
|
177 |
|
183 |
|
Line 233... |
Line 239... |
233 |
cv::subtract(frames0Rect[0], frames0Rect[1], occlusion0Rect);
|
239 |
cv::subtract(frames0Rect[0], frames0Rect[1], occlusion0Rect);
|
234 |
occlusion0Rect = (occlusion0Rect > 20) & (occlusion0Rect < 250);
|
240 |
occlusion0Rect = (occlusion0Rect > 20) & (occlusion0Rect < 250);
|
235 |
cv::subtract(frames1Rect[0], frames1Rect[1], occlusion1Rect);
|
241 |
cv::subtract(frames1Rect[0], frames1Rect[1], occlusion1Rect);
|
236 |
occlusion1Rect = (occlusion1Rect > 20) & (occlusion1Rect < 250);
|
242 |
occlusion1Rect = (occlusion1Rect > 20) & (occlusion1Rect < 250);
|
237 |
|
243 |
|
238 |
//cvtools::writeMat(occlusion0Rect, "occlusion0Rect.mat", "occlusion0Rect");
|
244 |
// cvtools::writeMat(occlusion0Rect, "occlusion0Rect.mat", "occlusion0Rect");
|
239 |
//cvtools::writeMat(occlusion1Rect, "occlusion1Rect.mat", "occlusion1Rect");
|
245 |
// cvtools::writeMat(occlusion1Rect, "occlusion1Rect.mat", "occlusion1Rect");
|
240 |
|
246 |
|
241 |
// erode occlusion masks
|
247 |
// erode occlusion masks
|
242 |
cv::Mat strel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2,2));
|
248 |
cv::Mat strel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2,2));
|
243 |
cv::erode(occlusion0Rect, occlusion0Rect, strel);
|
249 |
cv::erode(occlusion0Rect, occlusion0Rect, strel);
|
244 |
cv::erode(occlusion1Rect, occlusion1Rect, strel);
|
250 |
cv::erode(occlusion1Rect, occlusion1Rect, strel);
|
Line 259... |
Line 265... |
259 |
|
265 |
|
260 |
//cvtools::writeMat(frames0Rect[22], "frames0Rect_22.mat", "frames0Rect_22");
|
266 |
//cvtools::writeMat(frames0Rect[22], "frames0Rect_22.mat", "frames0Rect_22");
|
261 |
//cvtools::writeMat(frames0Rect[23], "frames0Rect_23.mat", "frames0Rect_23");
|
267 |
//cvtools::writeMat(frames0Rect[23], "frames0Rect_23.mat", "frames0Rect_23");
|
262 |
|
268 |
|
263 |
// divide into Gray coding frames and line shift frames
|
269 |
// divide into Gray coding frames and line shift frames
|
264 |
std::vector<cv::Mat> frames0GrayCode(frames0Rect.begin()+2, frames0Rect.begin()+2+nGrayBits);
|
270 |
std::vector<cv::Mat> frames0GrayCode(frames0Rect.begin()+2, frames0Rect.begin()+2+2*nGrayBits);
|
265 |
std::vector<cv::Mat> frames0LineShift(frames0Rect.begin()+2+nGrayBits, frames0Rect.end());
|
271 |
std::vector<cv::Mat> frames0LineShift(frames0Rect.begin()+2+2*nGrayBits, frames0Rect.end());
|
266 |
std::vector<cv::Mat> frames1GrayCode(frames1Rect.begin()+2, frames1Rect.begin()+2+nGrayBits);
|
272 |
std::vector<cv::Mat> frames1GrayCode(frames1Rect.begin()+2, frames1Rect.begin()+2+2*nGrayBits);
|
267 |
std::vector<cv::Mat> frames1LineShift(frames1Rect.begin()+2+nGrayBits, frames1Rect.end());
|
273 |
std::vector<cv::Mat> frames1LineShift(frames1Rect.begin()+2+2*nGrayBits, frames1Rect.end());
|
268 |
|
274 |
|
269 |
// decode patterns
|
275 |
// decode patterns
|
270 |
cv::Mat code0Gray(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
276 |
cv::Mat code0Gray(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
271 |
cv::Mat code1Gray(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
277 |
cv::Mat code1Gray(frameRectRows, frameRectCols, CV_32S, cv::Scalar(0));
|
272 |
|
278 |
|
Line 281... |
Line 287... |
281 |
cv::compare(frames1GrayCode[i*2], frames1GrayCode[i*2+1], temp, cv::CMP_GT);
|
287 |
cv::compare(frames1GrayCode[i*2], frames1GrayCode[i*2+1], temp, cv::CMP_GT);
|
282 |
temp.convertTo(bit1, CV_32S, 1.0/255.0);
|
288 |
temp.convertTo(bit1, CV_32S, 1.0/255.0);
|
283 |
cv::add(code1Gray, bit1*twopowi(nGrayBits-i-1), code1Gray, cv::noArray(), CV_32S);
|
289 |
cv::add(code1Gray, bit1*twopowi(nGrayBits-i-1), code1Gray, cv::noArray(), CV_32S);
|
284 |
}
|
290 |
}
|
285 |
|
291 |
|
286 |
// set occluded pixels to -1
|
292 |
// convert to standard binary
|
- |
|
293 |
cv::Mat code0Binary(code0Gray.rows, code0Gray.cols, CV_32S, cv::Scalar(-1));
|
- |
|
294 |
cv::Mat code1Binary(code1Gray.rows, code1Gray.cols, CV_32S, cv::Scalar(-1));
|
287 |
for(int r=0; r<frameRectRows; r++){
|
295 |
for(int r=0; r<frameRectRows; r++){
|
288 |
for(int c=0; c<frameRectCols; c++){
|
296 |
for(int c=0; c<frameRectCols; c++){
|
289 |
if(occlusion0Rect.at<unsigned char>(r,c) == 0)
|
- |
|
290 |
code0Gray.at<int>(r,c) = -1;
|
297 |
code0Binary.at<int>(r,c) = grayToBinary(code0Gray.at<int>(r,c));
|
291 |
if(occlusion1Rect.at<unsigned char>(r,c) == 0)
|
- |
|
292 |
code1Gray.at<int>(r,c) = -1;
|
298 |
code1Binary.at<int>(r,c) = grayToBinary(code1Gray.at<int>(r,c));
|
293 |
}
|
299 |
}
|
294 |
}
|
300 |
}
|
295 |
|
301 |
|
296 |
// convert to standard binary
|
302 |
// set occluded pixels to -1
|
297 |
cv::Mat code0Binary(code0Gray.rows, code0Gray.cols, CV_32F);
|
- |
|
298 |
cv::Mat code1Binary(code1Gray.rows, code1Gray.cols, CV_32F);
|
- |
|
299 |
for(int r=0; r<frameRectRows; r++){
|
303 |
for(int r=0; r<frameRectRows; r++){
|
300 |
for(int c=0; c<frameRectCols; c++){
|
304 |
for(int c=0; c<frameRectCols; c++){
|
301 |
if(code0Gray.at<int>(r,c) != -1)
|
305 |
if(occlusion0Rect.at<unsigned char>(r,c) == 0)
|
302 |
code0Binary.at<float>(r,c) = grayToBinary(code0Gray.at<int>(r,c));
|
306 |
code0Binary.at<int>(r,c) = -1;
|
303 |
if(code1Gray.at<int>(r,c) != -1)
|
307 |
if(occlusion1Rect.at<unsigned char>(r,c) == 0)
|
304 |
code1Binary.at<float>(r,c) = grayToBinary(code1Gray.at<int>(r,c));
|
308 |
code1Binary.at<int>(r,c) = -1;
|
305 |
}
|
309 |
}
|
306 |
}
|
310 |
}
|
307 |
|
311 |
|
308 |
//cvtools::writeMat(code0Gray, "code0Gray.mat", "code0Gray");
|
312 |
cvtools::writeMat(code0Gray, "code0Gray.mat", "code0Gray");
|
309 |
//cvtools::writeMat(code1Gray, "code1Gray.mat", "code1Gray");
|
313 |
cvtools::writeMat(code1Gray, "code1Gray.mat", "code1Gray");
|
- |
|
314 |
cvtools::writeMat(code0Binary, "code0Binary.mat", "code0Binary");
|
- |
|
315 |
cvtools::writeMat(code1Binary, "code1Binary.mat", "code1Binary");
|
310 |
|
316 |
|
311 |
// TODO: iterate through all line frames
|
317 |
// TODO: iterate through all line frames
|
312 |
cv::Mat lines0 = frames0LineShift[0];
|
318 |
cv::Mat lines0 = frames0LineShift[0];
|
313 |
cv::Mat lines1 = frames1LineShift[0];
|
319 |
cv::Mat lines1 = frames1LineShift[0];
|
314 |
|
320 |
|