Subversion Repositories seema-scanner

Rev

Rev 107 | Rev 109 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 107 Rev 108
Line 153... Line 153...
153
 
153
 
154
 
154
 
155
typedef struct intersection{
155
typedef struct intersection{
156
    unsigned int row;
156
    unsigned int row;
157
    unsigned int col;
157
    unsigned int col;
158
    unsigned int labelLeft;
-
 
159
    unsigned int labelRight;
-
 
160
    unsigned int labelAbove;
-
 
161
    unsigned int labelBelow;
-
 
162
    unsigned long id;
158
    unsigned long id;
163
    intersection() : row(0), col(0), labelLeft(0), labelRight(0), labelAbove(0), labelBelow(0), id(0){}
159
    intersection() : row(0), col(0), id(0){}
164
    intersection(unsigned int _row, unsigned int _col, unsigned int _labelLeft, unsigned int _labelRight, unsigned int _labelAbove, unsigned int _labelBelow, unsigned long long _id) :
160
    intersection(unsigned int _row, unsigned int _col, unsigned long long _id) :
165
        row(_row), col(_col), labelLeft(_labelLeft), labelRight(_labelRight), labelAbove(_labelAbove), labelBelow(_labelBelow), id(_id){}
161
        row(_row), col(_col), id(_id){}
166
} intersection;
162
} intersection;
167
 
163
 
168
 
164
 
169
static bool sortingLarger(intersection i,intersection j){ return (i.id<j.id);}
165
static bool sortingLarger(intersection i,intersection j){ return (i.id<j.id);}
170
static bool sortingEqual(intersection i,intersection j){ return (i.id==j.id);}
166
static bool sortingEqual(intersection i,intersection j){ return (i.id==j.id);}
171
 
167
 
172
static void getIntersectionLabels(const cv::Mat& codeHorz, const cv::Mat& codeVert, int NbitsHorz, int NbitsVert, std::vector<intersection>& intersections){
168
static void getIntersectionLabels(const cv::Mat& codeHorz, const cv::Mat& codeVert, const int NbitsHorz, const int NbitsVert, std::vector<intersection>& intersections){
173
 
169
 
174
    int nRows = codeHorz.rows;
170
    int nRows = codeHorz.rows;
175
    int nCols = codeHorz.cols;
171
    int nCols = codeHorz.cols;
176
 
172
 
177
    int labelHorz;
173
    int labelHorz;
Line 193... Line 189...
193
            if(labelHorz != -1 && labelHorzRight != -1 &&
189
            if(labelHorz != -1 && labelHorzRight != -1 &&
194
               countBits(labelHorz^labelHorzRight) == 1 &&
190
               countBits(labelHorz^labelHorzRight) == 1 &&
195
               labelVert != -1 && labelVertBelow != -1 &&
191
               labelVert != -1 && labelVertBelow != -1 &&
196
               countBits(labelVert^labelVertBelow) == 1){
192
               countBits(labelVert^labelVertBelow) == 1){
197
 
193
 
198
                // OVERFLOW??
194
                // shift together labels to form unique intersection id
199
                unsigned long id = ((ulong)labelHorz << NbitsHorz+2*NbitsVert) + ((ulong)labelHorzRight << 2*NbitsVert) +
195
                unsigned long id = (labelHorz << NbitsHorz+2*NbitsVert) + (labelHorzRight << 2*NbitsVert) +
200
                                          ((ulong)labelVert << NbitsVert) + (ulong)labelVertBelow;
196
                                   (labelVert << NbitsVert) + labelVertBelow;
-
 
197
 
201
                // store left label column
198
                // store intersection
202
                intersections.push_back(intersection(row, col, labelHorz, labelHorzRight, labelVert, labelVertBelow, id));
199
                intersections.push_back(intersection(row, col, id));
203
            }
200
            }
204
        }
201
        }
205
    }
202
    }
206
    // sort
203
    // sort
207
    std::sort(intersections.begin(), intersections.end(), sortingLarger);
204
    std::sort(intersections.begin(), intersections.end(), sortingLarger);
Line 210... Line 207...
210
    std::vector<intersection>::iterator it;
207
    std::vector<intersection>::iterator it;
211
    it = std::unique(intersections.begin(), intersections.end(), sortingEqual);
208
    it = std::unique(intersections.begin(), intersections.end(), sortingEqual);
212
    intersections.resize(std::distance(intersections.begin(),it));
209
    intersections.resize(std::distance(intersections.begin(),it));
