For checking the appropriateness of homography matrix between two perspectives of similar images, I wrote this function. You can choose what you prefer out of the possibilities, depending on which one you find more suitable:
private static boolean check_homography(Mat homography_mat){
/* Check 1. Compute the determinant of the homography, and see if it's too close
to zero for comfort*/
if(!homography_mat.empty())
{
double Determinant = Core.determinant(homography_mat);
if (Determinant > 0.1)
return true;
else
return false;
}
else
return false;
/* Check 2. Compute its SVD, and verify that the ratio of the first-to-last
singular value is not too high (order of 1.0E7). */
Mat singularValues = new Mat();
Core.SVDecomp(homography_mat, singularValues, new Mat(), new Mat(), Core.SVD_NO_UV);
System.out.print("
Printing the singular values of the homography");
for (int i = 0; i < singularValues.rows(); i++){
for ( int j = 0; j < singularValues.cols(); j++){
System.out.print("
Element at ( " + i + ", " + j + " ) is " + singularValues.get(i, j)[0]);
}
}
double conditionNumber = singularValues.get(0, 0)[0] / singularValues.get(2, 0)[0];
System.out.print("
Condition number is : " + conditionNumber);
if(conditionNumber < Math.pow(10, 7)){
System.out.print("
Homography matrix is non-singular");
return true;
}
else{
System.out.print("
Homography matrix is singular (or very close)");
return false;
}
/* Check 3. Check the compare absolute values at (0,0) and (0,1) with (1,1) and (1,0)
* respectively. If the two differences are close to 0, the homography matrix is
* good. (This just takes of rotation and not translation)
* */
if(Math.abs((Math.abs(homography_mat.get(0, 0)[0]) - Math.abs(homography_mat.get(1, 1)[0]))) <= 0.1){
if(Math.abs((Math.abs(homography_mat.get(0, 1)[0]) - Math.abs(homography_mat.get(1, 0)[0]))) <= 0.1){
System.out.print("
The homography matrix is good");
return true;
}
}
else{
System.out.print("
The homography matrix is bad");
return false;
}
return false;
/*
* Check 4: If the determinant of the top-left 2 by 2 matrix (rotation) > 0, transformation is orientation
* preserving.
* Else if the determinant is < 0, it is orientation reversing
*
* */
Determinant of the rotation mat
double det = homography_mat.get(0, 0)[0] * homography_mat.get(1,1)[0] - homography_mat.get(0, 1)[0] * homography_mat.get(1, 0)[0];
if (det < 0)
return false;
double N1 = Math.sqrt(homography_mat.get(0, 0)[0] * homography_mat.get(0, 0)[0] + homography_mat.get(1, 0)[0] * homography_mat.get(1, 0)[0]);
if (N1 > 4 || N1 < 0.1)
return false;
double N2 = Math.sqrt(homography_mat.get(0, 1)[0] * homography_mat.get(0, 1)[0] + homography_mat.get(1, 1)[0] * homography_mat.get(1, 1)[0]);
if (N2 > 4 || N2 < 0.1)
return false;
double N3 = Math.sqrt(homography_mat.get(2, 0)[0] * homography_mat.get(2, 0)[0] + homography_mat.get(2,1)[0] * homography_mat.get(2, 1)[0]);
if (N3 < 0.002)
return false;
return true;
}
Note - I coded this for Java, OpenCV when using ORB. I personally (with experience I guess), can look at the Homography matrix and say more or less if its good or not and hence the Check 1. Hope it helps!!
EDIT
Additionally, as @Micka mentioned, this is subject to your preference, you can also iterate along the two images pixel by pixel to find the similarity. The method I post here is used to check if the homography is good or not, however, it should be noted that
you can get bad homography even when two images are similar depending on the images and the method(pre/post processing, descriptor, detector etc. )