2

I am new in OpenCV so please to be lenient. I am doing an Android application to recognize the squares/rectangles and crop them. Function which looks for the squares/rectangles puts the found objects to vector> squares. I just wonder how to crop the picture according to the data in points stored in vector> squares and how to compute an angle on which the picture should be rotated. Thank you for any help

BenMorel
  • 34,448
  • 50
  • 182
  • 322
silvestrairwave
  • 173
  • 1
  • 1
  • 11

3 Answers3

2

This post is citing from OpenCV QA: Extract a RotatedRect area.

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:

// This is the RotatedRect, I got it from a contour for example...
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 on your image in src,
// the result is the rotated image in rotated. I am doing
// cubic interpolation here
warpAffine(src, rotated, M, src.size(), INTER_CUBIC);
// crop the resulting image, which is then given in cropped
getRectSubPix(rotated, rect_size, rect.center, cropped);
bytefish
  • 3,697
  • 1
  • 29
  • 35
  • 2
    Although the answer is almost valid, This rotates your *entire* image before cropping. *Highly* expensive operation there. – TimZaman May 21 '15 at 11:03
1

There are lots of useful posts around, I'm sure you can do a better search.

Crop:

Rotate:

Compute angle:

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • http://stackoverflow.com/questions/14756505/croping-an-image-in-ios-uisng-opencv-face-detect I am facing cropping problem in iphone live video stream.. Could you please have a look at my post.. – 2vision2 Feb 07 '13 at 19:32
0

Altought this question is quite old, I think there is the need for an answer that is not expensive as rotating the whole image (see @bytefish's answer). You will need a bounding rect, for some reason rotatedRect.boundingRect() didn't work for me, so I had to use Imgproc.boundingRect(contour). This is OpenCV for Android, the operations are almost the same for other environments:

Rect roi = Imgproc.boundingRect(contour);
// we only work with a submat, not the whole image:
Mat mat = image.submat(roi); 
RotatedRect rotatedRect = Imgproc.minAreaRect(new MatOfPoint2f(contour.toArray()));
Mat rot = Imgproc.getRotationMatrix2D(rotatedRect.center, rotatedRect.angle, 1.0);
// rotate using the center of the roi
double[] rot_0_2 = rot.get(0, 2);
for (int i = 0; i < rot_0_2.length; i++) {
    rot_0_2[i] += rotatedRect.size.width / 2 - rotatedRect.center.x;
}
rot.put(0, 2, rot_0_2);
double[] rot_1_2 = rot.get(1, 2);
for (int i = 0; i < rot_1_2.length; i++) {
    rot_1_2[i] += rotatedRect.size.height / 2 - rotatedRect.center.y;
}
rot.put(1, 2, rot_1_2);
// final rotated and cropped image:
Mat rotated = new Mat();
Imgproc.warpAffine(mat, rotated, rot, rotatedRect.size);
lmiguelmh
  • 3,074
  • 1
  • 37
  • 53