213
}
210
}
214
 
211
 
-
 
212
static void getSubpixelCoordinates(const std::vector<intersection>& matches, const std::vector<cv::Mat>& frames, const int NbitsHorz, const int NbitsVert, std::vector<cv::Point2f> &q){
-
 
213
 
-
 
214
    int nMatches = matches.size();
-
 
215
    q.resize(nMatches);
-
 
216
 
-
 
217
    // subpixel refinement finds the intersection of linear interpolants in the positive/negative pattern
-
 
218
    for(int i=0; i<nMatches; i++){
-
 
219
 
-
 
220
        // shift the labels back out from id
-
 
221
        int labelHorz = (matches[i].id >> NbitsHorz+2*NbitsVert) & (1 << (NbitsHorz+1) - 1);
-
 
222
        int labelHorzRight = (matches[i].id >> 2*NbitsVert) & (1 << (NbitsHorz+1) - 1);
-
 
223
        int labelVert = (matches[i].id >> NbitsVert) & (1 << (NbitsVert+1) - 1);
-
 
224
        int labelVertBelow = matches[i].id  & (1 << (NbitsVert+1) - 1);
-
 
225
 
-
 
226
        // determine the levels at which the edges exists
-
 
227
        int levelHorz = NbitsHorz - leastSignificantBitSet(labelHorz^labelHorzRight);
-
 
228
        int levelVert = NbitsVert - leastSignificantBitSet(labelVert^labelVertBelow);
-
 
229
 
-
 
230
        // interpolate horizontal coordinate
-
 
231
        float row = matches[i].row;
-
 
232
        float col = matches[i].col;
-
 
233
        float colRight = col+1;
-
 
234
 
-
 
235
        float posHorz = frames0[2*levelHorz+2].at<char>(row, col);
-
 
236
        float negHorz = frames0[2*levelHorz+3].at<char>(row, col);
-
 
237
        float posHorzRight = frames0[2*levelHorz+2].at<char>(row, colRight);
-
 
238
        float negHorzRight = frames0[2*levelHorz+3].at<char>(row, colRight);
-
 
239
 
-
 
240
        float x = col + (posHorz - negHorz)/(negHorzRight - negHorz - posHorzRight + posHorz);
-
 
241
 
-
 
242
        // interpolate vertical coordinate
-
 
243
        float rowBelow = row+1;
-
 
244
 
-
 
245
        float posVert = frames[2*NbitsHorz+2*levelVert+2].at<char>(rowBelow, col);
-
 
246
        float negVert = frames[2*NbitsHorz+2*levelVert+3].at<char>(rowBelow, col);
-
 
247
        float posVertBelow = frames[2*NbitsHorz+2*levelVert+2].at<char>(rowBelow, col);
-
 
248
        float negVertBelow = frames[2*NbitsHorz+2*levelVert+3].at<char>(rowBelow, col);
-
 
249
 
-
 
250
        float y = row + (posVert - negVert)/(negVertBelow - negVert - posVertBelow + posVert);
-
 
251
 
-
 
252
        // write into return vector
-
 
253
        q[i] = cv::Vec2f(x, y);
-
 
254
 
-
 
255
    }
-
 
256
}
-
 
257
 
215
static cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt){
258
static cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt){
216
    assert(!img.empty());
259
    assert(!img.empty());
217
    assert(img.channels() == 3);
260
    assert(img.channels() == 3);
218
 
261
 
219
    int x = (int)pt.x;
262
    int x = (int)pt.x;
Line 358... Line 401...
358
        color.resize(0);
401
        color.resize(0);
359
 
402
 
360
        return;
403
        return;
361
    }
404
    }
362
 
405
 
363
    std::vector<cv::Vec2f> q0(nMatches), q1(nMatches);
406
    std::vector<cv::Point2f> q0(nMatches), q1(nMatches);
364
 
407
 
365
//    for(int i=0; i<nMatches; i++){
408
//    for(int i=0; i<nMatches; i++){
366
//        q0[i] = cv::Vec2f(matches0[i].col, matches0[i].row);
409
//        q0[i] = cv::Vec2f(matches0[i].col, matches0[i].row);
367
//        q1[i] = cv::Vec2f(matches1[i].col, matches1[i].row);
410
//        q1[i] = cv::Vec2f(matches1[i].col, matches1[i].row);
368
//    }
411
//    }
369
 
412
 
370
    // horizontal subpixel refinement finds the intersection of linear interpolants in the positive/negative pattern
