in source/depth_estimation/Derp.cpp [749:823]
void randomProposal(
PyramidLevel<PixelType>& pyramidLevel,
const int dstIdx,
const int y,
const int numProposals,
const float minDepthMeters,
const float maxDepthMeters) {
std::default_random_engine engine;
engine.seed(y * pyramidLevel.level);
cv::Mat_<float>& dstDisparity = pyramidLevel.dstDisparity(dstIdx);
cv::Mat_<float>& dstCosts = pyramidLevel.dstCost(dstIdx);
cv::Mat_<float>& dstConfidence = pyramidLevel.dstConfidence(dstIdx);
const cv::Mat_<float>& variance = pyramidLevel.dstVariance(dstIdx);
for (int x = kSearchWindowRadius; x < dstDisparity.cols - kSearchWindowRadius; ++x) {
if (!pyramidLevel.dstFovMask(dstIdx)(y, x)) { // outside FOV
// Keep value from previous frame
continue;
}
float currDisp = dstDisparity(y, x); // upscaled disparity
// Use background value if we're outside the foreground mask
if (!pyramidLevel.dstForegroundMask(dstIdx)(y, x)) {
dstDisparity(y, x) = pyramidLevel.dstBackgroundDisparity(dstIdx)(y, x);
continue;
}
// Ignore locations with low variance
// Threshold is a little lower than our high variance threshold
// High variance locations include:
// - textured objects: easier to match
// - new objects: not present at coarser levels
// Lower than high variance locations include:
// - weaker edges: as they appear or dissapear
// - pixels around edges: can see what's behind
// We can go pretty low, as long as we ignore smooth and noisy areas
const float varHighDev = kRandomPropHighVarDeviation * pyramidLevel.varHighThresh;
const float varHighThresh = std::max(varHighDev, pyramidLevel.varNoiseFloor);
if (variance(y, x) < varHighThresh) {
continue;
}
float currCost;
float currConfidence;
std::tie(currCost, currConfidence) = computeCost(pyramidLevel, dstIdx, currDisp, x, y);
// We will refine only if we're getting much better cost
const float costThresh = std::fmin(0.5f * currCost, kRandomPropMaxCost);
// When using background, foreground pixels must be closer than background
const float minDisp = pyramidLevel.hasForegroundMasks
? pyramidLevel.dstBackgroundDisparity(dstIdx)(y, x)
: (1.0f / maxDepthMeters);
const float maxDisp = 1.0f / minDepthMeters;
float amplitude = (maxDisp - minDisp) / 2.0f;
for (int i = 0; i < numProposals; ++i) {
float propDisp = std::uniform_real_distribution<float>(
std::max(float(minDisp), currDisp - amplitude),
std::min(float(maxDisp), currDisp + amplitude))(engine);
float propCost;
float propConfidence;
std::tie(propCost, propConfidence) = computeCost(pyramidLevel, dstIdx, propDisp, x, y);
if (propCost < currCost && propCost < costThresh) {
currCost = propCost;
currDisp = propDisp;
currConfidence = propConfidence;
amplitude /= 2.0f;
}
}
dstDisparity(y, x) = currDisp;
dstCosts(y, x) = currCost;
dstConfidence(y, x) = currConfidence;
}
}