cv2函数原型-图像变换(旋转变换详解/计算旋转坐标/Python和C++实现)

目录

warpAffine

Python

C++

计算旋转后的矩形框Rect坐标

Python

C++


warpAffine

Python
import numpy as np
import cv2

img = cv2.imread('data/root/images/apple.jpg')
height, width = img.shape[:2]
center = (width / 2, height / 2)
# using cv2.getRotationMatrix2D() to get the rotation matrix
rotate_matrix = cv2.getRotationMatrix2D(center=center, angle=45, scale=1)
# rotate the image using cv2.warpAffine 45 degree anticlockwise(逆时针45度)
rotated_image = cv2.warpAffine(src=img, M=rotate_matrix, dsize=(width, height))
cv2.imwrite('data/root/images/apple_rotated.jpg', rotated_image)

当angle为正,绕center点逆时针旋转图像

angle属于(0,90],为x轴(矩形最低点) 顺时针 旋转的角度

C++
cv::Mat img_rot;
// 
cv::Point2f center(patches[i].cols / 2, patches[i].rows / 2);
cv::Mat rotation_matrix = cv::getRotationMatrix2D(center, m_rot_angle, 1.0);
//cv::Size dst_sz(patches[i].cols * cos(m_rot_angle) + patches[i].rows * sin(m_rot_angle), 
//				patches[i].cols * sin(m_rot_angle) + patches[i].rows * cos(m_rot_angle));
cv::warpAffine(patches[i], img_rot, rotation_matrix, patches[i].size(), 1, 0, cv::Scalar(114, 114, 114));

当angle为正,图像绕center点逆时针旋转

坐标系不变,原点仍然为(0,0)

旋转完之后再裁剪或填充成dsize大小的结果图

计算旋转后的矩形框Rect坐标

Python
# todo...

C++
cv::Point2f get_rotate_coords(const cv::Point2f orig_xy, const cv::Point2f center_xy, float theta) {
	// 二维平面里(原点在左下角),任一点orig_xy绕着center_xy逆时针旋转theta角度,返回新的坐标(x,y)
	float cos_th = cos(theta * 3.1415926 / 180.0), sin_th = sin(theta * 3.1415926 / 180.0);
	float x = (orig_xy.x - center_xy.x) * cos_th - (orig_xy.y - center_xy.y) * sin_th + center_xy.x;
	float y = (orig_xy.x - center_xy.x) * sin_th + (orig_xy.y - center_xy.y) * cos_th + center_xy.y;
	return cv::Point2f(x, y);
}

cv::Point2f get_rotate_coords_image(float imgH, const cv::Point2f orig_xy, const cv::Point2f center_xy, float theta) {
	// 图像坐标系(原点在左上角),图像上任一点orig_xy绕着center_xy逆时针旋转theta角度,返回新的图像坐标(x,y)
	cv::Point2f dst = get_rotate_coords(cv::Point2f(orig_xy.x, imgH - orig_xy.y), cv::Point2f(center_xy.x, imgH - center_xy.y), theta);
	dst.y = imgH - dst.y;
	return dst;
}

cv::Rect get_rotate_rectangle_image(float imgH, const cv::Rect rect, const cv::Point2f center_xy, float theta) {
	// rectangle的四个角点全部旋转,再取最小外接矩形框,可能为负数或超出原始图像范围!!!
	cv::Point2f src_xy0(rect.x, rect.y), src_xy1(rect.x + rect.width, rect.y), 
		src_xy2(rect.x + rect.width, rect.y + rect.height), 
		src_xy3(rect.x, rect.y + rect.height);
	cv::Point2f dst_xy0 = get_rotate_coords_image(imgH, src_xy0, center_xy, theta);
	cv::Point2f dst_xy1 = get_rotate_coords_image(imgH, src_xy1, center_xy, theta);
	cv::Point2f dst_xy2 = get_rotate_coords_image(imgH, src_xy2, center_xy, theta);
	cv::Point2f dst_xy3 = get_rotate_coords_image(imgH, src_xy3, center_xy, theta);
	int xmin = min(min(min(dst_xy0.x, dst_xy1.x), dst_xy2.x), dst_xy3.x) + 0.5, 
		ymin = min(min(min(dst_xy0.y, dst_xy1.y), dst_xy2.y), dst_xy3.y) + 0.5,
		xmax = max(max(max(dst_xy0.x, dst_xy1.x), dst_xy2.x), dst_xy3.x) + 0.5, 
		ymax = max(max(max(dst_xy0.y, dst_xy1.y), dst_xy2.y), dst_xy3.y) + 0.5;
	//cout << "imgH=" << imgH << ", center_xy=" << center_xy.x << "," << center_xy.y << endl;
	return cv::Rect(xmin, ymin, xmax-xmin, ymax-ymin);
}

某点绕中心点旋转后的坐标:

  1. 二维平面里(原点在左下角),任一点orig_xy绕着center_xy逆时针旋转theta角度,返回新的坐标(x,y)
  2. 图像坐标系(原点在左上角),图像上任一点orig_xy绕着center_xy逆时针旋转theta角度,返回新的图像坐标(x,y)

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值