# Extract a RotatedRect area 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. edit retag close merge delete

Sort by » oldest newest most voted

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:

more

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

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

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.

more

@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.

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

Official site

GitHub

Wiki

Documentation