У меня есть школьное задание, в котором меня просят, чтобы я мог увеличивать и уменьшать область интереса, используя opencv и C ++. Размер области интереса инициализируется в 80 * 80 и увеличивается (щелчок левой кнопкой мыши) и уменьшается (щелчок правой кнопкой мыши) на 10 пикселей по вертикали и по горизонтали при щелчке. Я думаю, что мне удалось сделать это так:
// callback associé à la souris sur la fenêtre "TP1"// clic droit -> zoom arrière
// clic gauche -> zoom avant
// (x, y) indique la position de la souris sur la fenêtre
// event est un évenement de la souris (clic, souris déplacé, etc.)
// flags indique si un bouton de la souris ou du clavier est enfoncé
void cb_on_mouse(int event, int x, int y, int flags, void*)
{
Mat tmp; // temporary image
bool update = false;
// copying src to tmp
src.copyTo(tmp);
// copying src to dst
src.copyTo(dst);
// when mouse moves
if (event == EVENT_MOUSEMOVE)
{
// showing x and y coordinates of the mouse on the main image
putText(dst, "x: " + to_string(x), Point(dst.rows + 4, dst.cols - 25), CV_FONT_HERSHEY_COMPLEX, 5, (0,0,0), 8, true);
putText(dst, "y: " + to_string(y), Point(dst.rows + 4, dst.cols - 5), CV_FONT_HERSHEY_COMPLEX, 5, (0,0,0), 8, true);
imshow("TP1", dst);
}
// when a click happens
else
{
// if ctrl + mouse_btn then there's no zoom
if (flags != EVENT_FLAG_CTRLKEY + EVENT_FLAG_RBUTTON && flags != EVENT_FLAG_CTRLKEY + EVENT_FLAG_LBUTTON)
{
// left click zooms in
if (event == EVENT_LBUTTONDOWN)
{
// zoom in limit set at 2 for both height and width
if (roi.height > 20 && roi.width > 20)
{
roi.height -= pas_yzoom;
roi.width -= pas_xzoom;
}
}
// right click zooms out
else if (event == EVENT_RBUTTONDOWN)
{
// zoom out limit is set of original image size (or close)
if (roi.height < tmp.rows && roi.width < tmp.cols)
{
roi.height += pas_yzoom;
roi.width += pas_xzoom;
}
}
// calculating x
// making sure it doesn't get out of bounds
if (x - (int)(roi.width / 2) <= 0)
roi.x = 0;
else if (x + (int)(roi.width / 2) >= tmp.cols)
roi.x = tmp.cols - roi.width;
else
roi.x = x - (int)(roi.width / 2);
// calculating y
// making sure it doesn't go out of bounds
if (y - (int)(roi.height / 2) <= 0)
roi.y = 0;
else if (y + (int)(roi.height / 2) >= tmp.rows)
roi.y = tmp.rows - roi.height;
else
roi.y = y - (int)(roi.height / 2);
update = true;
}
// only updating the image if an update took place
if (update)
{
zoomed_img = tmp(roi); // creating tmp image
imshow("Zoom", zoomed_img); // displaying tmp
}
}
}
Теперь мне нужно собрать информацию о пикселе, кликнувшем в окне увеличения, но я не знаю, как рассчитать его координаты на исходном изображении. Я действительно не знаю, как бороться с масштабом и всем этим. Я попробовал это, но это не работает:
Mat tmp_zoom; // temporary image for zoom
Mat tmp_src; // temporary image for source
float base_x; // x on original image
float base_y; // y on original image
float scale;
zoomed_img.copyTo(tmp_zoom);
src.copyTo(tmp_src);
scale = (float)(tmp_zoom.cols * tmp_zoom.rows) / (float)(roi.width * roi.height);
if (event == EVENT_LBUTTONDOWN)
{
base_x = ((float)x / scale);
base_y = ((float)y / scale);
cout << "Click on zoom: " << "\n";
cout << "base_x: " << base_x << "\n";
cout << "base_y: " << base_y << "\n";
circle(tmp_src, Point(base_x, base_y), 5, (0, 0, 0), 1, 8, 0);
imshow("TP1", tmp_src);
}
Вот что должна делать программа:
image_program
Я надеюсь, что это было понятно в описании проблемы, заранее благодарю за помощь.
извините, я не просмотрел ваш код
Если вы увеличили масштаб в roi, вы можете вспомнить, где находится этот roi (положение и размер).
Например:
roi.x = 300;
roi.y = 200;
roi.width = 20;
roi.height = 20;
Теперь, если у вас есть изображение с измененным размером, содержащее только эту область 20×20, но с размером, скажем, размером 100×100 пикселей, и вы отображаете его, вы хотите где-нибудь щелкнуть и вычислить соответствующую исходную позицию?
В этом увеличенном изображении вы знаете, что щелчок
click.x == 10;
click.y == 80;
Теперь вы можете вычислить относительную координату изображения в увеличенном изображении, как
cv::Point2f relative;
relative.x = (float)click.x/(float)zoomedWidth;
relative.y = (float)click.y/(float)zoomedHeight;
Теперь в вашем исходном изображении ваш пост должен быть
cv::Point2f original;
original.x = roi.x + relative.x*roi.width;
original.y = roi.y + relative.y*roi.height;
надеюсь это поможет
Других решений пока нет …