簡體   English   中英

用 OpenCV 圍繞一個點旋轉一個點

[英]Rotate a point around a point with OpenCV

有誰知道如何在 OpenCV 中圍繞另一個點旋轉一個點?

我正在尋找這樣的 function:

Point2f rotatePoint(Point2f p1, Point2f center, float angle)
{
    /* MAGIC */
}

這些是圍繞另一個點旋轉角度α所需的步驟:

  1. 通過樞軸點的負數轉換點
  2. 使用標准公式旋轉該點以進行2-d(或3-d)旋轉
  3. 翻譯回來

輪換的標准方程是:

x'= x cos(alpha) - y sin(alpha)

y'= x sin(alpha)+ y cos(alpha)

讓我們以Point(2,2)為中心點(15,5)45度的例子。

首先,翻譯:

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

現在旋轉45°:

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

最后,翻譯回來:

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

注意:角度必須以弧度指定,因此將度數乘以Pi / 180

要使點p1 = (x1, y1)p (x0, y0)旋轉角度a

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

其中(x2, y2)是點p1的新位置

這可能有所幫助

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;
}

如果您已經有RotatedRect形式的 ,您可以更改它的角度來旋轉點。

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

我正在尋找圖像的任何像素坐標的轉換,我很難通過谷歌搜索找到它。 不知何故,我發現一個python代碼鏈接正常工作,這有助於我理解這個問題: https//cristianpb.github.io/blog/image-rotation-opencv

以下是相應的C ++代碼,如果有人正在尋找它:

// 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]);
    }

通過示意圖擴展razz答案,以了解旋轉角度的方向:

/**
 * @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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM