目录
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);
}
某点绕中心点旋转后的坐标:
- 二维平面里(原点在左下角),任一点orig_xy绕着center_xy逆时针旋转theta角度,返回新的坐标(x,y)
- 图像坐标系(原点在左上角),图像上任一点orig_xy绕着center_xy逆时针旋转theta角度,返回新的图像坐标(x,y)