Skip to content

Commit

Permalink
[keyframe] Handle corner case when identifying subsequences
Browse files Browse the repository at this point in the history
This commit handles the specific case where the last frame of an input
sequence happens to be the one that pushes the motion accumulation over
the threshold: the last frame was being pushed a first time within the
'for' loop, and then a second time outside of it. This led the last
subsequence to have a size of 0, which led to the 'while' loop condition
filling the weights' vector to never be broken.
  • Loading branch information
cbentejac committed Jan 25, 2023
1 parent 5f61a5e commit e9567f9
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions src/aliceVision/keyframe/KeyframeSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,10 @@ void KeyframeSelector::processSmart(const float pxDisplacement, const std::size_

float step = pxDisplacement * std::min(_frameWidth, _frameHeight) / 100.0;
double motionAcc = 0.0;
for (std::size_t i = 1; i < sequenceSize; i++) { // Starts at 1 because the first frame's motion score will be -1

/* Starts at 1 because the first frame's motion score will be -1.
* Ends at sequenceSize - 1 to ensure the last frame cannot be pushed twice. */
for (std::size_t i = 1; i < sequenceSize -1; i++) {
motionAcc += _flowScores.at(i);
if (motionAcc >= step) {
subsequenceLimits.push_back(i);
Expand Down Expand Up @@ -248,7 +251,7 @@ void KeyframeSelector::processSmart(const float pxDisplacement, const std::size_
}
motionAcc = 0.0;

for (std::size_t i = 1; i < sequenceSize; i++) {
for (std::size_t i = 1; i < sequenceSize - 1; i++) {
motionAcc += _flowScores.at(i);
if (motionAcc >= step) {
newLimits.push_back(i);
Expand All @@ -264,7 +267,7 @@ void KeyframeSelector::processSmart(const float pxDisplacement, const std::size_
newLimits.push_back(0);
std::size_t stepSize = (sequenceSize / _minOutFrames) + 1;

for (std::size_t i = 1; i < sequenceSize; i += stepSize)
for (std::size_t i = 1; i < sequenceSize - 1; i += stepSize)
newLimits.push_back(i);
newLimits.push_back(sequenceSize - 1);
}
Expand All @@ -276,7 +279,7 @@ void KeyframeSelector::processSmart(const float pxDisplacement, const std::size_
step = step + displacementDiff;
motionAcc = 0.0;

for (std::size_t i = 1; i < sequenceSize; i++) {
for (std::size_t i = 1; i < sequenceSize - 1; i++) {
motionAcc += _flowScores.at(i);
if (motionAcc >= step) {
newLimits.push_back(i);
Expand All @@ -296,6 +299,7 @@ void KeyframeSelector::processSmart(const float pxDisplacement, const std::size_
double bestSharpness = 0.0;
std::size_t bestIndex = 0;
std::size_t subsequenceSize = subsequenceLimits.at(i) - subsequenceLimits.at(i - 1);
ALICEVISION_LOG_DEBUG("Subsequence [" << subsequenceLimits.at(i - 1) << ", " << subsequenceLimits.at(i) << "]");

// Weights for the whole subsequence [1.0; 2.0] (1.0 is on the subsequence's limits, 2.0 on its center)
std::deque<double> weights;
Expand All @@ -320,10 +324,12 @@ void KeyframeSelector::processSmart(const float pxDisplacement, const std::size_
bestSharpness = sharpness;
}
}
ALICEVISION_LOG_DEBUG("Selecting frame " << bestIndex);
ALICEVISION_LOG_DEBUG("Selecting frame with ID " << bestIndex);
_selectedKeyframes.push_back(bestIndex);
_selectedFrames.at(bestIndex) = '1'; // The frame has been selected, flip it to 1
}

ALICEVISION_LOG_DEBUG("Finished selecting all the keyframes!");
}

bool KeyframeSelector::computeScores(const std::size_t rescaledWidth, const std::size_t sharpnessWindowSize,
Expand Down

0 comments on commit e9567f9

Please sign in to comment.