OpenCV  4.2.0
Open Source Computer Vision
AKAZE local features matching

Introduction

In this tutorial we will learn how to use AKAZE [ANB13] local features to detect and match keypoints on two images. We will find keypoints on a pair of images with given homography matrix, match them and count the number of inliers (i.e. matches that fit in the given homography).

You can find expanded version of this example here: https://github.com/pablofdezalc/test_kaze_akaze_opencv

Data

We are going to use images 1 and 3 from Graffiti sequence of Oxford dataset.

Homography is given by a 3 by 3 matrix:

7.6285898e-01 -2.9922929e-01 2.2567123e+02
3.3443473e-01 1.0143901e+00 -7.6999973e+01
3.4663091e-04 -1.4364524e-05 1.0000000e+00

You can find the images (graf1.png, graf3.png) and homography (H1to3p.xml) in opencv/samples/data/.

Source Code

Explanation

  • Load images and homography

We are loading grayscale images here. Homography is stored in the xml created with FileStorage.

  • Detect keypoints and compute descriptors using AKAZE

We create AKAZE and detect and compute AKAZE keypoints and descriptors. Since we don't need the mask parameter, noArray() is used.

  • Use brute-force matcher to find 2-nn matches

We use Hamming distance, because AKAZE uses binary descriptor by default.

  • Use 2-nn matches and ratio criterion to find correct keypoint matches

If the closest match distance is significantly lower than the second closest one, then the match is correct (match is not ambiguous).

  • Check if our matches fit in the homography model

If the distance from first keypoint's projection to the second keypoint is less than threshold, then it fits the homography model.

We create a new set of matches for the inliers, because it is required by the drawing function.

  • Output results

Here we save the resulting image and print some statistics.

Results

Found matches

Depending on your OpenCV version, you should get results coherent with:

Keypoints 1: 2943
Keypoints 2: 3511
Matches: 447
Inliers: 308
Inlier Ratio: 0.689038
cv::noArray
InputOutputArray noArray()
cv::String
std::string String
Definition: cvstd.hpp:150
cv::MatExpr::max
MatExpr max(const Mat &a, const Mat &b)
cv::samples::findFile
cv::String findFile(const cv::String &relative_path, bool required=true, bool silentMode=false)
Try to find requested data file.
cv::Mat::at
_Tp & at(int i0=0)
Returns a reference to the specified array element.
cv::DMatch::queryIdx
int queryIdx
query descriptor index
Definition: types.hpp:815
cv::DMatch::trainIdx
int trainIdx
train descriptor index
Definition: types.hpp:816
cv::waitKey
int waitKey(int delay=0)
Waits for a pressed key.
cv::FileStorage
XML/YAML/JSON file storage class that encapsulates all the information necessary for writing or readi...
Definition: persistence.hpp:304
cv::sqrt
softfloat sqrt(const softfloat &a)
Square root.
cv::Feature2D::detectAndCompute
virtual void detectAndCompute(InputArray image, InputArray mask, std::vector< KeyPoint > &keypoints, OutputArray descriptors, bool useProvidedKeypoints=false)
cv::DMatch
Class for matching keypoint descriptors.
Definition: types.hpp:809
highgui.hpp
cv::IMREAD_GRAYSCALE
@ IMREAD_GRAYSCALE
If set, always convert image to the single channel grayscale image (codec internal conversion).
Definition: imgcodecs.hpp:66
cv::BFMatcher
Brute-force descriptor matcher.
Definition: features2d.hpp:1110
cv::imread
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
cv::dnn::print
static void print(const MatShape &shape, const String &name="")
Definition: shape_utils.hpp:188
cv::DescriptorMatcher::knnMatch
void knnMatch(InputArray queryDescriptors, InputArray trainDescriptors, std::vector< std::vector< DMatch > > &matches, int k, InputArray mask=noArray(), bool compactResult=false) const
Finds the k best matches for each descriptor from a query set.
cv::NORM_HAMMING
@ NORM_HAMMING
Definition: base.hpp:199
cv::Ptr
std::shared_ptr< _Tp > Ptr
Definition: cvstd_wrapper.hpp:23
CV_64F
#define CV_64F
Definition: interface.h:79
cv::imshow
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
cv::drawMatches
void drawMatches(InputArray img1, const std::vector< KeyPoint > &keypoints1, InputArray img2, const std::vector< KeyPoint > &keypoints2, const std::vector< std::vector< DMatch > > &matches1to2, InputOutputArray outImg, const Scalar &matchColor=Scalar::all(-1), const Scalar &singlePointColor=Scalar::all(-1), const std::vector< std::vector< char > > &matchesMask=std::vector< std::vector< char > >(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT)
features2d.hpp
cv::Scalar
Scalar_< double > Scalar
Definition: types.hpp:669
cv::drawMatches
void drawMatches(InputArray img1, const std::vector< KeyPoint > &keypoints1, InputArray img2, const std::vector< KeyPoint > &keypoints2, const std::vector< DMatch > &matches1to2, InputOutputArray outImg, const Scalar &matchColor=Scalar::all(-1), const Scalar &singlePointColor=Scalar::all(-1), const std::vector< char > &matchesMask=std::vector< char >(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT)
Draws the found matches of keypoints from two images.
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:792
cv::imshow
void imshow(const String &winname, const ogl::Texture2D &tex)
Displays OpenGL 2D texture in the specified window.
cv::CommandLineParser
Designed for command line parsing.
Definition: utility.hpp:797
cv::imwrite
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
cv
"black box" representation of the file storage associated with a file on disk.
Definition: affine.hpp:52
imgproc.hpp
cv::pow
softfloat pow(const softfloat &a, const softfloat &b)
Raising to the power.
cv::DescriptorMatcher::create
static Ptr< DescriptorMatcher > create(const String &descriptorMatcherType)
Creates a descriptor matcher of a given type with the default parameters (using default constructor).
cv::DMatch::distance
float distance
Definition: types.hpp:819