I will need to identify, rotate and crop a rectangle(business card) from a photo took from an iphone. I believe this can be done by using OpenCV, but I have not used it before. Could anyone give some tips on this?
6 Answers
From iOS 8, you can now use the new detector CIDetectorTypeRectangle that returns CIRectangleFeature. You can add options :
- Accuracy : low/hight
Aspect ratio : 1.0 if you want to find only squares for example
CIImage *image = // your image NSDictionary *options = @{CIDetectorAccuracy: CIDetectorAccuracyHigh, CIDetectorAspectRatio: @(1.0)}; CIDetector *rectangleDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle context:nil options:options]; NSArray *rectangleFeatures = [rectangleDetector featuresInImage:image]; for (CIRectangleFeature *rectangleFeature in rectangleFeatures) { CGPoint topLeft = rectangleFeature.topLeft; CGPoint topRight = rectangleFeature.topRight; CGPoint bottomLeft = rectangleFeature.bottomLeft; CGPoint bottomRight = rectangleFeature.bottomRight; }
More information in WWDC 2014 Advances in Core Image, Session 514.
See opencv sample code OpenCV2.2\samples\cpp\squares.cpp
. They do the following:
Detect edges using Canny
Retrieve contours by
findContours
For each contour
approximate contour using
approxPolyDP
to decrease number of verticesif contour has 4 vertices and each angle is ~90 degrees then yield a rectangle

- 7,454
- 1
- 20
- 37
-
What I don't understand is, if in some places the background can be near the foreground color, how can I still find the edge given the information that the original image is a rectangle. – TiansHUo May 26 '11 at 06:53
-
It's an interesting question. It seems that no universal solution exists. First that comes to my mind: if you have some apriory information about target object (e.g. color histogram or texture features) then you can locate an image region that contains the target with high probability and set bounding contour as initial guess, after that apply active contour method to improve the result – Andrey Sboev May 26 '11 at 07:53
To get you started, you should look at the feature detection api of OpenCV. Especially
cv::Canny
(for edge detection),- maybe
cv::cornerHarris
(for corner detection), - and
cv::HoughLines
(for finding straight lines in the edge image).
HTH

- 3,852
- 18
- 30
Depending on the viewpoint, the card may end up not being a rectangle but more of a trapezoid. You can use HoughLines2 in OpenCV to identify the edges in the image and try to identify the 4 edges that are most likely to be the edges of the business card.

- 5,547
- 2
- 19
- 14
-
You are saying that other than rotating, I will need to skew the photo? I am considering the case that the camera is normally facing the business card – TiansHUo May 26 '11 at 06:36
If you know the approximate height and width of the rectangle then you can do the following steps:
- Object detection: component labeling using contour tracing.
- After all the objects have been labeled then filter the detected components by calculating the perimeter of the rectangle. P=2*(H+W) Any component having the size of less than or greater than P is ignored, only the components closer to P in size is retained.
- Find corner points of the rectangle from the contour points.
- Extract the rectangle from the original image.
All of the above steps can be done using either OpenCV or Aforge.Net, I have personally done it using Aforge.Net.

- 21
- 1
I think goodFeaturesToTrack()
is easier to use for Harris-Corner detection. CornerHarris()
needs to set outout image to be specific type.

- 185
- 2
- 9