123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #include <iostream>
- #include <opencv2/core.hpp>
- #include <opencv2/videoio.hpp>
- #include <opencv2/highgui.hpp>
- #include <opencv2/imgproc.hpp>
- #include <opencv2/features2d.hpp>
- #include <opencv2/flann.hpp>
- #include <opencv2/xfeatures2d.hpp>
- using namespace cv;
- using namespace cv::xfeatures2d;
- ////////////////////////////////////////////////////
- // This program demonstrates the GMS matching strategy.
- int main(int argc, char* argv[])
- {
- const char* keys =
- "{ h help | | print help message }"
- "{ l left | | specify left (reference) image }"
- "{ r right | | specify right (query) image }"
- "{ camera | 0 | specify the camera device number }"
- "{ nfeatures | 10000 | specify the maximum number of ORB features }"
- "{ fastThreshold | 20 | specify the FAST threshold }"
- "{ drawSimple | true | do not draw not matched keypoints }"
- "{ withRotation | false | take rotation into account }"
- "{ withScale | false | take scale into account }";
- CommandLineParser cmd(argc, argv, keys);
- if (cmd.has("help"))
- {
- std::cout << "Usage: gms_matcher [options]" << std::endl;
- std::cout << "Available options:" << std::endl;
- cmd.printMessage();
- return EXIT_SUCCESS;
- }
- Ptr<Feature2D> orb = ORB::create(cmd.get<int>("nfeatures"));
- orb.dynamicCast<cv::ORB>()->setFastThreshold(cmd.get<int>("fastThreshold"));
- Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
- if (!cmd.get<String>("left").empty() && !cmd.get<String>("right").empty())
- {
- Mat imgL = imread(cmd.get<String>("left"));
- Mat imgR = imread(cmd.get<String>("right"));
- std::vector<KeyPoint> kpRef, kpCur;
- Mat descRef, descCur;
- orb->detectAndCompute(imgL, noArray(), kpRef, descRef);
- orb->detectAndCompute(imgR, noArray(), kpCur, descCur);
- std::vector<DMatch> matchesAll, matchesGMS;
- matcher->match(descCur, descRef, matchesAll);
- matchGMS(imgR.size(), imgL.size(), kpCur, kpRef, matchesAll, matchesGMS, cmd.get<bool>("withRotation"), cmd.get<bool>("withScale"));
- std::cout << "matchesGMS: " << matchesGMS.size() << std::endl;
- Mat frameMatches;
- if (cmd.get<bool>("drawSimple"))
- drawMatches(imgR, kpCur, imgL, kpRef, matchesGMS, frameMatches, Scalar::all(-1), Scalar::all(-1),
- std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
- else
- drawMatches(imgR, kpCur, imgL, kpRef, matchesGMS, frameMatches);
- imshow("Matches GMS", frameMatches);
- waitKey();
- }
- else
- {
- std::vector<KeyPoint> kpRef;
- Mat descRef;
- VideoCapture capture(cmd.get<int>("camera"));
- //Camera warm-up
- for (int i = 0; i < 10; i++)
- {
- Mat frame;
- capture >> frame;
- }
- Mat frameRef;
- for (;;)
- {
- Mat frame;
- capture >> frame;
- if (frameRef.empty())
- {
- frame.copyTo(frameRef);
- orb->detectAndCompute(frameRef, noArray(), kpRef, descRef);
- }
- TickMeter tm;
- tm.start();
- std::vector<KeyPoint> kp;
- Mat desc;
- orb->detectAndCompute(frame, noArray(), kp, desc);
- tm.stop();
- double t_orb = tm.getTimeMilli();
- tm.reset();
- tm.start();
- std::vector<DMatch> matchesAll, matchesGMS;
- matcher->match(desc, descRef, matchesAll);
- tm.stop();
- double t_match = tm.getTimeMilli();
- matchGMS(frame.size(), frameRef.size(), kp, kpRef, matchesAll, matchesGMS, cmd.get<bool>("withRotation"), cmd.get<bool>("withScale"));
- tm.stop();
- Mat frameMatches;
- if (cmd.get<bool>("drawSimple"))
- drawMatches(frame, kp, frameRef, kpRef, matchesGMS, frameMatches, Scalar::all(-1), Scalar::all(-1),
- std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
- else
- drawMatches(frame, kp, frameRef, kpRef, matchesGMS, frameMatches);
- String label = format("ORB: %.2f ms", t_orb);
- putText(frameMatches, label, Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255));
- label = format("Matching: %.2f ms", t_match);
- putText(frameMatches, label, Point(20, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255));
- label = format("GMS matching: %.2f ms", tm.getTimeMilli());
- putText(frameMatches, label, Point(20, 60), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255));
- putText(frameMatches, "Press r to reinitialize the reference image.", Point(frameMatches.cols-380, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255));
- putText(frameMatches, "Press esc to quit.", Point(frameMatches.cols-180, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255));
- imshow("Matches GMS", frameMatches);
- int c = waitKey(30);
- if (c == 27)
- break;
- else if (c == 'r')
- {
- frame.copyTo(frameRef);
- orb->detectAndCompute(frameRef, noArray(), kpRef, descRef);
- }
- }
- }
- return EXIT_SUCCESS;
- }
|