in lib/PoseOptimizer.cpp [1242:1339]
void DepthVideoPoseOptimizer::addSceneFlowSmoothnessLoss(
const Params& params, const FlowConstraintsCollection& constraints) {
LOG(INFO) << " Adding scene flow smoothness loss...";
DepthStream& ds = video_->depthStream(depthStream_);
const double aspect = video_->aspect();
const double vFocal =
(aspect >= 1.f ? params.focalLong / aspect : params.focalLong);
int tripletCount = 0;
int constraintCount = 0;
for (int frame = params.frameRange.firstFrame();
frame < params.frameRange.lastFrame() - 1; ++frame) {
if (!params.frameRange.inRange(frame) ||
!params.frameRange.inRange(frame + 1) ||
!params.frameRange.inRange(frame + 2)) {
continue;
}
++tripletCount;
DepthFrame& df0 = ds.frame(frame + 0);
DepthFrame& df1 = ds.frame(frame + 1);
DepthFrame& df2 = ds.frame(frame + 2);
const int triplet = frame + 1;
const TripletFlowConstraints& tripletConstraints = constraints(triplet);
for (const TripletConstraint& c : tripletConstraints) {
const Vector2fna& loc0 = c[0];
auto obs0 = std::make_shared<Observation>(
df0, poseParams_[frame + 0].data(), loc0);
const Vector2fna& loc1 = c[1];
auto obs1 = std::make_shared<Observation>(
df1, poseParams_[frame + 1].data(), loc1);
const Vector2fna& loc2 = c[2];
auto obs2 = std::make_shared<Observation>(
df2, poseParams_[frame + 2].data(), loc2);
if (!std::isfinite(obs0->sourceDepth) || obs0->sourceDepth <= 0 ||
!std::isfinite(obs1->sourceDepth) || obs1->sourceDepth <= 0 ||
!std::isfinite(obs2->sourceDepth) || obs2->sourceDepth <= 0) {
continue;
}
using LossType = SceneFlowSmoothnessLoss;
using CostFnType = ceres::DynamicAutoDiffCostFunction<LossType, kStride>;
auto* costFunction = new CostFnType(new LossType(
obs0, obs1, obs2, vFocal, aspect, params.intrOpt,
params.smoothLossType));
costFunction->SetNumResiduals(3);
for (int size : obs0->paramBlockSizes) {
costFunction->AddParameterBlock(size);
}
for (int size : obs1->paramBlockSizes) {
costFunction->AddParameterBlock(size);
}
for (int size : obs2->paramBlockSizes) {
costFunction->AddParameterBlock(size);
}
if (params.intrOpt == IntrinsicsOptimization::Shared) {
costFunction->AddParameterBlock(1);
} else if (params.intrOpt == IntrinsicsOptimization::PerFrame) {
costFunction->AddParameterBlock(1);
costFunction->AddParameterBlock(1);
costFunction->AddParameterBlock(1);
}
double lossWeight = (c.isStatic ?
params.smoothStaticWeight : params.smoothDynamicWeight);
ceres::LossFunction* lossFunction = new ceres::ScaledLoss(
nullptr, lossWeight, ceres::TAKE_OWNERSHIP);
std::vector<double*> paramBlocks;
insert(paramBlocks, obs0->paramBlockPtrs);
insert(paramBlocks, obs1->paramBlockPtrs);
insert(paramBlocks, obs2->paramBlockPtrs);
if (params.intrOpt == IntrinsicsOptimization::Shared) {
paramBlocks.push_back(&poseParams_[0][6]);
} else if (params.intrOpt == IntrinsicsOptimization::PerFrame) {
paramBlocks.push_back(&poseParams_[frame + 0][6]);
paramBlocks.push_back(&poseParams_[frame + 1][6]);
paramBlocks.push_back(&poseParams_[frame + 2][6]);
}
problem_->AddResidualBlock(costFunction, lossFunction, paramBlocks);
++constraintCount;
}
}
LOG(INFO) << " Using " << tripletCount << " frame triplets.";
LOG(INFO) << " Added " << constraintCount << " constraints.";
}