diff --git a/example_16-02.cpp b/example_16-02.cpp new file mode 100644 index 0000000..569af31 --- /dev/null +++ b/example_16-02.cpp @@ -0,0 +1,213 @@ +// Example 16-2. 2D Feature detectors and 2D Extra Features framework + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::cout; +using std::cerr; +using std::vector; +using std::string; + +using cv::Mat; +using cv::Point2f; +using cv::KeyPoint; +using cv::Scalar; +using cv::Ptr; + +using cv::FastFeatureDetector; +using cv::SimpleBlobDetector; + +using cv::DMatch; +using cv::BFMatcher; +using cv::DrawMatchesFlags; +using cv::Feature2D; +using cv::ORB; +using cv::BRISK; +using cv::AKAZE; +using cv::KAZE; + +using cv::xfeatures2d::BriefDescriptorExtractor; +using cv::xfeatures2d::SURF; +using cv::xfeatures2d::SIFT; +using cv::xfeatures2d::DAISY; +using cv::xfeatures2d::FREAK; + +const double kDistanceCoef = 4.0; +const int kMaxMatchingSize = 50; + +inline void detect_and_compute(string type, Mat& img, vector& kpts, Mat& desc) { + if (type.find("fast") == 0) { + type = type.substr(4); + Ptr detector = FastFeatureDetector::create(10, true); + detector->detect(img, kpts); + } + if (type.find("blob") == 0) { + type = type.substr(4); + Ptr detector = SimpleBlobDetector::create(); + detector->detect(img, kpts); + } + if (type == "surf") { + Ptr surf = SURF::create(800.0); + surf->detectAndCompute(img, Mat(), kpts, desc); + } + if (type == "sift") { + Ptr sift = SIFT::create(); + sift->detectAndCompute(img, Mat(), kpts, desc); + } + if (type == "orb") { + Ptr orb = ORB::create(); + orb->detectAndCompute(img, Mat(), kpts, desc); + } + if (type == "brisk") { + Ptr brisk = BRISK::create(); + brisk->detectAndCompute(img, Mat(), kpts, desc); + } + if (type == "kaze") { + Ptr kaze = KAZE::create(); + kaze->detectAndCompute(img, Mat(), kpts, desc); + } + if (type == "akaze") { + Ptr akaze = AKAZE::create(); + akaze->detectAndCompute(img, Mat(), kpts, desc); + } + if (type == "freak") { + Ptr freak = FREAK::create(); + freak->compute(img, kpts, desc); + } + if (type == "daisy") { + Ptr daisy = DAISY::create(); + daisy->compute(img, kpts, desc); + } + if (type == "brief") { + Ptr brief = BriefDescriptorExtractor::create(64); + brief->compute(img, kpts, desc); + } +} + +inline void match(string type, Mat& desc1, Mat& desc2, vector& matches) { + matches.clear(); + if (type == "bf") { + BFMatcher desc_matcher(cv::NORM_L2, true); + desc_matcher.match(desc1, desc2, matches, Mat()); + } + if (type == "knn") { + BFMatcher desc_matcher(cv::NORM_L2, true); + vector< vector > vmatches; + desc_matcher.knnMatch(desc1, desc2, vmatches, 1); + for (int i = 0; i < static_cast(vmatches.size()); ++i) { + if (!vmatches[i].size()) { + continue; + } + matches.push_back(vmatches[i][0]); + } + } + std::sort(matches.begin(), matches.end()); + while (matches.front().distance * kDistanceCoef < matches.back().distance) { + matches.pop_back(); + } + while (matches.size() > kMaxMatchingSize) { + matches.pop_back(); + } +} + +inline void findKeyPointsHomography(vector& kpts1, vector& kpts2, + vector& matches, vector& match_mask) { + if (static_cast(match_mask.size()) < 3) { + return; + } + vector pts1; + vector pts2; + for (int i = 0; i < static_cast(matches.size()); ++i) { + pts1.push_back(kpts1[matches[i].queryIdx].pt); + pts2.push_back(kpts2[matches[i].trainIdx].pt); + } + findHomography(pts1, pts2, cv::RANSAC, 4, match_mask); +} + +int main(int argc, char** argv) { + // Program expects at least four arguments: + // - descriptors type ("surf", "sink", "orb", "brisk", + // "kaze", "akaze", "freak", "daisy", "brief"). + // For "brief", "freak" and "daisy" you also need a prefix + // that is either "blob" or "fast" (e.g. "fastbrief", "blobdaisy") + // - match algorithm ("bf", "knn") + // - path to the object image file + // - path to the scene image file + // + if (argc < 5) { + cerr << "\nError: wrong number of arguments.\n"; + cerr << "\nExample 16-2. 2D Feature detectors and 2D Extra Features framework\n\n" + << "Use:\n" << argv[0] << " " + << " \n" + << "to run this demo\n\n" + << "Program expects at least four arguments:\n" + << " - descriptors type (\"surf\", \"sink\", \"orb\", \"brisk\",\n" + << " \"kaze\", \"akaze\", \"freak\", \"daisy\", \"brief\").\n" + << " For \"brief\", \"freak\" and \"daisy\" you also need a prefix\n" + << " that is either \"blob\" or \"fast\" (e.g. \"fastbrief\", " + << "\"blobdaisy\")\n" + << " - match algorithm (\"bf\", \"knn\")\n" + << " - path to the object image file\n" + << " - path to the scene image file\n\n" + << "Examples:\n" + << argv[0] << " surf knn box.png box_in_scene.png\n" + << argv[0] << " fastfreak bf box.png box_in_scene.png\n" + << std::endl; + exit(1); + } + + string desc_type(argv[1]); + string match_type(argv[2]); + + string img_file1(argv[3]); + string img_file2(argv[4]); + + Mat img1 = cv::imread(img_file1, CV_LOAD_IMAGE_COLOR); + Mat img2 = cv::imread(img_file2, CV_LOAD_IMAGE_COLOR); + + if (img1.channels() != 1) { + cvtColor(img1, img1, cv::COLOR_RGB2GRAY); + } + + if (img2.channels() != 1) { + cvtColor(img2, img2, cv::COLOR_RGB2GRAY); + } + + vector kpts1; + vector kpts2; + + Mat desc1; + Mat desc2; + + vector matches; + + detect_and_compute(desc_type, img1, kpts1, desc1); + detect_and_compute(desc_type, img2, kpts2, desc2); + + match(match_type, desc1, desc2, matches); + + vector match_mask(matches.size(), 1); + findKeyPointsHomography(kpts1, kpts2, matches, match_mask); + + Mat res; + cv::drawMatches(img1, kpts1, img2, kpts2, matches, res, Scalar::all(-1), + Scalar::all(-1), match_mask, DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); + + cv::imshow("result", res); + cv::waitKey(0); + + return 0; +} diff --git a/example_22-01.cpp b/example_22-01.cpp index 1fa56fe..3c7ab7f 100644 --- a/example_22-01.cpp +++ b/example_22-01.cpp @@ -18,7 +18,7 @@ using std::string; // void detectAndDraw( cv::Mat& img, // input image - cv::Ptr classifier, // preloaded classifier + cv::Ptr classifier, // preloaded classifier double scale = 1.3) { // resize image by ... // Just some pretty colors to draw with // @@ -69,12 +69,12 @@ int main(int argc, char** argv) { // if (argc < 3) { cerr << "\nError: wrong number of arguments.\n"; - cerr << "\nExample 22-1. Detecting and drawing faces\n\n" - << "Use:\n" << argv[0] << " \n" - << "to run this demo\n\n" - << "Example:\n" - << argv[0] << " ../faces.png ../haarcascade_frontalface_alt.xml\n" - << std::endl; + cerr << "\nExample 22-1. Detecting and drawing faces\n\n" + << "Use:\n" << argv[0] << " \n" + << "to run this demo\n\n" + << "Example:\n" + << argv[0] << " ../faces.png ../haarcascade_frontalface_alt.xml\n" + << std::endl; exit(1); } string image_file_name = string(argv[1]);