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 = 20; // number of columns over which each line is shifted
|
11 |
static unsigned int nLineShifts = 8; // 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 85... |
Line 85... |
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));
|
88 |
int nTotalBits = ceilf(log2f((float)screenCols));
|
89 |
|
89 |
|
- |
|
90 |
// determine the necessary Gray code bits and add some robustness
|
90 |
nGrayBits = nTotalBits - floorf(log2f((float)nLineShifts));
|
91 |
nGrayBits = nTotalBits - floorf(log2f((float)nLineShifts)) + 2;
|
91 |
|
92 |
|
92 |
N = 2 + 2*nGrayBits + nLineShifts;
|
93 |
N = 2 + 2*nGrayBits + nLineShifts;
|
93 |
|
94 |
|
94 |
// all on pattern
|
95 |
// all on pattern
|
95 |
cv::Mat allOn(1, screenCols, CV_8UC3, cv::Scalar::all(255));
|
96 |
cv::Mat allOn(1, screenCols, CV_8UC3, cv::Scalar::all(255));
|
Line 161... |
Line 162... |
161 |
|
162 |
|
162 |
void getlineCenters(const cv::Mat& linesScanLine, const cv::Mat& codeScanLine, std::vector<cv::Vec2f>& lineCenters){
|
163 |
void getlineCenters(const cv::Mat& linesScanLine, const cv::Mat& codeScanLine, std::vector<cv::Vec2f>& lineCenters){
|
163 |
|
164 |
|
164 |
int nCols = linesScanLine.cols;
|
165 |
int nCols = linesScanLine.cols;
|
165 |
|
166 |
|
166 |
// fourth order derivative filtering
|
167 |
// finite derivative
|
167 |
cv::Mat der(1, nCols, CV_32F);
|
168 |
cv::Mat g(1, nCols, CV_32F);
|
- |
|
169 |
cv::Mat h(1, nCols, CV_32F);
|
168 |
for(int i=2; i<nCols-2; i++)
|
170 |
for(int i=2; i<nCols-2; i++){
|
169 |
der.at<float>(0, i) = linesScanLine.at<unsigned char>(0, i-2)+linesScanLine.at<unsigned char>(0, i-1)-
|
171 |
// g.at<float>(0, i) = linesScanLine.at<unsigned char>(0, i+2)+linesScanLine.at<unsigned char>(0, i+1)-
|
170 |
linesScanLine.at<unsigned char>(0, i+1)-linesScanLine.at<unsigned char>(0, i+2);
|
172 |
// linesScanLine.at<unsigned char>(0, i-1)-linesScanLine.at<unsigned char>(0, i-2);
|
- |
|
173 |
g.at<float>(0, i) = 1.0*linesScanLine.at<unsigned char>(0, i+2)+8.0*linesScanLine.at<unsigned char>(0, i+1)-
|
- |
|
174 |
8.0*linesScanLine.at<unsigned char>(0, i-1)-1.0*linesScanLine.at<unsigned char>(0, i-2);
|
- |
|
175 |
h.at<float>(0, i) = -1.0*linesScanLine.at<unsigned char>(0, i+2)+16.0*linesScanLine.at<unsigned char>(0, i+1)-
|
- |
|
176 |
30.0*linesScanLine.at<unsigned char>(0, i)+
|
- |
|
177 |
16.0*linesScanLine.at<unsigned char>(0, i-1)-1.0*linesScanLine.at<unsigned char>(0, i-2);
|
171 |
|
178 |
}
|
172 |
// cvtools::writeMat(codeScanLine, "codeScanLine.mat", "codeScanLine");
|
179 |
// cvtools::writeMat(codeScanLine, "codeScanLine.mat", "codeScanLine");
|
173 |
// cvtools::writeMat(linesScanLine, "linesScanLine.mat", "linesScanLine");
|
180 |
// cvtools::writeMat(linesScanLine, "linesScanLine.mat", "linesScanLine");
|
174 |
// cvtools::writeMat(der, "der.mat", "der");
|
181 |
// cvtools::writeMat(der, "der.mat", "der");
|
175 |
|
182 |
|
176 |
for(int i=0; i<nCols; i++){
|
183 |
for(int i=0; i<nCols-1; i++){
|
- |
|
184 |
// float fLeft = linesScanLine.at<unsigned char>(0, i-1);
|
177 |
int code = codeScanLine.at<int>(0, i);
|
185 |
float fI = linesScanLine.at<unsigned char>(0, i);
|
- |
|
186 |
// float fRight = linesScanLine.at<unsigned char>(0, i+1);
|
- |
|
187 |
|
- |
|
188 |
float gI = g.at<float>(0, i);
|
- |
|
189 |
float gRight = g.at<float>(0, i+1);
|
- |
|
190 |
|
- |
|
191 |
float hI = h.at<float>(0, i);
|
178 |
|
192 |
|
- |
|
193 |
int codeI = codeScanLine.at<int>(0, i);
|
179 |
if((code != -1) && (der.at<float>(0, i) < 0.0) && (der.at<float>(0, i+1) > 0.0) && ((der.at<float>(0, i+1) - der.at<float>(0, i)) > 20.0)){
|
194 |
//int codeRight = codeScanLine.at<int>(0, i+1);
|
180 |
|
195 |
|
- |
|
196 |
if((codeI != -1) && (fI > 1) && (gI >= 0.0) && (gRight <= 0.0) && (gRight < gI) && (hI < -2.0)){
|
181 |
lineCenters.push_back(cv::Vec2f(i, code));
|
197 |
float delta = gI/(gI - gRight);
|
182 |
// TODO: subpixel interpolation, non-max suppression
|
198 |
lineCenters.push_back(cv::Vec2f(i + delta, codeI));
|
183 |
}
|
199 |
}
|
184 |
|
200 |
|
185 |
}
|
201 |
}
|
186 |
|
202 |
|
187 |
}
|
203 |
}
|
Line 248... |
Line 264... |
248 |
// erode occlusion masks
|
264 |
// erode occlusion masks
|
249 |
cv::Mat strel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2,2));
|
265 |
cv::Mat strel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2,2));
|
250 |
cv::erode(occlusion0Rect, occlusion0Rect, strel);
|
266 |
cv::erode(occlusion0Rect, occlusion0Rect, strel);
|
251 |
cv::erode(occlusion1Rect, occlusion1Rect, strel);
|
267 |
cv::erode(occlusion1Rect, occlusion1Rect, strel);
|
252 |
|
268 |
|
253 |
// correct for texture modulation and ambient
|
269 |
// // correct for texture modulation and ambient
|
254 |
cv::Mat A0 = frames0Rect[1];
|
270 |
// cv::Mat A0 = frames0Rect[1];
|
255 |
cv::Mat M0 = frames0Rect[0]-frames0Rect[1];
|
271 |
// cv::Mat M0 = frames0Rect[0]-frames0Rect[1];
|
256 |
|
272 |
|
257 |
cv::divide(256.0, M0, M0, CV_32F);
|
273 |
// cv::divide(256.0, M0, M0, CV_32F);
|
258 |
cv::Mat A1 = frames1Rect[1];
|
274 |
// cv::Mat A1 = frames1Rect[1];
|
259 |
cv::Mat M1 = frames1Rect[0]-frames1Rect[1];
|
275 |
// cv::Mat M1 = frames1Rect[0]-frames1Rect[1];
|
260 |
cv::divide(256.0, M1, M1, CV_32F);
|
276 |
// cv::divide(256.0, M1, M1, CV_32F);
|
261 |
|
277 |
|
262 |
for(int i=2; i<N; i++){
|
278 |
// for(int i=2; i<N; i++){
|
263 |
cv::multiply(frames0Rect[i]-A0, M0, frames0Rect[i], 1.0, CV_8UC1);
|
279 |
// cv::multiply(frames0Rect[i]-A0, M0, frames0Rect[i], 1.0, CV_8UC1);
|
264 |
cv::multiply(frames1Rect[i]-A1, M1, frames1Rect[i], 1.0, CV_8UC1);
|
280 |
// cv::multiply(frames1Rect[i]-A1, M1, frames1Rect[i], 1.0, CV_8UC1);
|
265 |
}
|
281 |
// }
|
266 |
|
282 |
|
267 |
//cvtools::writeMat(frames0Rect[22], "frames0Rect_22.mat", "frames0Rect_22");
|
283 |
//cvtools::writeMat(frames0Rect[22], "frames0Rect_22.mat", "frames0Rect_22");
|
268 |
//cvtools::writeMat(frames0Rect[23], "frames0Rect_23.mat", "frames0Rect_23");
|
284 |
//cvtools::writeMat(frames0Rect[23], "frames0Rect_23.mat", "frames0Rect_23");
|
269 |
|
285 |
|
270 |
// divide into Gray coding frames and line shift frames
|
286 |
// divide into Gray coding frames and line shift frames
|
Line 329... |
Line 345... |
329 |
|
345 |
|
330 |
// sorted, unique line centers
|
346 |
// sorted, unique line centers
|
331 |
getlineCenters(lines0.row(row), code0Binary.row(row), lineCenters0);
|
347 |
getlineCenters(lines0.row(row), code0Binary.row(row), lineCenters0);
|
332 |
getlineCenters(lines1.row(row), code1Binary.row(row), lineCenters1);
|
348 |
getlineCenters(lines1.row(row), code1Binary.row(row), lineCenters1);
|
333 |
|
349 |
|
334 |
// if(s==0 && row==1300){
|
350 |
if(s==0 && row==1300){
|
335 |
// std::cout << cv::Mat(lineCenters0) << std::endl;
|
351 |
std::cout << cv::Mat(lineCenters0) << std::endl;
|
336 |
// std::cout << cv::Mat(lineCenters1) << std::endl;
|
352 |
std::cout << cv::Mat(lineCenters1) << std::endl;
|
337 |
|
353 |
|
338 |
// cvtools::writeMat(lines0.row(row), "lines0.mat", "lines0");
|
354 |
cvtools::writeMat(lines0.row(row), "lines0.mat", "lines0");
|
339 |
// cvtools::writeMat(lines1.row(row), "lines1.mat", "lines1");
|
355 |
cvtools::writeMat(lines1.row(row), "lines1.mat", "lines1");
|
340 |
// cvtools::writeMat(code0Binary.row(row), "code0Binary.mat", "code0Binary");
|
356 |
cvtools::writeMat(code0Binary.row(row), "code0Binary.mat", "code0Binary");
|
341 |
// cvtools::writeMat(code1Binary.row(row), "code1Binary.mat", "code1Binary");
|
357 |
cvtools::writeMat(code1Binary.row(row), "code1Binary.mat", "code1Binary");
|
342 |
// }
|
358 |
}
|
343 |
|
359 |
|
344 |
// match and store
|
360 |
// match and store
|
345 |
int i=0, j=0;
|
361 |
int i=0, j=0;
|
346 |
while(i<lineCenters0.size() && j<lineCenters1.size()){
|
362 |
while(i<lineCenters0.size() && j<lineCenters1.size()){
|
347 |
|
363 |
|