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

时间:2016-01-31 10:46:34

标签: c++ image opencv zoom scale

我有这个学校作业,要求我能够使用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

我希望问题描述清楚,谢谢你提前帮助。

1 个答案:

答案 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;

希望这会有所帮助