图像中某点绕点旋转后的坐标,图像旋转坐标位置

图像中某点绕点旋转后的坐标,图像旋转坐标位置


在平面坐标上,任意点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),其计算公式为:

x1 = x1; 
y1 = row - y1; 
x2 = x2; 
y2 = row - y2; 
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; 
x=x; 
y = row - y;

下面给出OpenCV的实现代码:原图像的大小500x577,像素点P(100,100),绕图像中心Q(250,288.5)旋转θ角度后,则该像素点的新坐标位置为(173, 60)

   关于OpenCV实现图像旋转的方法,可参考本人的博客:《OpenCV图像旋转,指定填充背景颜色边界颜色》 http://blog.csdn.net/guyuealian/article/details/77993410

#include "stdafx.h"
#include <iostream>  
#include<vector>
#include<algorithm>
#include <opencv2\opencv.hpp>  
#include <opencv2\highgui\highgui.hpp>  
using namespace std;
using namespace cv;
#define pi 3.1415926
 
vector<cv::Point2i> getRotatePoint(cv::Mat srcImage, vector<cv::Point2i> Points, const cv::Point rotate_center, const double angle) {
	vector<cv::Point2i> dstPoints;
	int x1 = 0, y1 = 0;
	int row = srcImage.rows;
	for (size_t i = 0; i < Points.size(); i++)
	{
		x1 = Points.at(i).x;
		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);
		y = row - y;
		dstPoints.push_back(Point2i(x, y));
	}
	return dstPoints;
}
 
int main() {
	Mat src = imread("D:\\OpencvTest\\16.jpg");
	Point2i point(100, 100);
	vector<cv::Point2i> Points;
	Points.push_back(point);
	cv::circle(src, point, 2, cv::Scalar(255, 0, 0),2);  
	cv::imshow("src image ", src);
 
	cv::Mat dst;    
	//旋转角度-20度      
	double angle =- 20;
	//输出图像的尺寸与原图一样    
	cv::Size dst_sz(src.cols, src.rows);
	//指定旋转中心      
	cv::Point2f center(src.cols / 2., src.rows / 2.);
 
	//获取旋转矩阵(2x3矩阵)      
	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);
	//cv::warpAffine(src, dst, rot_mat, dst_sz, INTER_LINEAR, BORDER_REPLICATE);  
 
	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);
	waitKey(0);
	return 0;
}
 

 

python代码:

def rotate_point(point1, point2, angle, height):
    """
    点point1绕点point2旋转angle后的点
    ======================================
    在平面坐标上,任意点P(x1,y1),绕一个坐标点Q(x2,y2)旋转θ角度后,新的坐标设为(x, y)的计算公式:
    x= (x1 - x2)*cos(θ) - (y1 - y2)*sin(θ) + x2 ;
    y= (x1 - x2)*sin(θ) + (y1 - y2)*cos(θ) + y2 ;
    ======================================
    将图像坐标(x,y)转换到平面坐标(x`,y`):
    x`=x
    y`=height-y
    :param point1:
    :param point2: base point (基点)
    :param angle: 旋转角度,正:表示逆时针,负:表示顺时针
    :param height:
    :return:
    """
    x1, y1 = point1
    x2, y2 = point2
    # 将图像坐标转换到平面坐标
    y1 = height - y1
    y2 = height - y2
    x = (x1 - x2) * np.cos(np.pi / 180.0 * angle) - (y1 - y2) * np.sin(np.pi / 180.0 * angle) + x2
    y = (x1 - x2) * np.sin(np.pi / 180.0 * angle) + (y1 - y2) * np.cos(np.pi / 180.0 * angle) + y2
    # 将平面坐标转换到图像坐标
    y = height - y
    return (x, y)

【尊重原创,转载请注明出处】https://panjinquan.blog.csdn.net/article/details/78288131

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI吃大瓜

尊重原创,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值