Excuse me, apparently I shouldn’t type/explain myself while tired. I wrote the code and tested it, then cleaned it up before posting but didn’t test that. As a result a couple of errors creeped in.
Firstly, you’re right, there is no need to square-- in the original code I typed:
roi.height += (height_diff * 2);
roi.width += (width_diff * 2);
But my brain translated that as “squared” when that is the wrong answer. The perimeter of a rectangle is defined as 2(length+width), so that’s what we’re doing here and that (not squared) yields the desired outcome.
Secondly, when I cleaned up the code I removed a superfluous copy of a cv::Mat that I was operating on for testing and when I removed it I broke the positioning code. The second assignment to y_percent/x_percent should operate on the larger video frame, not the smaller one thus this is correct:
y_percent = percent_to_number(y_percent, f->rows);
x_percent = percent_to_number(x_percent, f->cols);
And while the problem is simplistic enough that I wouldn’t copy/paste, the entire tested/working solution is as follows:
std::size_t height_diff(percent_difference(f->size().height, frame.size().height));
std::size_t width_diff(percent_difference(f->size().width, frame.size().width));
std::size_t y_percent(number_to_percent(roi.y, frame.rows));
std::size_t x_percent(number_to_percent(roi.x, frame.cols));
height_diff = percent_to_number(height_diff, roi.height);
width_diff = percent_to_number(width_diff, roi.width);
y_percent = percent_to_number(y_percent, f->rows);
x_percent = percent_to_number(x_percent, f->cols);
roi.y = y_percent;
roi.x = x_percent;
roi.height += (height_diff * 2);
roi.width += (width_diff * 2);
/* There is an assertion inside of opencv which will crash the program
* if we don't handle it here.
*/
if (0 > roi.x || 0 > roi.width || roi.x + roi.width > f->cols ||
0 > roi.y || 0 > roi.height || roi.y + roi.height > f->rows) {
qDebug() << "ASSERTION FAILED";
return new cv::Mat(f->clone());
}
frame = (*f)(roi).clone();
Thanks!