Вопрос:

Перемещение cv :: RotatedRect в том же положении после вращения cv :: Mat без обрезки

c++ opencv

31 просмотра

1 ответ

902 Репутация автора

В настоящее время я не могу понять, что необходимо преобразовать cv::RotatedRectпосле поворота изображения без обрезки, используя следующий код Ларса Шиллингмана в этом вопросе .

Вот код, который он предоставил как ответ:

#include "opencv2/opencv.hpp"

int main()
{
    cv::Mat src = cv::imread("im.png", CV_LOAD_IMAGE_UNCHANGED);
    double angle = -45;

    // get rotation matrix for rotating the image around its center in pixel coordinates
    cv::Point2f center((src.cols-1)/2.0, (src.rows-1)/2.0);
    cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
    // determine bounding rectangle, center not relevant
    cv::Rect2f bbox = cv::RotatedRect(cv::Point2f(), src.size(), angle).boundingRect2f();
    // adjust transformation matrix
    rot.at<double>(0,2) += bbox.width/2.0 - src.cols/2.0;
    rot.at<double>(1,2) += bbox.height/2.0 - src.rows/2.0;

    cv::Mat dst;
    cv::warpAffine(src, dst, rot, bbox.size());
    cv::imwrite("rotated_im.png", dst);

    return 0;
}

В моем случае, я, cv::RotatedRectкоторый соответствует определенной позиции на srcизображении. Это cv::RotatedRectдолжно соответствовать тому же положению после того, как преобразование / вращение было применено к srcмату. В настоящее время я борюсь с этим правильно.

Из того, что я знаю, чтобы повернуть cv::RotatedRect, необходимо только напрямую изменить элементы структуры, например angle. Я совершенно уверен, что мне нужно только изменить центр, но новая позиция всегда немного отличается от ожидаемой. Первоначально я ожидал , что я только добавить разницу между bboxи srcразмерами , чтобы получить то , что я ищу , но это оказывается не так (inlcuding вращения конечно).

connected_components[i].center.x += ...
connected_components[i].center.y += ...
cv::RotatedRect newRect(connected_components[i].center, connected_components[i].size, connected_components[i].angle- median);
Автор: Bastian Источник Размещён: 10.08.2019 11:23

Ответы (1)


0 плюса

902 Репутация автора

Ответ довольно прост. Мы можем повторно использовать матрицу преобразования для точечного преобразования, используя cv::transform. Пример кода ниже:

cv::Point2f points[4];
        connected_components[i].points(points);
        std::vector<cv::Point2f> old_points;
        old_points.insert(old_points.begin(), std::begin(points), std::end(points));
        std::vector<cv::Point2f> new_points;
        cv::transform(old_points, new_points, rotation_matrix);
        for (unsigned int j = 0; j < 4; ++j) {
            cv::line(dest, new_points[j], new_points[(j + 1) % 4], cv::Scalar(0, 255, 0));
        }
Автор: Bastian Размещён: 11.08.2019 08:59
Вопросы из категории :
32x32