Повернуть точку вокруг точки с помощью OpenCV - PullRequest
16 голосов
/ 31 октября 2011

Кто-нибудь знает, как я могу повернуть точку вокруг другой в OpenCV?

Я ищу такую ​​функцию:

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

Ответы [ 5 ]

30 голосов
/ 31 октября 2011

Это шаги, необходимые для поворота точки вокруг другой точки на угол альфа:

  1. Перевести точку на отрицательную точку опоры
  2. Поворот точки с использованием стандартного уравнения для 2-го (или 3-го) вращения
  3. Перевести обратно

Стандартное уравнение вращения:

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

y '= x sin (альфа) + y cos (альфа) * ​​1019 *

Давайте возьмем пример точки (15,5) вокруг точки (2,2) на 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

7 голосов
/ 23 августа 2015

Для поворота точки 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

2 голосов
/ 19 апреля 2015

Это может помочь

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;
}
2 голосов
/ 28 июля 2014

Если у вас уже есть точки в виде 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.
1 голос
/ 24 декабря 2017

Я искал преобразование любой пиксельной координаты изображения, и я едва мог найти это, прибегая к помощи Google. Каким-то образом я нашел одну ссылку кода 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]);
    }
...