Orthographic Projection using Planar Homography
Can planar homography extract the orthographic projection of an isometric view image?
Hello everyone. In this post, we are doing to experiment if we can extract orthogonal views (top, front, side) from an isometric view using homography.
What is homography?
Planar homography is defined as mapping between two planar projections of an image. To transform between two projections, a homography matrix is required. This matrix is a normalized 3x3 in shape with 8 degrees of freedom. The images are assumed to be taken on a planar plane, thus spherical images (fish eye lens image) will not work on this planar homography.
In this experiment, the image is drawn from an isometric view. To get for the orthographic view, we have to know the relationship between these views by a homography matrix. Luckily, skimage has a function to calculate the homography matrix based on the source points and destination points of the images.
To execute homography in the image, you need two sets of points:
- The source points. These are the points from the original image as your source reference.
- The destination points. These are the points that you want to map out your image. In this case, we are given the dimensions of the drawing. We can use this as our reference for our destination points
At least 3 points should not be collinear to each when picking these points.
Plotting the Source Points of Top View
from skimage.io import imread, imshow
import matplotlib.pyplot as plt
import numpy as np
from skimage import transform# Top View of the Imagetop = imread('isometric.PNG')
plt.annotate('1', xy=(335, 39), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
plt.annotate('2', xy=(170, 39), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
plt.annotate('3', xy=(309, 92), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
plt.annotate('4', xy=(381, 92), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
imshow(top)
top_src = np.array([335, 39,
170, 39,
309, 92,
381, 92,
]).reshape((4, 2))
Applying Transform to the Destination Image.
dest = imread('white.PNG')top_dst = np.array([440, 200,
300, 200,
380, 310,
440, 310]).reshape((4, 2))tform = transform.estimate_transform('projective', top_src, top_dst)
tf_img = transform.warp(top, tform.inverse, output_shape=(800,800))plt.figure(figsize=(15,8))plt.annotate('1', xy=(440, 200), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
plt.annotate('2', xy=(300, 200), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
plt.annotate('3', xy=(380, 310), c="r", arrowprops=dict(facecolor='red', shrink=0.05))
plt.annotate('4', xy=(440, 310), c="r", arrowprops=dict(facecolor='red', shrink=0.05))plt.imshow(tf_img)
Although the aspect ratio of the top face of the drawing is correct, it is not successful in hiding the front and side faces of the drawing.
This is also the case for front and side views.
In conclusion, planar homography has limitations on converting a 2D image of isometric view into 2D images of orthographic orientation. While it correctly captures the size associated with the destination view, it does not hide the faces from other sides. This might also have to do with the limitation of information provided with images, as they are only two dimensional with not enough information about the depth.
Thanks for reading. :)