Excuse me, apparently I shouldn’t talk when I’m tired-- I tested it, then cleaned up the code some and pasted the cleaned up code without testing it.
In the original tested/working variant I typed:
roi.height += (height_diff * 2);
roi.width += (width_diff * 2);
which my brain translated to “squared”, which is incorrect. I’m increasing the perimeter of the rectangle which is 2(l+w) and not l^2+w^2. So the lines above are the actual correct solution not the lines that square the new height/width.
Additionally, I removed a redundant copy of a cv::Mat without testing it and it broke the positioning because of the second assignment to y_percent/x_percent operating on the wrong rows/cols. They should read:
y_percent = percent_to_number(y_percent, f->rows);
x_percent = percent_to_number(x_percent, f->cols);
And just for clarity, the entire section of code that is tested and working is:
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();
Basically, you need to reposition the xy coordinates in absolute terms and not relative to its current position (although there is probably a way to do it relative to its current xy) and then you need to increase the perimeter of the rectangle, which is 2(length+width).
If you copy/paste, be mindful that there are no sanity checks (e.g. that larger is actually larger) there as in my exact circumstances was impossible.