Ask Your Question
10

Extract a RotatedRect area

asked 2012-07-18 10:28:51 -0600

imran gravatar image

updated 2020-10-25 09:17:45 -0600

Can someone explain to me how you would extract a RotatedRect to a submatrix image. Basically, using something like cvSetImageROI to extract the inverted rectangular area from the image?

The Mat::operator()(const Rect& roi) only takes in a Rectangle not a RotatedRect.

rotated rect region

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
20

answered 2012-07-18 16:38:19 -0600

updated 2013-05-16 15:26:36 -0600

There's a great article by Felix Abecassis on rotating and deskewing images. This also shows you how to extract the data in the RotatedRect:

You basically only need cv::getRotationMatrix2D to get the rotation matrix for the affine transformation with cv::warpAffine and cv::getRectSubPix to crop the rotated image. The relevant lines in my application are:

        // rect is the RotatedRect (I got it from a contour...)
        RotatedRect rect;
        // matrices we'll use
        Mat M, rotated, cropped;
        // get angle and size from the bounding box
        float angle = rect.angle;
        Size rect_size = rect.size;
        // thanks to http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/
        if (rect.angle < -45.) {
            angle += 90.0;
            swap(rect_size.width, rect_size.height);
        }
        // get the rotation matrix
        M = getRotationMatrix2D(rect.center, angle, 1.0);
        // perform the affine transformation
        warpAffine(src, rotated, M, src.size(), INTER_CUBIC);
        // crop the resulting image
        getRectSubPix(rotated, rect_size, rect.center, cropped);

A simple trick to only rotate the content of the RotatedRect is to first get the ROI from the Bounding Box of the RotatedRect by using RotatedRect::boundingRect() and then perform the same as above, for cv::RotatedRect see:

edit flag offensive delete link more

Comments

@Philipp this is the perfect solution. Thanks so much!!!

imran gravatar imageimran ( 2012-07-18 17:20:20 -0600 )edit

Please see my updated answer, which explains how to only rotate the area of the RotatedRect.

Philipp Wagner gravatar imagePhilipp Wagner ( 2012-07-18 18:00:04 -0600 )edit
3

answered 2012-07-18 13:32:47 -0600

blue gravatar image

You could rotate the image first and then extract the rectangle, but if the rectangle is small compared to the full image it might be better tor use warpAffine.

Allocate the destination image with the size of the rectangle.

I think the affine transformation matrix is

T=[ 1 0 x0 ]
  [ 0 1 y0 ]
R=[ cos(theta) -sin(theta) 0 ]
  [ sin(theta)  cos(theta) 0 ]
  [      0           0     1 ]
M=T(x0,y0)*R(theta)
 =[ cos(theta) -sin(theta) x0 ]
  [ sin(theta)  cos(theta) y0 ]

Where x0,y0 is the coordinate of the upper-left corner of the rectangle and theta is the rotation angle. I haven't tested this, so there may be an error in this definition but it should be a good start.

edit flag offensive delete link more

Comments

@blue Thanks so much! The rectangle is small and I would've love to use warpAffine on the rectangle region alone (thus only rotating the pixels therein) but when I allocate the destination image with the size of the rectangle while using the upper-left point of the rectangle to create the transformation matrix then it would return the upper-left corner of the image (the area where the bubbles area). The way around this was to rotate the entire image according to the center of the rectangle and allocate the destination image with the size of the source image, then extracting an ROI of the rectangle region.

Thanks again for your help. I hope there is still some way to just rotate the rectangle region.

imran gravatar imageimran ( 2012-07-18 17:16:28 -0600 )edit

Find the BoundingBox of the RotatedRect, set the ROI to this Bounding Box and then rotate it as above.

Philipp Wagner gravatar imagePhilipp Wagner ( 2012-07-18 18:01:12 -0600 )edit

Question Tools

4 followers

Stats

Asked: 2012-07-18 10:28:51 -0600

Seen: 72,224 times

Last updated: May 16 '13