Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perspective correction of UIImage from Points

I'm working on a app where I'll let the user take a picture e.g of a business card or photograph.

The user will then mark the four corners of the object (which they took a picture off) - Like it is seen in a lot of document/image/business card scanning apps:

enter image description here

My question is how do i crop and fix the perspective according to these four points? I've been searching for days and looked at several image proccessing libraries without any luck.

Any one who can point me in the right direction?

like image 671
Jakob Halskov Avatar asked Nov 22 '11 23:11

Jakob Halskov


3 Answers

From iOS8+ there is Filter for Core Image called CIPerspectiveCorrection. All you need to do is pass the image and four points.Perspective Correction

Also there is one more filter supporting iOS6+ called CIPerspectiveTransform which can be used in similar way (skewing image).

like image 148
Roman Roba Avatar answered Nov 14 '22 23:11

Roman Roba


If this image were loaded in as a texture, it'd be extremely simple to skew it using OpenGL. You'd literally just draw a full-screen quad and use the yellow correction points as the UV coordinate at each point.

like image 1
StilesCrisis Avatar answered Nov 14 '22 23:11

StilesCrisis


I'm not sure if you've tried the Opencv library yet, but it has a very nice way to deskew an image. I've got here a small snippet that takes an array of corners, your four corners for example, and a final size to map it into.

You can read the man page for warpPerspective on the OpenCV site.

cv::Mat deskew(cv::Mat& capturedFrame, cv::Point2f source_points[], cv::Size finalSize)
{
    cv::Point2f dest_points[4];

    // Output of deskew operation has same color space as source frame, but
    // is proportional to the area the document occupied; this is to reduce
    // blur effects from a scaling component.
    cv::Mat deskewedMat = cv::Mat(finalSize, capturedFrame.type());

    cv::Size s = capturedFrame.size();

    // Deskew to full output image corners
    dest_points[0] = cv::Point2f(0,s.height); // lower left
    dest_points[1] = cv::Point2f(0,0);        // upper left
    dest_points[2] = cv::Point2f(s.width,0);  // upper right
    dest_points[3] = cv::Point2f(s.width,s.height);  // lower right

    // Build quandrangle "de-skew" transform matrix values
    cv::Mat transform = cv::getPerspectiveTransform( source_points, dest_points  );
    // Apply the deskew transform
    cv::warpPerspective( capturedFrame, deskewedMat, transform, s, cv::INTER_CUBIC );

    return deskewedMat;
}
like image 1
Buddhisthead Avatar answered Nov 14 '22 22:11

Buddhisthead