8

我有一个图像,我在图像上放置了一个矩形。然后我旋转图像。如何获得旋转图像上矩形的中心?

或者我可以以某种方式旋转一个矩形来放置旋转的图像吗?我认为在这种情况下,旋转必须沿着与用于旋转图像的点相同的点进行。

这是上面放置一个矩形的图像。

在此处输入图像描述

这是旋转后的图像。

在此处输入图像描述

这是我用来旋转图像的代码:

cv::Mat frame, frameRotated;
frame = cv::imread("lena.png");

cv::Rect rect(225,250,150,150);
cv::rectangle(frame, rect, cv::Scalar(0,0,255),2);

int theta = 30;
double radians = theta * PI / 180.0;            

double sin = abs(std::sin(radians));
double cos = abs(std::cos(radians));

int newWidth = (int) (frame.cols * cos + frame.rows * sin);
int newHeight = (int) (frame.cols * sin + frame.rows * cos);

cv::Mat targetMat(cv::Size(newWidth, newHeight), frame.type());

int offsetX = (newWidth - frame.cols) / 2;
int offsetY = (newHeight - frame.rows) / 2;

frame.copyTo(targetMat.rowRange(offsetY, offsetY + frame.rows).colRange(offsetX, offsetX + frame.cols));

cv::Point2f src_center(targetMat.cols/2.0F, targetMat.rows/2.0F);
cv::Mat rot_mat = cv::getRotationMatrix2D(src_center, theta, 1.0);
cv::warpAffine(targetMat, frameRotated, rot_mat, targetMat.size());

imshow("frame", frame); 
imshow("rotated frame", frameRotated);  

编辑

假设我在旋转图像中有一个点,如何使用旋转矩阵在原始图像中获取对应点?

4

3 回答 3

2

您只需要使用 rot_mat 来变换矩形的原始中心。我测试了以下,它的工作原理:

cv::Rect r(250, 350, 20, 30);
cv::Point2d c(r.x + r.width / 2, r.y + r.height / 2);
// c is center of rect

// get c's location in targetMat when frame is copied
c.x += offsetX;  
c.y += offsetY;


int theta = 30;
double radians = theta * M_PI / 180.0;            

cv::Point2d src_center(targetMat.cols/2.0F, targetMat.rows/2.0F);
cv::Mat rot_mat = cv::getRotationMatrix2D(src_center, theta, 1.0);

// now transform point using rot_mat
double *x = rot_mat.ptr<double>(0);
double *y = rot_mat.ptr<double>(1);
Point2d dst(x[0] * c.x + x[1] * c.y + x[2], 
            y[0] * c.x + y[1] * c.y + y[2]);
// dst is center of transformed rect

编辑

要从旋转图像转换一个点,您只需要反转该过程:

// undo translation
Point2d dst1(dst.x - x[2], dst.y - y[2]); 

// undo rotation
Point2d dst2(x[0] * dst1.x - x[1] * dst1.y, -y[0] * dst1.x + y[1] * dst1.y); 

// undo shift
Point2d in_unrotated_image(dst2.x - offsetX, dst2.y - offsetY); 
于 2013-11-06T01:13:00.303 回答
1

您可以通过乘以旋转矩阵将源 Mat 中的任何点转换为旋转的 Mat。

如果你需要翻译 X,Y 并且给定 T=1,你可以通过 Mat 乘法来做到这一点

 |  cosθ  sinθ  Tx |   | X |    | _X |
 |                 | * | Y |  = |    |
 | -sinθ  cosθ  Ty |   | 1 |    | _Y |

其中 Tx 和 Ty 是沿 x 和 y 的翻译,请参见 OpenCV Doc

假设您需要在旋转后的 Mat 中找到源 Mat 的中心 (cent_x,cent_y)

Mat rot_mat = getRotationMatrix2D(src_center, theta, 1.0); //Find the rotation matrix 
Mat co_Ordinate = (Mat_<double>(3,1) << cent_x,cent_y,1); //Create 3x1 matrix with input co-ordinates.

Mat rst=rot_mat*co_Ordinate; // Multiply rotation matrix with input co-ordinate matrix
trans_x=(int)rst.at<double>(0,0); //First row of result will be x
trans_y=(int)rst.at<double>(1,0); //Second row of result will be y.

希望这些有帮助....

于 2013-11-08T10:30:36.203 回答
0

我已经解决了第二个问题的问题。

我使用了接受的答案中提供的相同代码,并创建了带有减 theta 的旋转矩阵。

于 2013-11-06T12:00:03.813 回答