Im building a panorama code based on scikit-image. Its pretty standard, going like
1) load and grayscale images
2) ORB detection and matching
3) RANSAC homography search (yielding a 3x3 matrix)
4) Warping and stitching images
this is working well with my images. However, to get it working in acceptable time, I have to downscale my images for ORB. The transformations derived then applied to the downscaled images give good results, however applying them to the non-scaled images dosn't work.
For reference: scaling is done by skimage.transform.rescale with one constant scale, transformation is a skimage.transform.ProjectiveTransform class and warping is done with skimage.transform.warp
Q1) In my understadning, homographys are only defined up to scale. So why cant i use them on a different scale (if sclaing was done at the image center)
Q2) Is there a way to simply scale my homography?
The estimated homography, H, is defined up to scale in the sense that, when applied to a homographic vector p = [x y z]
, the resulting vector Hp = [x' y' z']
represents the 2-D vector [x'/z' y'/z']
. As such, any scaling of the homography matrix, say kH
, yields kHp = [kx' ky' kz']
or the 2D equivalent [x'/z' y'/z']
, the same as before.
In your described scenario, what you want instead is to rescale the transformation so that it can be applied to your original image coordinates, even though the homography was estimated on scaled down coordinates.
So, you can do something like this:
from skimage import transform as tf
import numpy as np
# Set up a fake homography as illustration
# This homography is estimated on the scaled down image,
# but we'd
estimated_tf = tf.ProjectiveTransform(np.arange(9).reshape((3, 3))/10)
print('Estimated:\n', estimated_tf.params)
S_down = tf.SimilarityTransform(scale=0.5)
S_up = tf.SimilarityTransform(scale=2)
full_tf = S_down + estimated_tf + S_up
print('On scaled down coordinates:', estimated_tf([1, 2]))
print('On full coordinates:', full_tf([2, 4]))
Which yields
Estimated:
[[ 0. 0.1 0.2]
[ 0.3 0.4 0.5]
[ 0.6 0.7 0.8]]
On scaled down coordinates: [[ 0.14285714 0.57142857]]
On full coordinates: [[ 0.28571429 1.14285714]]