我有这个学校作业,要求我能够使用opencv和C ++放大和缩小感兴趣的区域。感兴趣区域的大小初始化为80 * 80,并且在点击时增加(左键单击)并减少(右键单击)10px垂直和水平。我想我已经设法这样做了:
// 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
我希望问题描述清楚,谢谢你提前帮助。
答案 0 :(得分:0)
如果你放大了roi,你可以记住这个roi的位置(位置和大小)。
例如:
roi.x = 300;
roi.y = 200;
roi.width = 20;
roi.height = 20;
现在,如果你有一个仅调整了20x20区域的大小调整后的图像,但调整大小为100x100像素图像,然后显示它,你想点击某处并计算相应的原始位置?
在该缩放图像中,您知道点击坐标,例如
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;
希望这会有所帮助