Rotate a point around a point with OpenCV

雨燕双飞 提交于 2019-11-28 20:38:06
Adrian

These are the steps needed to rotate a point around another point by an angle alpha:

  1. Translate the point by the negative of the pivot point
  2. Rotate the point using the standard equation for 2-d (or 3-d) rotation
  3. Translate back

The standard equation for rotation is:

x' = xcos(alpha) - ysin(alpha)

y' = xsin(alpha) + ycos(alpha)

Let's take the example of Point(15,5) around Point(2,2) by 45 degrees.

Firstly, translate:

v = (15,5) - (2,2) = (13,3)

Now rotate by 45°:

v = (13*cos 45° - 3*sin 45°, 13*sin 45° + 3*cos 45°) = (7.07.., 11.31..)

And finally, translate back:

v = v + (2,2) = (9.07.., 13.31..)

Note: Angles must be specified in radians, so multiply the number of degrees by Pi / 180

To rotate point p1 = (x1, y1) around p (x0, y0) by angle a:

x2 = ((x1 - x0) * cos(a)) - ((y1 - y0) * sin(a)) + x0;
y2 = ((x1 - x0) * sin(a)) + ((y1 - y0) * cos(a)) + y0;

where (x2, y2) is the new location of point p1

If you already have points in the form of RotatedRect, you can change the angle of it to rotate the points.

//RotatedRect myRect;
Point2f oldPoints[4];
myRect.points(oldPoints);  //gives existing points of the rectangle.
myRect.angle = 0;          //change the angle.
Point2f newPoints[4];
myRect.points(newPoints);  //gives rotated points of the rectangle.

This might help

cv::Point2f rotate2d(const cv::Point2f& inPoint, const double& angRad)
{
    cv::Point2f outPoint;
    //CW rotation
    outPoint.x = std::cos(angRad)*inPoint.x - std::sin(angRad)*inPoint.y;
    outPoint.y = std::sin(angRad)*inPoint.x + std::cos(angRad)*inPoint.y;
    return outPoint;
}

cv::Point2f rotatePoint(const cv::Point2f& inPoint, const cv::Point2f& center, const double& angRad)
{
    return rotate2d(inPoint - center, angRad) + center;
}

I was looking for the transformation of any pixel coordinate of an Image and I could hardly find that by googling it. Somehow I found one link of python code which work correctly and which helped me to understand the issue: https://cristianpb.github.io/blog/image-rotation-opencv

The following is the corresponding C++ code, if some one is looking for it:

// send the original angle and don't transform in radian
    cv::Point2f rotatePointUsingTransformationMat(const cv::Point2f& inPoint, const cv::Point2f& center, const double& rotAngle)
    {
        cv::Mat rot = cv::getRotationMatrix2D(center, rotAngle, 1.0);
        float cos = rot.at<double>(0,0);
        float sin = rot.at<double>(0,1);
        int newWidth = int( ((center.y*2)*sin) +  ((center.x*2)*cos) );
        int newHeight = int( ((center.y*2)*cos) +  ((center.x*2)*sin) );

        rot.at<double>(0,2) += newWidth/2.0 - center.x;
        rot.at<double>(1,2) += newHeight/2.0 - center.y;

        int v[3] = {static_cast<int>(inPoint.x),static_cast<int>(inPoint.y),1};
        int mat3[2][1] = {{0},{0}};

        for(int i=0; i<rot.rows; i++)
        {
            for(int j=0; j<= 0; j++)
            {
                int sum=0;
                for(int k=0; k<3; k++)
                {
                    sum = sum + rot.at<double>(i,k) * v[k];
                }
                mat3[i][j] = sum;
            }
        }
        return Point2f(mat3[0][0],mat3[1][0]);
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!