简体   繁体   English

如何获得缩放图像中点的原始坐标?

[英]How do you get the original coordinates of a point within a zoomed image?

I have this school assignment which asks me to be able zoom in and out on a region of interest using opencv and C++. 我有这个学校作业,要求我能够使用opencv和C ++放大和缩小感兴趣的区域。 The size of the region of interest is initialized at 80*80 and it augments (left click) and diminishes (right click) by 10px vertically and horizontally on click. 感兴趣区域的大小被初始化为80 * 80,并且在单击时垂直和水平方向都增加了10px(左键单击),减小了10%(右键单击)。 I think I have managed to do that as so: 我想我已经做到了:

// 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
        }
    }
}

Now I need to gather information about a pixel clicked within the zoom window, but I do not know how to calculate its coordinates on the original image. 现在,我需要收集有关在缩放窗口中单击的像素的信息,但是我不知道如何计算其在原始图像上的坐标。 I really don't know how to deal with scale and all that. 我真的不知道该如何处理规模等等。 I tried this but it isn't working: 我试过了,但是没有用:

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);
}

Here's what the program is supposed to do: image_program 该程序应该执行以下操作: image_program

I hope that was clear as problem description, thank you in advance for helping. 希望问题描述清楚无误,在此先感谢您的帮助。

sorry I didnt review your code. 抱歉,我没有审查您的代码。

If you zoomed in a roi you can remember where this roi is placed (position and size). 如果您放大某个roi,则可以记住该roi的位置(位置和大小)。

For example: 例如:

roi.x = 300;
roi.y = 200;
roi.width = 20;
roi.height = 20;

Now if you have a resized image holding only this 20x20 region but resized to, let's say 100x100 pixels image, and you display it, you want to click somewhere and compute the corresponding original position? 现在,如果您有一个调整大小的图像,仅包含此20x20区域,但调整为100x100像素的图像,并显示出来,您想单击某个位置并计算相应的原始位置吗?

In that zoomed image you know the click cordinate, like 在放大的图片中,您知道点击坐标,例如

click.x == 10;
click.y == 80;

Now you can compute the relative image coordinate within the zoomed image like 现在您可以计算缩放图像内的相对图像坐标,例如

cv::Point2f relative;
relative.x = (float)click.x/(float)zoomedWidth;
relative.y = (float)click.y/(float)zoomedHeight;

Now in your original image your click pos should be 现在,在您的原始图片中,您的点击位置应该是

cv::Point2f original;
original.x = roi.x + relative.x*roi.width;
original.y = roi.y + relative.y*roi.height;

hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM