adding samples for brief and the cout << cv::Mat functions.
authorEthan Rublee <no@email>
Sun, 14 Nov 2010 06:28:41 +0000 (06:28 +0000)
committerEthan Rublee <no@email>
Sun, 14 Nov 2010 06:28:41 +0000 (06:28 +0000)
samples/cpp/brief_match_test.cpp [new file with mode: 0644]
samples/cpp/cvout_sample.cpp [new file with mode: 0644]
samples/cpp/video_homography.cpp [new file with mode: 0644]

diff --git a/samples/cpp/brief_match_test.cpp b/samples/cpp/brief_match_test.cpp
new file mode 100644 (file)
index 0000000..81f517d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * matching_test.cpp
+ *
+ *  Created on: Oct 17, 2010
+ *      Author: ethan
+ */
+#include <opencv2/opencv.hpp>
+#include <vector>
+#include <iostream>
+
+using namespace cv;
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::vector;
+
+void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train,
+                    const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query)
+{
+  pts_train.clear();
+  pts_query.clear();
+  pts_train.reserve(matches.size());
+  pts_query.reserve(matches.size());
+  for (size_t i = 0; i < matches.size(); i++)
+  {
+    const DMatch& match = matches[i];
+    pts_query.push_back(kpts_query[match.queryIdx].pt);
+    pts_train.push_back(kpts_train[match.trainIdx].pt);
+  }
+
+}
+
+float match(const vector<KeyPoint>& kpts_train, const vector<KeyPoint>& kpts_query, DescriptorMatcher& matcher,
+            const Mat& train, const Mat& query, vector<DMatch>& matches)
+{
+
+  float t = (double)getTickCount();
+  matcher.match(query, train, matches);
+  return ((double)getTickCount() - t) / getTickFrequency();
+}
+
+int main(int ac, char ** av)
+{
+  if (ac != 3)
+  {
+    cerr << "usage: " << av[0] << " im1.jpg im2.jpg" << endl;
+    return 1;
+  }
+  string im1_name, im2_name;
+  im1_name = av[1];
+  im2_name = av[2];
+
+  Mat im1 = imread(im1_name, CV_LOAD_IMAGE_GRAYSCALE);
+  Mat im2 = imread(im2_name, CV_LOAD_IMAGE_GRAYSCALE);
+
+  if (im1.empty() || im2.empty())
+  {
+    cerr << "could not open one of the images..." << endl;
+    return 1;
+  }
+
+  double t = (double)getTickCount();
+
+  FastFeatureDetector detector(50);
+  BriefDescriptorExtractor extractor(32);
+
+  vector<KeyPoint> kpts_1, kpts_2;
+  detector.detect(im1, kpts_1);
+  detector.detect(im2, kpts_2);
+
+  t = ((double)getTickCount() - t) / getTickFrequency();
+
+  cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size()
+      << " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl;
+
+  Mat desc_1, desc_2;
+
+  cout << "computing descriptors..." << endl;
+
+  t = (double)getTickCount();
+
+  extractor.compute(im1, kpts_1, desc_1);
+  extractor.compute(im2, kpts_2, desc_2);
+
+  t = ((double)getTickCount() - t) / getTickFrequency();
+
+  cout << "done computing descriptors... took " << t << " seconds" << endl;
+
+  cout << "matching with BruteForceMatcher<HammingLUT>" << endl;
+  BruteForceMatcher<HammingLUT> matcher;
+  vector<DMatch> matches_lut;
+  float lut_time = match(kpts_1, kpts_2, matcher, desc_1, desc_2, matches_lut);
+  cout << "done BruteForceMatcher<HammingLUT> matching. took " << lut_time << " seconds" << endl;
+
+  cout << "matching with BruteForceMatcher<Hamming>" << endl;
+  BruteForceMatcher<Hamming> matcher_popcount;
+  vector<DMatch> matches_popcount;
+  float pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
+  cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;
+
+  vector<Point2f> mpts_1, mpts_2;
+  matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2);
+  vector<uchar> outlier_mask;
+  Mat H = findHomography(Mat(mpts_2), Mat(mpts_1), outlier_mask, RANSAC, 1);
+
+  Mat outimg;
+  drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1),
+              reinterpret_cast<const vector<char>&> (outlier_mask));
+  imshow("matches - popcount - outliers removed", outimg);
+
+  Mat warped;
+  warpPerspective(im2, warped, H, im1.size());
+  imshow("warped", warped);
+  imshow("diff", im1 - warped);
+  waitKey();
+  return 0;
+}
diff --git a/samples/cpp/cvout_sample.cpp b/samples/cpp/cvout_sample.cpp
new file mode 100644 (file)
index 0000000..86e7034
--- /dev/null
@@ -0,0 +1,34 @@
+#include "opencv2/core/core.hpp"
+
+using namespace std;
+using namespace cv;
+
+int main()
+{
+  Mat i = Mat::eye(4, 4, CV_32F);
+  cout << "i = " << i << ";" << endl;
+
+  Mat r = Mat(10, 10, CV_8UC1);
+  randu(r, Scalar(0), Scalar(255));
+
+  cout << "r = " << r << ";" << endl;
+
+  Point2f p(5, 1);
+  cout << "p = " << p << ";" << endl;
+
+  Point3f p3f(2, 6, 7);
+  cout << "p3f = " << p3f << ";" << endl;
+
+  vector<Point2f> points(20);
+  for (size_t i = 0; i < points.size(); ++i)
+  {
+    points[i] = Point2f(i * 5, i % 7);
+  }
+  cout << "points = " << points << ";" << endl;
+
+  cout << "#csv" << endl;
+
+  writeCSV(cout, r);
+
+  return 1;
+}
diff --git a/samples/cpp/video_homography.cpp b/samples/cpp/video_homography.cpp
new file mode 100644 (file)
index 0000000..7324a51
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * video_homography.cpp
+ *
+ *  Created on: Oct 18, 2010
+ *      Author: erublee
+ */
+
+#include <opencv2/opencv.hpp>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+using namespace cv;
+
+namespace
+{
+void drawMatchesRelative(const vector<KeyPoint>& train, const vector<KeyPoint>& query,
+                         std::vector<cv::DMatch>& matches, Mat& img, const vector<unsigned char>& mask = vector<
+                             unsigned char> ())
+{
+  for (int i = 0; i < (int)matches.size(); i++)
+  {
+    if (mask.empty() || mask[i])
+    {
+      Point2f pt_new = query[matches[i].queryIdx].pt;
+      Point2f pt_old = train[matches[i].trainIdx].pt;
+      Point2f dist = pt_new - pt_old;
+
+      cv::line(img, pt_new, pt_old, Scalar(125, 255, 125), 1);
+      cv::circle(img, pt_new, 2, Scalar(255, 0, 125), 1);
+
+    }
+  }
+}
+
+void keypoints2points(const vector<KeyPoint>& in, vector<Point2f>& out)
+{
+  out.clear();
+  out.reserve(in.size());
+  for (size_t i = 0; i < in.size(); ++i)
+  {
+    out.push_back(in[i].pt);
+  }
+}
+
+void points2keypoints(const vector<Point2f>& in, vector<KeyPoint>& out)
+{
+  out.clear();
+  out.reserve(in.size());
+  for (size_t i = 0; i < in.size(); ++i)
+  {
+    out.push_back(KeyPoint(in[i], 1));
+  }
+}
+
+void warpKeypoints(const Mat& H, const vector<KeyPoint>& in, vector<KeyPoint>& out)
+{
+  vector<Point2f> pts;
+  keypoints2points(in, pts);
+  vector<Point2f> pts_w(pts.size());
+  Mat m_pts_w(pts_w);
+  perspectiveTransform(Mat(pts), m_pts_w, H);
+  points2keypoints(pts_w, out);
+}
+
+void matches2points(const vector<KeyPoint>& train, const vector<KeyPoint>& query,
+                    const std::vector<cv::DMatch>& matches, std::vector<cv::Point2f>& pts_train,
+                    std::vector<Point2f>& pts_query)
+{
+
+  pts_train.clear();
+  pts_query.clear();
+  pts_train.reserve(matches.size());
+  pts_query.reserve(matches.size());
+
+  size_t i = 0;
+
+  for (; i < matches.size(); i++)
+  {
+
+    const DMatch & dmatch = matches[i];
+
+    pts_query.push_back(query[dmatch.queryIdx].pt);
+    pts_train.push_back(train[dmatch.trainIdx].pt);
+
+  }
+
+}
+
+void resetH(Mat&H)
+{
+  H = Mat::eye(3, 3, CV_32FC1);
+}
+}
+int main(int ac, char ** av)
+{
+
+  if (ac != 2)
+  {
+    cout << "usage: " << av[0] << " <video device number>" << endl;
+    return 1;
+  }
+
+  BriefDescriptorExtractor brief(32);
+
+  VideoCapture capture;
+  capture.open(atoi(av[1]));
+  if (!capture.isOpened())
+  {
+    cout << "capture device " << atoi(av[1]) << " failed to open!" << endl;
+    return 1;
+  }
+
+  cout << "following keys do stuff:" << endl;
+  cout << "t : grabs a reference frame to match against" << endl;
+  cout << "l : makes the reference frame new every frame" << endl;
+  cout << "q or escape: quit" << endl;
+
+  Mat frame;
+
+  vector<DMatch> matches;
+
+  BruteForceMatcher<Hamming> desc_matcher;
+
+  vector<Point2f> train_pts, query_pts;
+  vector<KeyPoint> train_kpts, query_kpts;
+  vector<unsigned char> match_mask;
+
+  Mat gray;
+
+  bool ref_live = true;
+
+  Mat train_desc, query_desc;
+  const int DESIRED_FTRS = 500;
+  GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4);
+
+  Mat H_prev = Mat::eye(3, 3, CV_32FC1);
+  for (;;)
+  {
+    capture >> frame;
+    if (frame.empty())
+      continue;
+
+    cvtColor(frame, gray, CV_RGB2GRAY);
+
+    detector.detect(gray, query_kpts);
+
+    brief.compute(gray, query_kpts, query_desc);
+
+    if (!train_kpts.empty())
+    {
+
+      vector<KeyPoint> test_kpts;
+      warpKeypoints(H_prev.inv(), query_kpts, test_kpts);
+
+      Mat mask = windowedMatchingMask(test_kpts, train_kpts, 25, 25);
+      desc_matcher.match(query_desc, train_desc, matches, mask);
+      drawKeypoints(frame, test_kpts, frame, Scalar(255, 0, 0), DrawMatchesFlags::DRAW_OVER_OUTIMG);
+
+      matches2points(train_kpts, query_kpts, matches, train_pts, query_pts);
+
+      if (matches.size() > 5)
+      {
+        Mat H = findHomography(Mat(train_pts), Mat(query_pts), match_mask, RANSAC, 4);
+        if (countNonZero(Mat(match_mask)) > 15)
+        {
+          H_prev = H;
+        }
+        else
+          resetH(H_prev);
+        drawMatchesRelative(train_kpts, query_kpts, matches, frame, match_mask);
+      }
+      else
+        resetH(H_prev);
+
+    }
+    else
+    {
+      H_prev = Mat::eye(3, 3, CV_32FC1);
+      Mat out;
+      drawKeypoints(gray, query_kpts, out);
+      frame = out;
+    }
+
+    imshow("frame", frame);
+
+    if (ref_live)
+    {
+      train_kpts = query_kpts;
+      query_desc.copyTo(train_desc);
+    }
+    char key = waitKey(2);
+    switch (key)
+    {
+      case 'l':
+        ref_live = true;
+        resetH(H_prev);
+        break;
+      case 't':
+        ref_live = false;
+        train_kpts = query_kpts;
+        query_desc.copyTo(train_desc);
+        resetH(H_prev);
+        break;
+      case 27:
+      case 'q':
+        return 0;
+        break;
+    }
+
+  }
+  return 0;
+}