Ask Your Question
0

rotate RotatedRect

asked 2016-04-04 07:21:02 -0500

Nbb gravatar image

updated 2016-04-04 13:35:13 -0500

EDIT : I found http://answers.opencv.org/question/36... which I am going to try tomorrow. I have tried it and it looks like it works for the example below. Going to try it on other images.

Hello,

I have a rotatedRect at 30 degrees as shown in the image below. image description

How do I 'unrotate' the rect and draw it like in the figure below ? I tried rotatedRect.angle = rotatedRect.angle - 30 before drawing it but the box drawn seems way off especially if the box is smaller and far from the center of the image.

PS: I do not want to rotate the frame. I just want to rotate the rectangle

image description

It gives me something like this EXAMPLE Below is my code. Someone please offer some suggestion. This is my algo

1) Rotate image by 30 degrees using getRotationMatrix2D(Point2f(src.cols / 2, src.rows / 2), 30, 1);

2) Find rotatedRect

3) Rotate rotatedRect by -30 degrees

4) Draw on original frame

image description

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);

Mat rotMat, rotatedFrame;
Point center;

/// Function header
void thresh_callback(int, void*);

/** @function main */
int main(int argc, char** argv)
{
    /// Load source image and convert it to gray
    src = imread("test.jpg");

    center = Point(src.cols / 2, src.rows / 2);
    rotMat = getRotationMatrix2D(Point2f(src.cols / 2, src.rows / 2), 30, 1);

    warpAffine(src, rotatedFrame, rotMat, src.size(), INTER_CUBIC);

    /// Convert image to gray and blur it
    cvtColor(rotatedFrame, src_gray, CV_BGR2GRAY);
    blur(src_gray, src_gray, Size(3, 3));

    /// Create Window
    char* source_window = "Source";
    namedWindow(source_window, CV_WINDOW_AUTOSIZE);
    imshow(source_window, src);

    createTrackbar(" Threshold:", "Source", &thresh, max_thresh, thresh_callback);
    thresh_callback(0, 0);

    waitKey(0);
    return(0);
}

/** @function thresh_callback */
void thresh_callback(int, void*)
{
    Mat threshold_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    /// Detect edges using Threshold
    threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY);
    /// Find contours
    findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    /// Find the rotated rectangles and ellipses for each contour
    vector<RotatedRect> minRect(contours.size());
    vector<RotatedRect> minEllipse(contours.size());

    for (int i = 0; i < contours.size(); i++)
    {
        minRect[i] = minAreaRect(Mat(contours[i]));
        if (contours[i].size() > 5)
        {
            minEllipse[i] = fitEllipse(Mat(contours[i]));
        }
    }

    /// Draw contours + rotated rects + ellipses
    Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
    for (int i = 0; i< contours.size(); i++)
    {
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));


        Point2f rect_points[4]; 
        minRect[i].points(rect_points);
        for (int j = 0; j < 4; j++)
            line(rotatedFrame, rect_points[j], rect_points[(j + 1) % 4], color, 1, 8);

        float angle = 30 * (3.142 / 180);
        for (int j = 0; j < 4; j++)
        {
            rect_points[j].x = ((rect_points[j].x - center.x) * cos(angle)) - ((rect_points[j].y - center.y) * sin(angle)) + center.x;
            rect_points[j].y = ((rect_points[j].x - center.x) * sin(angle)) + ((rect_points[j].y - center.y) * cos(angle)) + center.y;

        }

        for (int j = 0; j < 4; j++)
            line(src, rect_points[j ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-04-04 07:28:59 -0500

Use the warpAffine method:

cv::Mat rotation = cv::getRotationMatrix2D(rotatedRect.center, -rotatedRect.angle, 1);
cv::warpAffine(src, dst, rotation, dst.size());
edit flag offensive delete link more

Comments

Hello sorry I just want to rotate the rotatedRect i.e. its parameters

Nbb gravatar imageNbb ( 2016-04-04 11:44:09 -0500 )edit

Hello sorry I just want to rotate the rotatedRect i.e. its parameters. I do not want to rotate the image. I will rotated the rect then draw it on the original frame i.e. the unrotated frame

Nbb gravatar imageNbb ( 2016-04-04 11:44:31 -0500 )edit

But then you can still use warpaffine, to warp only the corner points to a new set of points and then draw a rectangle between those!

StevenPuttemans gravatar imageStevenPuttemans ( 2016-04-05 07:13:26 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2016-04-04 07:21:02 -0500

Seen: 3,901 times

Last updated: Apr 04 '16