Discovering known objects through feature detection and single-match matching
- Use the function findhomography to find the transform between matched keypoints.
- Use the function Perspectivetransform to map the points.
Detection + description + Match ~ ~ Get the matching keypoints after the deformation matrix can be calculated
Findhomography
Finds a perspective transformation between and planes.
Parameters:
- srcpoints –coordinates of the points in the original plane, a matrix of the type cv_32fc2 orvector& Lt Point2f> .
- dstpoints –coordinates of the points in the target plane, a matrix of the type cv_32fc2 or avector& Lt Point2f> .
- Method –
Method used to computed a homography matrix. The following methods is possible:
- 0 -A regular method using all the points
- Cv_ransac -ransac-based Robust method
- cv_lmeds -Least-median Robust method
- Ransacreprojthreshold –
Maximum allowed reprojection error to treat a point pair as an inlier (used in the RANSAC method only). That is, if
Then the point was considered an outlier. If srcpoints and dstpoints is measured in pixels, it usually makes sense to set this parameter SOMEWH Ere in the range of 1 to 10.
- mask –optional output mask set by a robust method ( Cv_ransac or cv_lmeds ). Note that the input mask values is ignored.
The functions find and return the perspective transformation between the source and the destination planes:
So, the back-projection error
is minimized. If the parameter method is set to the default value of 0, the function uses all the point pairs to compute an Initia L homography estimate with a simple least-squares scheme.
Then perform a perspective projection transformation on the four corners of the object
void perspectivetransform(inputarray src, outputarray dst, Inputarray m)
Parameters:
- src –input two-channel or three-channel floating-point array; Each element was a 2d/3d vector to being transformed.
- DST –output array of the same size and type as src.
- m – 3x3 or 4x4 floating-point transformation matrix.
Performs the perspective matrix transformation of vectors.
Code
#include <stdio.h> #include <iostream> #include "opencv2/core/core.hpp" #include "opencv2/features2d/ Features2d.hpp "#include" opencv2/highgui/highgui.hpp "#include" opencv2/calib3d/calib3d.hpp "#include" opencv2/ Nonfree/nonfree.hpp "using namespace cv;void Readme ();/** @function main */int main (int argc, char** argv) {if (argc! = 3 ) {Readme (); return-1;} Mat img_object = Imread (argv[1], cv_load_image_grayscale); Mat Img_scene = Imread (argv[2], cv_load_image_grayscale); if (!img_object.data | |!img_scene.data) {std::cout<< " --(!) Error reading Images "<< Std::endl; return-1; }//--Step 1:detect the keypoints using SURF detectorint Minhessian = 400; Surffeaturedetector Detector (Minhessian);std::vector<keypoint> keypoints_object, Keypoints_scene; Detector.detect (Img_object, Keypoints_object);d etector.detect (Img_scene, keypoints_scene);//--Step 2:calculate Descriptors (feature vectors) surfdescriptorextractor extractor; Mat Descriptors_object, DescriptOrs_scene;extractor.compute (Img_object, Keypoints_object, Descriptors_object); Extractor.compute (Img_scene, Keypoints_scene, Descriptors_scene);//--Step 3:matching descriptor vectors using FLANN matcherflannbasedmatcher matche r;std::vector< dmatch > Matches;matcher.match (descriptors_object, Descriptors_scene, matches);d ouble max_dist = 0; Double min_dist = 100;//--Quick calculation of Max and min distances between keypointsfor (int i = 0; i < Descriptors_ Object.rows; i++) {Double dist = matches[i].distance;if (Dist < min_dist) min_dist = dist;if (Dist > max_dist) max_dist = Dist ;} printf ("--Max dist:%f \ n", max_dist);p rintf ("-Min dist:%f \ n", min_dist);//--Draw only "good" matches (i.e. whos E distance is less than 3*min_dist) std::vector< dmatch > good_matches;for (int i = 0; i < Descriptors_object.row S i++) {if (Matches[i].distance < 3*min_dist) {Good_matches.push_back (matches[i]);}} Mat img_matches;drawmatches (Img_object, Keypoints_Object, Img_scene, Keypoints_scene,good_matches, Img_matches, Scalar::all ( -1), Scalar::all ( -1),vector<char> () , drawmatchesflags::not_draw_single_points);//--Localize the objectstd::vector<point2f> obj;std::vector< point2f> scene;for (int i = 0; i < good_matches.size (); i++) {//--Get the keypoints from the good Matchesobj.push_b ACK (keypoints_object[good_matches[i].queryidx].pt); Scene.push_back (keypoints_scene[good_matches[i].trainIdx]. PT);} Mat H = findhomography (obj, scene, Cv_ransac);//--Get the corners from the image_1 (the object to be "detected") std:: Vector<point2f> obj_corners (4); Obj_corners[0] = Cvpoint (0,0); OBJ_CORNERS[1] = cvpoint (img_object.cols, 0); obj_corners[2] = Cvpoint (Img_object.cols, img_object.rows); obj_corners[ 3] = cvpoint (0, img_object.rows);std::vector<point2f> scene_corners (4);p erspectivetransform (Obj_corners, Scene_corners, H);//--Draw lines between the corners (the mapped object in the scene-image_2) line ( Img_matches, Scene_corners[0] + point2f (img_object.cols, 0), scene_corners[1] + point2f (img_object.cols, 0), Scalar (0, 255, 0), 4), line (Img_matches, scene_corners[1] + point2f (img_object.cols, 0), scene_corners[2] + point2f (img_object.co LS, 0), Scalar (0, 255, 0), 4), line (Img_matches, scene_corners[2] + point2f (img_object.cols, 0), scene_corners[3] + Poi NT2F (img_object.cols, 0), Scalar (0, 255, 0), 4); line (Img_matches, scene_corners[3] + point2f (img_object.cols, 0), SCE Ne_corners[0] + point2f (img_object.cols, 0), Scalar (0, 255, 0), 4);//--Show detected matchesimshow ("Good Matches & ; Object detection ", img_matches); Waitkey (0); return 0;} /** @function Readme */void Readme () {std::cout << "Usage:./surf_descriptor
OpenCV tutorials--features2d + homography to find a known object