This project aims to use homographies to warp images into another image space and then seamlessly blend them into a mosaic.
I took images on my phone with the auto-light adjustment feature turned off while keeping my
hand still and adjusting the angle while keeping the center of projection (COP) of my phone in
the same location. I ensured I had some overlap amongst the set of images and included
noticeably different elements, like a lamp post or a new building, in those images.
I have included the raw images with points in a later section so they can be closer to the
warped images and blended mosaics.
Here are the six sets of my original images with the correspondence points drawn on.
To recover homographies - which is how we transform/warp one image to another's projective plane, we can solve a system of equations, which is equivalent to solving for the vector $h$ of values in $Ah = b$, where in $A$, $b$, $x_i, y_i$ are the coordinates of the source image and $x_i^\prime, y_i^\prime$ are the coordinates of the destination image, and $i$ is the number of pairs of correspondence points.
Then, we can reshape the homography matrix to be 3 by 3.
For this part, we can choose two sets of 4 points - the first set are the original 4 corners of the object in the image we want to rectify and the second set are the 4 corners we want the image to take up, which we expect to be a front-facing square or rectangle.
Here are the two sets of points on two images, followed by the rectified image.
I tried two approaches - naively and a more complex one - to blend each set of 3 images into
one mosaic image. For both, I first warped the left image to middle image and warped the right
image to middle image and found my final canvas by taking the corresponding min and max of the
transformed corners.
To naively blend the images, I directly added the pixel values of both warped images mentioned
above and then used a mask to do the same for the middle image, which didn't need to be warped
since I chose this as the "reference" image. Using a mask was essentially the same as directly
adding the pixel values as since I didn't use distance transform in the approach.
My more complex approach was to use Gaussian and Laplacian stacks to blend like I did in
Project 2 and also distance transforms. Like Aayush Gupta, a student in a previous semester of
CS 180, did, I used a mutually exclusive mask, which is calculated by comparing the
scipy.distance_transform_edt
applied onto the masks. I had two rounds of this
process - the first one was on the warped mask left and warped mask right and second round was
on the result of blending those two images and the middle image. I used 5 levels and
sigma = 4
and kernel_size = 6 * 4 = 24
for convolving images, just
like I did in Project 2.
The first three blended mosaics in the right column are my best results. They are indoors and there's little fluctuation in the lighting. The latter 3 mosaics are taken with the sky and it seems that my camera kept including exposure differences across the images, despite turning the auto-light adjustment feature off. We can see that the more complex approach effectively makes the mosaic more seamless by reducing the abrupt changes in exposure to the human eye.
In this project, we follow some algorithms and methods from the paper Multi-Image Matching using Multi-Scale Oriented Patches” by Brown et al.
get_harris_corners
from the starter code to get the Harris
corners on each image that we want to stitch together. Here are examples of my two results. I
chose a min_distance = 5
, which is the minimum distance we allow to separate peaks,
to pass into skimage.feature.peak_local_max
It aims to filter out corners to get a uniform distribution of corners, selecting the
strongest ones while ensuring diversity spatially. We use a robustness factor called
c_robust
in our suppression condition and use the Euclidean distances between
corners so we select ones that aren't too near one another. We aim to maximize the minimum
radii, which gives us spatial uniformity amongst corners.
Now, using the corner coordinates modified/filtered by ANMS, we can extract the feature
descriptors. We achieve this by looping over each of the coordinates, padding them with the
half window size, resizing the 40x40 window into an 8x8 one, performing bias/gain
normalization and then flattening it. This helps us capture the image structure local to the
region around each corner.
Then, we can loop over each descriptor and apply the Lowe's Ratio test on the ratio of the
distance between the first and second nearest neighbo. If it's below the threshold, we can add
the feature descriptor and its nearest neighbor to our modified set. Finally, we will pass in
the two resulting lists of modified descriptors to RANSAC in the next step.
Here are the feature descriptors.
threshold
that we choose
best_H
and chosen (largest so far) inlier set
best_inliers
if the number of inliers from this current iteration exceeds that
of the current best_inliers
We can then proceed to the rest of the algorithm to create our mosaic by using the
best_H
we got from RANSAC.
threshold
= 4)threshold
= 4)threshold
= 4)