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 */
}
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:
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
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;
}
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.
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;
}
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]);
}
© 2022 - 2024 — McMap. All rights reserved.