简体   繁体   English

在OpenCV中旋转旋转图像的后点

[英]Rotating back points from a rotated image in OpenCV

I'm having troubles with rotation. 我有轮换麻烦。 What I want to do is this: 我想要做的是:

  • Rotate an image 旋转图像
  • Detect features on the rotated image (points) 检测旋转图像上的特征(点)
  • Rotate back the points so I can have the points coordinates corresponding to the initial image 向后旋转点,使得我可以得到与初始图像对应的点坐标

I'm a bit stuck on the third step. 我有点卡在第三步。

I manage to rotated the image with the following code: 我设法使用以下代码旋转图像:

cv::Mat M(2, 3, CV_32FC1);
cv::Point2f center((float)dst_img.rows / 2.0f, (float)dst_img.cols / 2.0f);
M = cv::getRotationMatrix2D(center, rotateAngle, 1.0);
cv::warpAffine(dst_img, rotated, M, cv::Size(rotated.cols, rotated.rows));

I try to rotate back the points with this code: 我尝试用这段代码回转点:

float xp = r.x * std::cos( PI * (-rotateAngle) / 180 ) - r.y * sin(PI * (rotateAngle) / 180);
float yp = r.x * sin(PI * (-rotateAngle) / 180) + r.y * cos(PI * (rotateAngle) / 180);

It is not to fare to be working but the points don't go back well on the image. 这不是为了工作,但这些点在图像上不能很好地回归。 There is an offset. 有一个偏移。

Thank you for your help 谢谢您的帮助

If M is the rotation matrix you get from cv::getRotationMatrix2D , to rotate a cv::Point p with this matrix you can do this: 如果M是从cv::getRotationMatrix2D获得的旋转矩阵,要使用此矩阵旋转cv::Point p ,您可以执行以下操作:

cv::Point result;
result.x = M.at<double>(0,0)*p.x + M.at<double>(0,1)*p.y + M.at<double>(0,2);
result.y = M.at<double>(1,0)*p.x + M.at<double>(1,1)*p.y + M.at<double>(1,2);

If you want to rotate a point back, generate the inverse matrix of M or use cv::getRotationMatrix2D(center, -rotateAngle, scale) to generate a matrix for reverse rotation. 如果要将点旋转回来,则生成M的逆矩阵或使用cv::getRotationMatrix2D(center, -rotateAngle, scale)生成反向旋转矩阵。

For a rotation matrix, its transpose is its inverse. 对于旋转矩阵,其转置是反向的。 So you can just do Mt() * r to move it back to your original frame, where r is a cv::Mat (you might have to convert it to a cv::Mat from a cv::Point2f or whatever, or just write out the matrix multiplication explicitly). 所以你可以把Mt() * r移回原来的框架,其中rcv::Mat (你可能需要将它转换为cv::Mat来自cv::Point2f或其他什么,或者只是明确地写出矩阵乘法)。

Here's the code to do it explicitly (should be correct, but warning, it's entirely untested): 这是明确执行它的代码(应该是正确的,但警告,它完全未经测试):

cv::Point2f p;
p.x = M.at<float>(0, 0) * r.x + M.at<float>(1, 0) * r.y;
p.y = M.at<float>(0, 1) * r.x + M.at<float>(1, 1) * r.y;
// p contains r rotated back to the original frame.

I had the same problem. 我有同样的问题。

For a transform M and point pp in the rotated image, we wish to find the point pp_org in the coordanates of the original image. 对于旋转图像中的变换M和点pp ,我们希望在原始图像的pp_org中找到点pp_org Use the following lines: 使用以下行:

cv::Mat_<double> iM;
cv::invertAffineTransform(M, iM);
cv::Point2f pp_org = iM*pp;

Where the operator * in the above line is defined as: 上述行中的运算符*定义为:

cv::Point2f operator*(cv::Mat_<double> M, const cv::Point2f& p)
{ 
    cv::Mat_<double> src(3/*rows*/,1 /* cols */); 

    src(0,0)=p.x; 
    src(1,0)=p.y; 
    src(2,0)=1.0; 

    cv::Mat_<double> dst = M*src; //USE MATRIX ALGEBRA 
    return cv::Point2f(dst(0,0),dst(1,0)); 
} 

Note: M is the rotation matrix you used to go from the original to the rotated image 注意: M是您用于从原始图像到旋转图像的旋转矩阵

  • You need to rotate your points accorning to center point of your image. 您需要根据图像的中心点旋转点数。
  • Here x and y are your points which you want to rotate, imageCenter_x aand _y is center point of your image. 这里x和y是你想要旋转的点,imageCenter_x a和_y是你图像的中心点。
  • Below is my code. 以下是我的代码。

     angle = angle * (M_PI / 180); float axis_x = x - imageCenter_x; float axis_y = y - imageCenter_y; x = axis_x * cos(angle) + axis_y * sin(angle); y = (-axis_x) * sin(angle) + axis_y * cos(angle); x = x + imageCenter_x; y = y + imageCenter_y; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM