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 */
}
These are the steps needed to rotate a point around another point by an angle alpha:
- Translate the point by the negative of the pivot point
- Rotate the point using the standard equation for 2-d (or 3-d) rotation
- 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]);
}
来源:https://stackoverflow.com/questions/7953316/rotate-a-point-around-a-point-with-opencv