OpenCV using the picture feature point detection and matching (C ++)

background

Recently downloaded from various websites a lot of anime wallpaper, some of which have the same content, but the location size, background color, tint, the hero of the different (examples below). Because of this, the mean square error basis, histogram detection methods are difficult to recognize these and other similar images.

Thinking

There are many OpenCV for feature point detection and calculation functions, these functions can be utilized and gradation surrounding pixels if it is detected in the image feature points, and calculates its information, such as ORB, SIFT, SURF, AKANA. As well as some information on the feature point OpenCV using feature point matching algorithm, such as BF, FLANN. Each picture we can put participate in the matching feature points and information calculated, and then the picture pairwise matching feature points, if the number of feature points on the two images match more than one value, that is, that this two similar pictures . Because this method is considered features of the image directly, so for the size of the position, hue, hero different images can be well matched.

For feature point detection, the algorithm is divided into two classes, a class of feature point information is output binary string, comprising ORB, AKANA the like, the feature point is a floating-point type information output, including SIFT, SURF, but this SIFT and SURF two algorithms are proprietary, commercial to pay, so put them in the OpenCV contrib expansion pack inside, if you are using a version of the python OpenCV, you must download 3.4.2.16 version of opencv-contrib-python to use OpenCV in the SIFT and SURF function. I use the C ++ version of OpenCV, you need to download the source code and OpenCV OpenCV-contrib expansion pack and then compile it yourself, a lot of trouble, so I chose the ORB. For the feature point matching, FLANN regardless of efficiency or effect much better than BF (of course there may be useless for me BF), but a lot of online tutorials (including OpenCV own documentation) are ORB with BF, SIFT with FLANN, StackOverflow there ORB with FLANN people ask how to use, and some say the feature point information directly answer is an integer algorithms can not match FLANN, but fortunately another person in question gives the parameters of FLANN with the ORB, ( HTTPS: // StackOverflow. COM / questions / 43,830,849 / OpenCV-the FLANN for-use-with-ORB-descriptors-to-match-Features ) this also shows that the problem is still overlooked by many people, after all, in today's world is the world of deep learning, very few people go these concern the traditional algorithms.

This procedure is relatively inefficient, require some optimization. First, we ask for the picture feature points and the match should be the original grayscale image after down version, taking care not to use this operation to complete cv :: resize, or will be much slower, directly specify the second when imread argument is cv :: IMREAD_REDUCE_COLOR_4 can be reduced while reading a picture. Of course, in that the bottleneck or 2 cyclic twenty-two match, in order to reduce the operation FLANN I to an average value of each channel pre-image, substantially represented by this value the tone of the image, in the double loop, If the average of the two pictures that much difference (I set is 60), they think they do not like, do not feature point matching, of course, this will lead to a lot more slip through the net, but doing so proved most similar the picture still will not be screened out, but the speed has improved a lot.

Code

 1 #include <io.h>
 2 #include <ctime>
 3 #include <vector>
 4 #include <opencv2/opencv.hpp>
 5 
 6 bool judge(cv::Scalar &a, cv::Scalar &b, int num) {
 7     return a[0] - b[0] < num && a[1] - b[1] < num && a[2] - b[2] < num;
 8 }
 9 
10 int main() {
11 
12     clock_t start = clock(); //计时开始
13     std::vector <cv::String> filelist;
14     typedef std::tuple <cv::String, cv::String, int> data;
15     std::vector <std::vector <cv::KeyPoint>> kplist;
16     std::vector <cv::Mat> deslist;
17     std::vector <cv::Scalar> averagebgr;
18     std::vector <data> same;
19 
20     _finddata_t fd;
21     intptr_t pf = _findfirst("D:/image/*.??g", &fd); filelist.push_back(cv::String("D:/宋奕欣/") + fd.name);
22     the while filelist.push_back (CV :: String ((_findnext (PF, & fd)!) " D: / Image / " ) + fd.name);
 23      _findclose (PF); // include pictures, here is io . .h and Lane _findfirst _findnext, wildcards ?? g screened .jpg and .png file 
24  
25      CV :: the Ptr <CV :: the ORB> ORB = CV the ORB :: :: Create ();
 26 is      for (Auto I: Filelist) {
 27          CV :: Mat imgo = CV :: imread (I, CV :: IMREAD_REDUCED_COLOR_4);
 28          averagebgr.push_back (Mean CV :: (imgo)); // find the average value of each channel 
29          CV Mat IMG ::; :: cvtColor CV (imgo, IMG, CV :: COLOR_BGR2GRAY);
 30         Vector :: STD <CV :: KeyPoint> KP; CV :: Mat des; // KP feature points, des feature point information 
31 is          orb-> detectAndCompute (IMG, CV :: Mat (), KP, des) ;
 32          kplist.push_back (KP);
 33 is          deslist.push_back (des);
 34 is      }
 35  
36      STD :: COUT << " . Successfully keypoints found " << STD :: endl;
 37 [  
38 is  
39      CV :: FlannBasedMatcher FLANN (CV makePtr :: <FLANN CV :: :: LshIndexParams> ( 12 is , 20 is , 2 )); //The cv :: makePtr <cv :: flann :: LshIndexParams> (12, 20, 2) is to make the ORB FLANN can match parameters, a default constructor specifies KD tree algorithm is random, and can only be used SIFT SURF 
40      for ( int I = 0 ; I <filelist.size (); I ++ )
 41 is          for ( int J = I + . 1 ; J <filelist.size (); J ++ ) {
 42 is  
43 is              IF ! (Judge (averagebgr [I], averagebgr [J], 60 )) Continue ;
 44 is  
45              STD :: Vector <CV :: KeyPoint> KPL, KPS; CV :: Mat DESL, Dess;
 46 is              KPL = kplist [I]; DESL = deslist [I];
 47              KPS = kplist [j]; dess =deslist [J];
 48  
49              STD :: Vector <STD :: Vector <CV :: DMatch>> The matches; flann.knnMatch (Dess, DESL, The matches, 2 );
 50              STD :: Vector <CV :: DMatch> Good ;
 51 is              for (Auto K: The matches) {
 52 is                  IF (k.size ()> . 1 && K [ 0 ] .distance < 0.5 * K [ . 1 ] .distance) good.push_back (K [ 0 ]); // knnMatch 2 when k =, each Dmatch returns minimum distance matching sets, when the minimum distance of the two groups differ sufficiently large, that a small group it may be a legitimate match 
53 is              }
 54 is  
55              iF (Good. size ()> 10) Same.push_back (STD :: make_tuple (Filelist [I], Filelist [J], good.size ()));    
 56 is  
57 is              // CV Mat IMG ::; :: drawMatches CV (imgs, KPS, IMGL, KPL , Good, IMG, the Scalar :: CV (0, 255, 0));
 58              // CV :: imshow ( "IMG", IMG); CV :: waitKey (); 
59          }
 60  
61 is      STD :: Sort (Same .begin (), same.end (), [] (Data X, Y Data) {
 62 is          return STD :: GET < 2 > (X)> STD :: GET < 2 > (Y);
 63 is      }); / / the image matching sort of feature points match 
64      for (I Data: Same) {
 65          STD STD :: :: << COUTget<0>(i) << ' ' << std::get<1>(i) << ' ' << std::get<2>(i) << std::endl;
66     }
67 
68     std::cout << (double)(clock() - start) / CLOCKS_PER_SEC << std::endl;
69     system("pause");
70     return 0;
71 }

 

Guess you like

Origin www.cnblogs.com/YuanZiming/p/11333143.html