Ask Your Question
4

Extract a RotatedRect area

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

imran gravatar image imran
423 3 5 17

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

delete close flag offensive retag edit

2 Answers

Sort by ยป oldest newest most voted
13

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

Philipp Wagner gravatar image Philipp Wagner flag of Germany
1601 2 15 23
http://www.bytefish.de/

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:

link delete flag offensive edit

Comments

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

imran ( 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 ( 2012-07-18 18:00:04 -0600 )edit
3

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

blue gravatar image blue
201 4

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.

link delete flag offensive edit

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 ( 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 ( 2012-07-18 18:01:12 -0600 )edit

Login/Signup to Answer

Question tools

Follow
3 followers

subscribe to rss feed

Stats

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

Seen: 9,031 times

Last updated: May 16 '13