void FastGSW::geoMaskDijkstra(const Mat &left, const Mat &seg, const Point &pivot, vector<vector<float>> &w) { w[pivot.y][pivot.x] = 0.0f; priority_queue<Node> heap; heap.emplace(0.0f, pivot); int segIdx = seg.at<int>(pivot); int ny, nx; while (!heap.empty()) { Node v = heap.top(); heap.pop(); if (v.d > w[v.y][v.x]) continue; for (int dy = -1; dy <= 1; ++dy) { for (int dx = -1; dx <= 1; ++dx) { if (dx == 0 && dy == 0) continue; ny = v.y + dy; nx = v.x + dx; if (!in(ny, nx, seg)) continue; if (seg.at<int>(ny, nx) != segIdx) continue; if (w[ny][nx] > (v.d + diff(left.pix(v.y, v.x), left.pix(ny, nx)))) { w[ny][nx] = (v.d + diff(left.pix(v.y, v.x), left.pix(ny, nx))); heap.emplace(w[ny][nx], nx, ny); } } } } }
void FastGSW::computeLR(const Mat &left, const Mat &right, const Mat &seg, Mat &disp, int dispType) { disp.create(left.size(), dispType); int mxIdx = *max_element(seg.begin<int>(), seg.end<int>()); vector<vector<Point>> segPts(mxIdx + 1); for (int i = 0; i < seg.rows; ++i) { for (int j = 0; j < seg.cols; ++j) { segPts[seg.at<int>(i, j)].emplace_back(j, i); } } vector<vector<float>> w(seg.rows, vector<float>(seg.cols, numeric_limits<float>::infinity())); vector<Vec3f> segColor(mxIdx + 1, Vec3f(0, 0, 0)); for (int i = 0; i <= mxIdx; ++i) { geoMaskDijkstra(left, seg, segPts[i][segPts[i].size()/2], w); float denom = 0.0f; for (const Point &pnt : segPts[i]) { w[pnt.y][pnt.x] = exp(-w[pnt.y][pnt.x] / gamma); Vec3f tmp = left.pix(pnt.y, pnt.x); segColor[i] += w[pnt.y][pnt.x]*tmp; denom += w[pnt.y][pnt.x]; } segColor[i] /= denom; } vector<vector<float>> cst(seg.rows, vector<float>(seg.cols, numeric_limits<float>::infinity())); vector<vector<float>> ps(seg.rows, vector<float>(seg.cols, 0.0f)); for (int d = 0; d <= numDisp; ++d) { for (int i = 0; i < seg.rows; ++i) { for (int j = 0; j < seg.cols; ++j) { ps[i][j] = psAt(ps, i - 1, j) + psAt(ps, i, j - 1) - psAt(ps, i - 1, j - 1) + mcost(segColor[seg.at<int>(i, j)], right, i, j, d); } } for (int i = 0; i < seg.rows; ++i) { for (int j = 0; j < seg.cols; ++j) { float tc = cost(ps, i, j); if (tc < cst[i][j]) { cst[i][j] = tc; if (dispType == CV_16S) disp.at<short>(i, j) = (short)d; else disp.at<float>(i, j) = (float)d; } } } } }
void FastGSW::computeRL(const Mat &left, const Mat &right, const Mat &seg, Mat &disp, int dispType) { disp.create(left.size(), dispType); //only for visualization vvv //Mat tmp = segRandomPaint(seg); //left.copyTo(tmp); //segContours(seg, tmp); //imwrite("segmentation.png", tmp); //only for visualization ^^^ int mxIdx = *max_element(seg.begin<int>(), seg.end<int>()); vector<vector<Point>> segPts(mxIdx + 1); for (int i = 0; i < seg.rows; ++i) { for (int j = 0; j < seg.cols; ++j) { segPts[seg.at<int>(i, j)].emplace_back(j, i); } } //Geodesic supports weights vector<vector<float>> w(seg.rows, vector<float>(seg.cols, 0.0f)); //Segment color vector<Vec3f> segColor(mxIdx + 1, Vec3f(0, 0, 0)); Mat display(seg.rows, seg.cols, CV_8UC1); for (int i = 0; i <= mxIdx; ++i) { geoMaskDijkstra(right, seg, segPts[i][segPts[i].size()/2], w); //only for visualization vvv //float maxw = 0.0f; //for (const Point &pnt : segPts[i]) { // maxw = max(maxw, w[pnt.y][pnt.x]); //} //only for visualization ^^^ float denom = 0.0f; for (const Point &pnt : segPts[i]) { w[pnt.y][pnt.x] = exp(-w[pnt.y][pnt.x] / gamma); //display.at<uchar>(pnt) = ((w[pnt.y][pnt.x] / maxw)*255.0f); Vec3f tmp = right.pix(pnt.y, pnt.x); segColor[i] += w[pnt.y][pnt.x] * tmp; denom += w[pnt.y][pnt.x]; } segColor[i] /= denom; //only for visualization vvv //for (const Point &pnt : segPts[i]) { // tmp.at<Vec3b>(pnt) = segColor[i]; //} //only for visualization ^^^ } vector<vector<float>> cst(seg.rows, vector<float>(seg.cols, numeric_limits<float>::infinity())); vector<vector<float>> ps(seg.rows, vector<float>(seg.cols, 0.0f)); for (int d = 0; d <= numDisp; ++d) { //prefix sums for (int i = 0; i < seg.rows; ++i) { for (int j = 0; j < seg.cols; ++j) { ps[i][j] = psAt(ps, i - 1, j) + psAt(ps, i, j - 1) - psAt(ps, i - 1, j - 1) + mcost(segColor[seg.at<int>(i, j)], left, i, j, -d); } } for (int i = 0; i < seg.rows; ++i) { for (int j = 0; j < seg.cols; ++j) { float tc = cost(ps, i, j); if (tc < cst[i][j]) { cst[i][j] = tc; if (dispType == CV_16S) disp.at<short>(i, j) = (short)(-d); else disp.at<float>(i, j) = (float)(-d); } } } } //imwrite("recolored.png", tmp); //imwrite("geodesic.png", display); }