Rotating back points from a rotated image in OpenCV

前端 未结 4 813
攒了一身酷
攒了一身酷 2020-12-17 16:43

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 p
相关标签:
4条回答
  • 2020-12-17 17:05

    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. 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

    0 讨论(0)
  • 2020-12-17 17:12
    • 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.
    • 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;
      
    0 讨论(0)
  • 2020-12-17 17:15

    For a rotation matrix, its transpose is its inverse. So you can just do M.t() * 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).

    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.
    
    0 讨论(0)
  • 2020-12-17 17:21

    If M is the rotation matrix you get from cv::getRotationMatrix2D, to rotate a cv::Point p with this matrix you can do this:

    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.

    0 讨论(0)
提交回复
热议问题