I’m working on a project with ARKit
and I’m trying to do a perspective correction of the ARFrame.capturedImage
to orient a piece of paper sitting on a detected plane so I can feed that into a CoreML
model which expects images to be taken from directly overhead.
ARKit
gives me the device orientation relative to the plane (ARCamera.transform
, ARCamera.eulerAngles
, and ARCamera.projectionMatrix
all look promising).
So I have the orientation of the camera (and I know the plane is horizontal since that’s all ARKit
detects right now).. but I can’t quite figure out how to create a GLKMatrix4
that will perform the correct perspective correction.
Originally I thought it would be as easy as transforming by the inverse of ARCamera.projectionMatrix
but that doesn’t appear to work at all; I’m not entirely sure what that matrix is describing.. it doesn’t seem to change much based on the device orientation.
I’ve tried creating my own matrix using GLKMatrix4Rotate
and the roll/pitch/yaw but that didn’t work.. I couldn’t even get it working with a single axis of rotation.
I found GLKMatrix4MakePerspective
, GLKMatrix4MakeOrtho
, and GLKMatrix4MakeFrustum
which seem to do perspective transforms but I can’t figure out how to take the information I have and translate it to the inputs of those functions to make the proper perspective transformation.
Edit:
As an example to better explain what I’m trying to do, I used the Perspective Warp
tool in Photoshop to transform an example image; what I want to know is how to come up with a matrix that will perform a similar transform given the info I have about the scene.
2
Answers
I ended up using iOS11
Vision
's Rectangle Detection and then feeding it into Core Image'sCIPerspectiveCorrection
filter.I solved using OpenCV perspective transformation. (https://docs.opencv.org/trunk/da/d6e/tutorial_py_geometric_transformations.html,https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#getperspectivetransform)
If you’re able to get the corners of your paper in the scene (for example with an
ARReferenceImage
and project them in 2D), take them. Otherwise you can try to detect the corners through OpenCV directly (see https://stackoverflow.com/a/12636153/9298773) from theUIImage
taken fromsceneView.snapshot()
withsceneView
of typeARSceneView
. In this last case I’d suggest you to binarize first and to change theMAX_CORNERS
variable in the snippet at the link above to 4 (the 4 corners of your paper).Then create a new
cv::Mat
with width and height of your choice respecting the proportion width and height of your paper and do perspective transform. For a guideline of this last paragraph, take a look at the section “Perspective Correction using Homography” at this link: https://www.learnopencv.com/homography-examples-using-opencv-python-c/#download. Succintly: you ask opencv to find an appropriate transform to project your prospected paper points into a perfectly rectangular plane (your newcv::Mat
)