Construct GCGraph */
| 444 | Construct GCGraph |
| 445 | */ |
| 446 | static void constructGCGraph( const Mat& img, const Mat& mask, const GMM& bgdGMM, const GMM& fgdGMM, double lambda, |
| 447 | const Mat& leftW, const Mat& upleftW, const Mat& upW, const Mat& uprightW, |
| 448 | GCGraph<double>& graph ) |
| 449 | { |
| 450 | int vtxCount = img.cols*img.rows, |
| 451 | edgeCount = 2*(4*img.cols*img.rows - 3*(img.cols + img.rows) + 2); |
| 452 | graph.create(vtxCount, edgeCount); |
| 453 | Point p; |
| 454 | for( p.y = 0; p.y < img.rows; p.y++ ) |
| 455 | { |
| 456 | for( p.x = 0; p.x < img.cols; p.x++) |
| 457 | { |
| 458 | // add node |
| 459 | int vtxIdx = graph.addVtx(); |
| 460 | Vec3b color = img.at<Vec3b>(p); |
| 461 | |
| 462 | // set t-weights |
| 463 | double fromSource, toSink; |
| 464 | if( mask.at<uchar>(p) == GC_PR_BGD || mask.at<uchar>(p) == GC_PR_FGD ) |
| 465 | { |
| 466 | fromSource = -log( bgdGMM(color) ); |
| 467 | toSink = -log( fgdGMM(color) ); |
| 468 | } |
| 469 | else if( mask.at<uchar>(p) == GC_BGD ) |
| 470 | { |
| 471 | fromSource = 0; |
| 472 | toSink = lambda; |
| 473 | } |
| 474 | else // GC_FGD |
| 475 | { |
| 476 | fromSource = lambda; |
| 477 | toSink = 0; |
| 478 | } |
| 479 | graph.addTermWeights( vtxIdx, fromSource, toSink ); |
| 480 | |
| 481 | // set n-weights |
| 482 | if( p.x>0 ) |
| 483 | { |
| 484 | double w = leftW.at<double>(p); |
| 485 | graph.addEdges( vtxIdx, vtxIdx-1, w, w ); |
| 486 | } |
| 487 | if( p.x>0 && p.y>0 ) |
| 488 | { |
| 489 | double w = upleftW.at<double>(p); |
| 490 | graph.addEdges( vtxIdx, vtxIdx-img.cols-1, w, w ); |
| 491 | } |
| 492 | if( p.y>0 ) |
| 493 | { |
| 494 | double w = upW.at<double>(p); |
| 495 | graph.addEdges( vtxIdx, vtxIdx-img.cols, w, w ); |
| 496 | } |
| 497 | if( p.x<img.cols-1 && p.y>0 ) |
| 498 | { |
| 499 | double w = uprightW.at<double>(p); |
| 500 | graph.addEdges( vtxIdx, vtxIdx-img.cols+1, w, w ); |
| 501 | } |
| 502 | } |
| 503 | } |