在C ++中使用OpenCV在倾斜线上方创建旋转的矩形

时间:2018-09-19 07:42:49

标签: c++ opencv

我正在尝试绘制随线的旋转而旋转的矩形(该矩形由四个点创建)

Basic rectangle

我使用矩形创建的图像中的白色叠加层。我想使其旋转并站在红色矩形上方。

这是我的红色矩形代码:

std::vector<cv::Point> imagePoints;
imagePoints.push_back(it->rect_tl());
imagePoints.push_back(it->rect_tr());
imagePoints.push_back(it->rect_br());
imagePoints.push_back(it->rect_bl());
imagePoints.push_back(it->rect_tl());
polylines(cam_view, imagePoints, false, Scalar(0, 0, 255), 2);

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我假设您已经指定了红色矩形。因此,我计算了红色矩形顶线的角度,并使用cv::RotatedRect函数创建了一个新的旋转矩形。

这是示例代码:

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

// Function to calculate the angle from 0 to 180° between two lines
float getClockwiseAngle0to180(cv::Point2f x_axis1, cv::Point2f x_axis2, cv::Point2f tl, cv::Point2f tr) {
    float dot = (x_axis2.x - x_axis1.x) * (tr.x - tl.x) + (tr.y - tl.y) * (x_axis2.y - x_axis1.y);
    float det = (x_axis2.x - x_axis1.x) * (tr.y - tl.y) - (x_axis2.y - x_axis1.y) * (tr.x - tl.x);

    float angle = atan2(det, dot);
    angle = angle * (180 / (float)CV_PI);
    if (angle < 0) {
        angle = angle + 360;
    }
    if (angle >= 180) {
        angle = angle - 180;
    }
    return angle;
}

int main(int argc, char** argv) {
    cv::Mat test_image(400, 400, CV_8UC3, cv::Scalar(0));

    // You created the red rectangle with some detection algorithm and it seems that
    // you already have topleft (tl), topright (tr)... coordinate of the red rectangle
    std::vector<cv::Point2f> red_rect_points;
    cv::Point2f tl(200.0, 200.0);
    cv::Point2f tr(300.0, 150.0);
    cv::Point2f br(350.0, 220.0);
    cv::Point2f bl(250.0, 300.0);
    red_rect_points.push_back(tl);
    red_rect_points.push_back(tr);
    red_rect_points.push_back(br);
    red_rect_points.push_back(bl);

    // Get the angle between the tl and tr point with the given function
    float rotation = getClockwiseAngle0to180(cv::Point2f(0, 0), cv::Point2f(1, 0), tr, tl);
    std::cout << rotation << std::endl;

    // Create a new white rectangle with the same rotation angle
    // Construct it using center, size and angle
    cv::RotatedRect white_rectangle(cv::Point2f(200, 150), cv::Size2f(80, 50), rotation);
    cv::Point2f white_vertices[4];
    white_rectangle.points(white_vertices);

    // Draw both rectangles
    for (int i = 0; i < 4; ++i) {
        line(test_image, red_rect_points[i], red_rect_points[(i+1)%4], cv::Scalar(0, 0, 255), 1, 8, 0);
        line(test_image, white_vertices[i], white_vertices[(i+1)%4], cv::Scalar(255, 255, 255), 1, 8, 0);
    }

    cv::imshow("Rectangles", test_image);
    cv::waitKey(0);

}