in source/depth_estimation/Derp.cpp [402:477]
void pingPongRectangle(
cv::Mat_<float>& dispRes,
cv::Mat_<float>& costsRes,
cv::Mat_<float>& confidencesRes,
const cv::Mat_<bool>& changed,
const cv::Mat_<cv::Vec3b>& labImage,
const PyramidLevel<PixelType>& pyramidLevel,
const int dstIdx,
const int xBegin,
const int yBegin,
const int xEnd,
const int yEnd) {
const cv::Mat_<float>& disp = pyramidLevel.dstDisparity(dstIdx);
const cv::Mat_<float>& confidences = pyramidLevel.dstConfidence(dstIdx);
const cv::Mat_<bool>& maskFov = pyramidLevel.dstFovMask(dstIdx);
const cv::Mat_<float>& dispBackground = pyramidLevel.dstBackgroundDisparity(dstIdx);
const cv::Mat_<float>& variance = pyramidLevel.dstVariance(dstIdx);
for (int y = yBegin; y < yEnd; ++y) {
for (int x = xBegin; x < xEnd; ++x) {
if (!maskFov(y, x)) {
// Keep value from previous frame
continue;
}
// Use background value if we're outside the foreground mask
if (!pyramidLevel.dstForegroundMask(dstIdx)(y, x)) {
dispRes(y, x) = dispBackground(y, x);
continue;
}
// Ignore locations with low variance
if (variance(y, x) < pyramidLevel.varNoiseFloor) {
continue;
}
float bestCost = INFINITY;
float bestDisparity = disp(y, x);
float bestConfidence = confidences(y, x);
std::vector<std::array<int, 2>> candidateNeighborOffsets;
if (kDoColorPruning) {
const std::array<int, 2>& startPoint = {{x, y}};
candidateNeighborOffsets = prunePingPongCandidates(
candidateTemplateOriginal, labImage, startPoint, kColorPruningNumNeighbors);
} else {
candidateNeighborOffsets = candidateTemplateOriginal;
}
const float backgroundDisparity =
pyramidLevel.hasForegroundMasks ? pyramidLevel.dstBackgroundDisparity(dstIdx)(y, x) : 0;
for (const auto& candidateNeighborOffset : candidateNeighborOffsets) {
const int xx = math_util::clamp(x + candidateNeighborOffset[0], 0, disp.cols - 1);
const int yy = math_util::clamp(y + candidateNeighborOffset[1], 0, disp.rows - 1);
if (maskFov(yy, xx)) { // inside FOV
const float d = disp(yy, xx);
// When using background disparity, foreground pixels must be closer than background
if (d >= backgroundDisparity && changed(yy, xx)) {
const auto costValues = computeCost(pyramidLevel, dstIdx, d, x, y);
const float cost = std::get<0>(costValues);
if (cost < bestCost) {
bestCost = cost;
bestDisparity = d;
bestConfidence = std::get<1>(costValues);
}
}
}
}
dispRes(y, x) = bestDisparity;
costsRes(y, x) = bestCost;
confidencesRes(y, x) = bestConfidence;
}
}
}