-
 
371
    // TODO: subpixel refinement in both horizontal and vertical
-
 
372
    for(int i=0; i<nMatches; i++){
-
 
373
 
-
 
374
        int level = NbitsHorz - leastSignificantBitSet(matches0[i].labelLeft^matches0[i].labelRight);
-
 
375
 
-
 
376
        // refine for camera 0
413
    // subpixel refinement
377
        float row = matches0[i].row;
-
 
378
        float c0 = matches0[i].col;
-
 
379
        float c1 = c0+1;
-
 
380
 
-
 
381
        float pos0 = frames0[2*level+2].at<char>(row, c0);
-
 
382
        float pos1 = frames0[2*level+2].at<char>(row, c1);
-
 
383
        float neg0 = frames0[2*level+3].at<char>(row, c0);
414
    getSubpixelCoordinates(matches0, frames0, NbitsHorz, NbitsVert,q0);
384
        float neg1 = frames0[2*level+3].at<char>(row, c1);
415
    getSubpixelCoordinates(matches1, frames1, NbitsHorz, NbitsVert,q1);
385
 
-
 
386
        float col = c0 + (pos0 - neg0)/(neg1 - neg0 - pos1 + pos0);
-
 
387
        q0[i] = cv::Vec2f(col, row);
-
 
388
 
-
 
389
        // refine for camera 1
-
 
390
        row = matches1[i].row;
-
 
391
        c0 = matches1[i].col;
-
 
392
        c1 = c0+1;
-
 
393
 
-
 
394
        pos0 = frames1[2*level+2].at<char>(row, c0);
-
 
395
        pos1 = frames1[2*level+2].at<char>(row, c1);
-
 
396
        neg0 = frames1[2*level+3].at<char>(row, c0);
-
 
397
        neg1 = frames1[2*level+3].at<char>(row, c1);
-
 
398
 
-
 
399
        col = c0 + (pos0 - neg0)/(neg1 - neg0 - pos1 + pos0);
-
 
400
        q1[i] = cv::Vec2f(col, row);
-
 
401
 
-
 
402
    }
-
 
403
 
-
 
404
 
-
 
405
 
416
 
406
 
417
 
407
    // retrieve color information (at integer coordinates)
418
    // retrieve color information (at subpixel coordinates)
408
    color.resize(nMatches);
419
    color.resize(nMatches);
409
    for(int i=0; i<nMatches; i++){
420
    for(int i=0; i<nMatches; i++){
410
 
421
 
411
//        cv::Vec3b c0 = color0.at<cv::Vec3b>(q0[i][1], q0[i][0]);
422
//        cv::Vec3b c0 = color0.at<cv::Vec3b>(q0[i][1], q0[i][0]);
412
//        cv::Vec3b c1 = color1.at<cv::Vec3b>(q1[i][1], q1[i][0]);
423
//        cv::Vec3b c1 = color1.at<cv::Vec3b>(q1[i][1], q1[i][0]);
Line 423... Line 434...
423
    cv::Mat P1(3, 4, CV_32F), temp(3,4,CV_32F);
434
    cv::Mat P1(3, 4, CV_32F), temp(3,4,CV_32F);
424
    cv::Mat(calibration.R1).copyTo(temp(cv::Range(0,3), cv::Range(0,3)));
435
    cv::Mat(calibration.R1).copyTo(temp(cv::Range(0,3), cv::Range(0,3)));
425
    cv::Mat(calibration.T1).copyTo(temp(cv::Range(0,3), cv::Range(3,4)));
436
    cv::Mat(calibration.T1).copyTo(temp(cv::Range(0,3), cv::Range(3,4)));
426
    P1 = cv::Mat(calibration.K1) * temp;
437
    P1 = cv::Mat(calibration.K1) * temp;
427
 
438
 
428
    cv::correctMatches(calibration.F, q0, q1, q0, q1);
439
    //cv::correctMatches(calibration.F, q0, q1, q0, q1);
429
 
440
 
430
    cv::Mat QMatHomogenous, QMat;
441
    cv::Mat QMatHomogenous, QMat;
431
    cv::triangulatePoints(P0, P1, q0, q1, QMatHomogenous);
442
    cv::triangulatePoints(P0, P1, q0, q1, QMatHomogenous);
432
 
443
 
433
    cvtools::convertMatFromHomogeneous(QMatHomogenous, QMat);
444
    cvtools::convertMatFromHomogeneous(QMatHomogenous, QMat);