图像中某点绕点旋转后的坐标,图像旋转坐标位置
在平面坐标上,任意点P(x1,y1),绕一个坐标点Q(x2,y2)旋转θ角度后,新的坐标设为(x, y)的计算公式:
-
x= (x1 - x2)*
cos(θ) - (y1 - y2)*
sin(θ) + x2 ;
-
y= (x1 - x2)*
sin(θ) + (y1 - y2)*
cos(θ) + y2 ;
这是在平面上的坐标旋转公式,但在图像中某个像素点旋转一个角度后的坐标不能用上述公式直接求出,因为图像(0,0)点的坐标的原点是在图像的左上角。
假设图像的宽度x高度为col x row,图像中某个像素P(x1,y1),绕某个像素点Q(x2,y2)旋转θ角度后,则该像素点的新坐标位置为(x, y),其计算公式为:
-
-
-
-
-
x = (x1 - x2)*
cos(pi /
180.0 * θ) - (y1 - y2)*
sin(pi /
180.0 * θ) + x2;
-
y = (x1 - x2)*
sin(pi /
180.0 * θ) + (y1 - y2)*
cos(pi /
180.0 * θ) + y2;
-
-
下面给出OpenCV的实现代码:原图像的大小500x577,像素点P(100,100),绕图像中心Q(250,288.5)旋转θ角度后,则该像素点的新坐标位置为(173, 60)
关于OpenCV实现图像旋转的方法,可参考本人的博客:《OpenCV图像旋转,指定填充背景颜色边界颜色》 http://blog.csdn.net/guyuealian/article/details/77993410
-
-
-
-
-
#include <opencv2\opencv.hpp>
-
#include <opencv2\highgui\highgui.hpp>
-
-
-
-
-
vector<cv::Point2i> getRotatePoint(cv::Mat srcImage,
vector<cv::Point2i> Points,
const cv::Point rotate_center,
const
double angle) {
-
vector<cv::Point2i> dstPoints;
-
-
-
for (
size_t i =
0; i < Points.size(); i++)
-
-
-
y1 = row - Points.at(i).y;
-
int x2 = rotate_center.x;
-
int y2 = row - rotate_center.y;
-
int x = cvRound((x1 - x2)*
cos(pi /
180.0 * angle) - (y1 - y2)*
sin(pi /
180.0 * angle) + x2);
-
int y = cvRound((x1 - x2)*
sin(pi /
180.0 * angle) + (y1 - y2)*
cos(pi /
180.0 * angle) + y2);
-
-
dstPoints.push_back(Point2i(x, y));
-
-
-
-
-
-
Mat src = imread(
"D:\\OpencvTest\\16.jpg");
-
-
vector<cv::Point2i> Points;
-
-
cv::circle(src, point,
2, cv::Scalar(
255,
0,
0),
2);
-
cv::imshow(
"src image ", src);
-
-
-
-
-
-
cv::
Size dst_sz(src.cols, src.rows);
-
-
cv::
Point2f center(src.cols / 2., src.rows / 2.);
-
-
-
cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle,
1.0);
-
-
cv::Scalar borderColor = Scalar(
0,
238,
0);
-
cv::warpAffine(src, dst, rot_mat, dst_sz, INTER_LINEAR, BORDER_CONSTANT, borderColor);
-
-
-
vector<cv::Point2i> dstPoints = getRotatePoint(dst, Points, center, angle);
-
cv::circle(dst, dstPoints.at(
0),
5, cv::Scalar(
0,
0,
255),
2);
-
cv::imshow(
"Rotation Image", dst);
-
-
-
-