Home > Software design >  mapping of coordinates to the resized image
mapping of coordinates to the resized image

Time:03-17

I have original image of size (969,348) and the resized image is (696,484). I have a point (385,400) in the resized image, so I want to plot it to the original image. oldx = 385 oldy = 400 I have resized it using

resize(org, resizeimage, Size(org.rows / 0.5, org.cols / 2), 0, 0, INTER_AREA);

I am using OpenCV C and where I am confused with the rows and cols, what is the width and height. I have tried this but it gives me (0,484) coordinate.

Point(round(float((oldx / org.cols)) * resizeimage.cols), round(float((oldy / org.rows))) * resizeimage.rows)

CodePudding user response:

I prefer map coordinates in the following way:

float x_ratio = resizeimage.cols / static_cast<float>(org.cols);
float y_ratio = resizeimage.rows / static_cast<float>(org.rows);
cv::Point newPoint(static_cast<int>(oldx * x_ratio), 
                   static_cast<int>(oldy * y_ratio));

CodePudding user response:

The distance for the center is proportional to the scaling (in each axis).

We may compute newx and newy as follows:

  • Subtract x_original_center and y_original_center from oldx and oldy.
    After subtraction, (0, 0) is the "new center" (applies "centered coordinate system").
  • Scale the "zero centered" coordinates by scale_x and scale_y.
  • Convert the "scaled zero centered" coordinates to "top left (0, 0)" by adding x_scaled_center and y_scaled_center.

Illustration:

Origin:
(0,0)                     New coordinate system: (0,0) center 
     -----------------                       -----------------                
    |                 | x -= (cols-1)/2     |    (0,0)        |
    |                 | ===============>    |                 |
    |                 | y -= (rows-1)/2     |                 |
     -----------------                       -----------------
     
     
    After scaling:
    The distance to the center is proportional to the scale.
    In x axis the distance is proportional to x_scale
    In y axis the distance is proportional to y_scale


                                        -------------
                                       |             |
                                       |      ^    o |
                                       | y*sy |      |
     --------^--------                 |      |      |
    |      y |     o  |    Scale       |      V      |
    |         <--->   | ===========>   |       <-->  |
    |           x     |                |       x*sx  |
     -----------------                 |             |
                                       |             |
                                       |             |
                                       |             |
                                        -------------    
                                        
Convert the scaled result to origin (0, 0): 
newx  = (new_cols-1)/2
newy  = (new_rows-1)/2

Computing the center accurately:
The C conversion is:
(0, 0) is the top left, and (cols-1, rows-1) is the bottom right coordinate.
The accurate center coordinate is:
x_original_center = (original_rows-1.0)/2.0
y_original_center = (original_cols-1.0)/2.0


C code sample:

#include <cmath>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/highgui/highgui.hpp>

int main()
{
    double scale_x = 2.0;
    double scale_y = 0.5;

    int oldx = 385;
    int oldy = 400;

    cv::Mat org = cv::Mat::zeros(cv::Size(969, 348), CV_8UC1);  //Fill with zeros (for example).
    cv::Mat resizeimage;

    //Height and width before resize:
    int rows = org.rows;    //384
    int cols = org.cols;    //969

    //cv::resize(org, resizeimage, Size(org.rows / 0.5, org.cols / 2.0), 0, 0, INTER_AREA);

    //Instead of dividing by 0.5, sacle by 2.0 (and Instead of dividing by 2.0, scale by 0.5)
    cv::resize(org, resizeimage, cv::Size((int)std::round(rows * scale_x), (int)std::round(cols * scale_y)), 0, 0, cv::INTER_AREA);

    //Height and width after resize:
    int resized_rows = resizeimage.rows;    //485
    int resized_cols = resizeimage.cols;    //696

    //Center before resize:
    double x_original_center = ((double)cols - 1.0) / 2.0;  //484.0
    double y_original_center = ((double)rows - 1.0) / 2.0;  //173.5

    //Center after resize:
    double x_scaled_center = ((double)resized_cols - 1.0) / 2.0;    //347.5
    double y_scaled_center = ((double)resized_rows - 1.0) / 2.0;    //242

    //Subtract the center, scale, and add the "scaled center".
    int newx = (int)std::round((oldx - x_original_center) * scale_x   x_scaled_center); //150
    int newy = (int)std::round((oldy - y_original_center) * scale_y   y_scaled_center); //355

    std::cout << "newx = " << newx << std::endl << "newy = " << newy << std::endl;

    return 0;
}
  • Related