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
andy_original_center
fromoldx
andoldy
.
After subtraction, (0, 0) is the "new center" (applies "centered coordinate system"). - Scale the "zero centered" coordinates by
scale_x
andscale_y
. - Convert the "scaled zero centered" coordinates to "top left (0, 0)" by adding
x_scaled_center
andy_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;
}