AlignToVideo: Handle tolerance = 0 correctly

Checking if the diff is '>' instead of '>=' will always fail if
tolerance=0, even if the colours are identical. This will cause the line
to get a startime greter than its end time, which is not desireable.

Rounding errors and limits of floating type precision might still affect
the comparison. An additional sanity check before calculation is added
to ensure the selected position and colour match within tolerance.
This allows us to refactor the search code to never check the starting
frame and guanrantees valid timings with start<end even with
rounding errors.
This commit is contained in:
Oneric 2020-07-16 23:21:25 +02:00
parent 7f4cdaea42
commit e2ea84541f
1 changed files with 15 additions and 13 deletions

View File

@ -195,7 +195,7 @@ namespace {
// in pixel: B,G,R
rgb2lab(pixel[2], pixel[1], pixel[0], lab);
auto diff = sqrt(pow(lab[0] - orig[0], 2) + pow(lab[1] - orig[1], 2) + pow(lab[2] - orig[2], 2));
return diff < tolerance;
return diff <= tolerance;
}
template<typename T>
@ -290,28 +290,30 @@ namespace {
auto view = interleaved_view(frame->width, frame->height, reinterpret_cast<boost::gil::bgra8_pixel_t*>(frame->data.data()), frame->pitch);
if (frame->flipped)
y = frame->height - y;
// Ensure selected color and position match
if(!check_point(*view.at(x,y), lab, tolerance))
{
wxMessageBox(_("Selected position and color are not within tolerance!"));
return;
}
int lrud[4];
calculate_point(view, x, y, lab, tolerance, lrud);
// find forward
#define CHECK_EXISTS_POS check_exists(pos, x, y, lrud, lab, tolerance)
while (pos >= 0)
{
if (CHECK_EXISTS_POS)
pos -= 2;
else break;
}
do {
pos -= 2;
} while (pos >= 0 && !CHECK_EXISTS_POS)
pos++;
pos = std::max(0, pos);
auto left = CHECK_EXISTS_POS ? pos : pos + 1;
pos = current_n_frame;
while (pos < n_frames)
{
if (CHECK_EXISTS_POS)
pos += 2;
else break;
}
do {
pos += 2;
} while (pos < n_frames && !CHECK_EXISTS_POS)
pos--;
pos = std::min(pos, n_frames - 1);
auto right = CHECK_EXISTS_POS ? pos : pos - 1;