Вращение точек назад от повернутого изображения в OpenCV - PullRequest
12 голосов
/ 29 июля 2011

У меня проблемы с вращением.Я хочу сделать следующее:

  • Повернуть изображение
  • Определить объекты на повернутом изображении (точки)
  • Повернуть точки назад, чтобы получитькоординаты точек, соответствующие исходному изображению

Я немного застрял на третьем шаге.

Мне удается повернуть изображение с помощью следующего кода:

cv::Mat M(2, 3, CV_32FC1);
cv::Point2f center((float)dst_img.rows / 2.0f, (float)dst_img.cols / 2.0f);
M = cv::getRotationMatrix2D(center, rotateAngle, 1.0);
cv::warpAffine(dst_img, rotated, M, cv::Size(rotated.cols, rotated.rows));

Я пытаюсь повернуть точки назад с помощью этого кода:

float xp = r.x * std::cos( PI * (-rotateAngle) / 180 ) - r.y * sin(PI * (rotateAngle) / 180);
float yp = r.x * sin(PI * (-rotateAngle) / 180) + r.y * cos(PI * (rotateAngle) / 180);

Работать не стоит, но точки на изображении плохо восстанавливаются.Есть смещение.

Спасибо за помощь

Ответы [ 4 ]

6 голосов
/ 12 апреля 2013

Если M - это матрица вращения, полученная из cv::getRotationMatrix2D, чтобы повернуть cv::Point p с этой матрицей, вы можете сделать это:

cv::Point result;
result.x = M.at<double>(0,0)*p.x + M.at<double>(0,1)*p.y + M.at<double>(0,2);
result.y = M.at<double>(1,0)*p.x + M.at<double>(1,1)*p.y + M.at<double>(1,2);

Если вы хотите повернуть точку назад,сгенерируйте обратную матрицу M или используйте cv::getRotationMatrix2D(center, -rotateAngle, scale), чтобы сгенерировать матрицу для обратного вращения.

3 голосов
/ 29 июля 2011

Для матрицы вращения ее транспонирование является обратным.Таким образом, вы можете просто сделать M.t() * r, чтобы переместить его обратно в исходный кадр, где r - это cv::Mat (вам, возможно, придется преобразовать его в cv::Mat из cv::Point2f или что-либо еще, или просто выписатьматричное умножение явно).

Вот код, чтобы сделать это явно (должен быть правильным, но предупреждение, это полностью не проверено):

cv::Point2f p;
p.x = M.at<float>(0, 0) * r.x + M.at<float>(1, 0) * r.y;
p.y = M.at<float>(0, 1) * r.x + M.at<float>(1, 1) * r.y;
// p contains r rotated back to the original frame.
1 голос
/ 20 апреля 2015

У меня была такая же проблема.

Для преобразования M и точки pp на повернутом изображении мы хотим найти точку pp_org в координатах исходного изображения. Используйте следующие строки:

cv::Mat_<double> iM;
cv::invertAffineTransform(M, iM);
cv::Point2f pp_org = iM*pp;

Где оператор * в приведенной выше строке определяется как:

cv::Point2f operator*(cv::Mat_<double> M, const cv::Point2f& p)
{ 
    cv::Mat_<double> src(3/*rows*/,1 /* cols */); 

    src(0,0)=p.x; 
    src(1,0)=p.y; 
    src(2,0)=1.0; 

    cv::Mat_<double> dst = M*src; //USE MATRIX ALGEBRA 
    return cv::Point2f(dst(0,0),dst(1,0)); 
} 

Примечание: M - это матрица вращения, которую вы использовали для перехода от оригинала к повернутому изображению

0 голосов
/ 19 декабря 2015
  • Вам необходимо повернуть свои точки в соответствии с центральной точкой вашего изображения.
  • Здесь x и y - ваши точки, которые вы хотите повернуть, imageCenter_x a и _y - центральная точка вашего изображения.
  • Ниже мой код.

    angle = angle * (M_PI / 180);  
    float axis_x = x - imageCenter_x;  
    float axis_y = y - imageCenter_y;       
    
    x = axis_x * cos(angle) + axis_y * sin(angle);   
    y = (-axis_x) * sin(angle) + axis_y * cos(angle);
    
    x = x + imageCenter_x;  
    y = y + imageCenter_y;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...