Вращение обратных точек с повернутого изображения в OpenCV
У меня возникают проблемы с вращением.
Я хочу сделать следующее:
- Поворот изображения
- Обнаружение функций на повернутом изображении (точках)
- Поверните назад точки, чтобы я мог иметь координаты точек, соответствующие исходному изображению
Я немного застрял на третьем шаге.
Мне удалось повернуть изображение с помощью следующего кода:
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);
Это не значит, что вы работаете, но точки не возвращаются на изображение. Существует смещение.
Спасибо за помощь
Ответы
Ответ 1
Если M
- матрица вращения, которую вы получаете от cv::getRotationMatrix2D
, чтобы повернуть a 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)
для создания матрицы для обратного вращения.
Ответ 2
Для матрицы вращения ее транспонирование является ее обратной. Таким образом, вы можете просто сделать 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.
Ответ 3
У меня была та же проблема.
Для преобразования 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
- это матрица вращения, которую вы использовали для перехода от оригинала к повернутому изображению.
Ответ 4