Rotate a point around a point with OpenCV
Asked Answered
G

6

20

Does anyone know how I can rotate a point around another in OpenCV?

I am looking for a function like this:

Point2f rotatePoint(Point2f p1, Point2f center, float angle)
{
    /* MAGIC */
}
Germanium answered 31/10, 2011 at 11:52 Comment(0)
F
34

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

Fugacity answered 31/10, 2011 at 12:48 Comment(2)
Welcome to Stack Overflow. If an answer solves your problem you should accept it. Please read about accepting answers.Publishing
+1 for a good answer, though I'd avoid using 45° as a test case as the sine and cosine are the same.Substandard
I
15

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

Illmannered answered 22/8, 2015 at 23:21 Comment(0)
S
5

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;
}
Seemaseeming answered 19/4, 2015 at 13:58 Comment(0)
T
2

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.
Toadinthehole answered 28/7, 2014 at 6:21 Comment(0)
A
1

Extension to razz's answer with a schematic to give an idea about the direction of a rotation angle:

/**
 * @brief rotate a point wrt a reference point by a given degree angle on an image
 * @param given_pt a point to be rotated
 * @param ref_pt a reference point wrt which the given_pt will be rotated
 * @param rotation_angle_deg rotation angle in degrees
 * @return rotated point
 *
 * .------------------------------------.
 * |            * -------.          img |
 * |    rotated_pt    -90 \             |
 * |                       \            |
 * |                        \           |
 * |            * ---------> *          |
 * |         ref_pt     given_pt        |
 * |                       /            |
 * |                      /             |
 * |    rotated_pt   +90 /              |
 * |            * ------'               |
 * '------------------------------------'
 */
cv::Point rotatePointOnImage(const cv::Point& given_pt, const cv::Point& ref_pt, const double& angle_deg) {
    double    rotation_angle = angle_deg * M_PI / 180.0;
    cv::Point rotated_pt;

    rotated_pt.x = (given_pt.x - ref_pt.x) * cos(rotation_angle) - (given_pt.y - ref_pt.y) * sin(rotation_angle) + ref_pt.x;
    rotated_pt.y = (given_pt.x - ref_pt.x) * sin(rotation_angle) + (given_pt.y - ref_pt.y) * cos(rotation_angle) + ref_pt.y;

    return rotated_pt;
}
Aftereffect answered 7/6, 2022 at 20:8 Comment(0)
M
0

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]);
    }
Medarda answered 23/12, 2017 at 21:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.