cvv_demo.cpp 3.82 KB
Newer Older
1 2 3 4 5
// system includes
#include <getopt.h>
#include <iostream>

// library includes
Maksim Shabunin's avatar
Maksim Shabunin committed
6 7 8 9 10
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/videoio.hpp>
#include <opencv2/videoio/videoio_c.h>
11 12 13 14 15 16 17 18

#define CVVISUAL_DEBUGMODE
#include <opencv2/cvv/debug_mode.hpp>
#include <opencv2/cvv/show_image.hpp>
#include <opencv2/cvv/filter.hpp>
#include <opencv2/cvv/dmatch.hpp>
#include <opencv2/cvv/final_show.hpp>

Maksim Shabunin's avatar
Maksim Shabunin committed
19
using namespace cv;
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

template<class T> std::string toString(const T& p_arg)
{
  std::stringstream ss;

  ss << p_arg;

  return ss.str();
}


void
usage()
{
  printf("usage: cvv_demo [-r WxH]\n");
  printf("-h       print this help\n");
  printf("-r WxH   change resolution to width W and height H\n");
}


int
main(int argc, char** argv)
{
  cv::Size* resolution = nullptr;

  // parse options
  const char* optstring = "hr:";
  int opt;
  while ((opt = getopt(argc, argv, optstring)) != -1) {
    switch (opt) {
    case 'h':
      usage();
      return 0;
      break;
    case 'r':
      {
        char dummych;
        resolution = new cv::Size();
        if (sscanf(optarg, "%d%c%d", &resolution->width, &dummych, &resolution->height) != 3) {
          printf("%s not a valid resolution\n", optarg);
          return 1;
        }
      }
      break;
    default: /* '?' */
      usage();
      return 2;
    }
  }

  // setup video capture
  cv::VideoCapture capture(0);
  if (!capture.isOpened()) {
    std::cout << "Could not open VideoCapture" << std::endl;
    return 3;
  }

  if (resolution) {
    printf("Setting resolution to %dx%d\n", resolution->width, resolution->height);
    capture.set(CV_CAP_PROP_FRAME_WIDTH, resolution->width);
    capture.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->height);
  }


  cv::Mat prevImgGray;
  std::vector<cv::KeyPoint> prevKeypoints;
  cv::Mat prevDescriptors;

  int maxFeatureCount = 500;
Maksim Shabunin's avatar
Maksim Shabunin committed
89
  Ptr<ORB> detector = ORB::create(maxFeatureCount);
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

  cv::BFMatcher matcher(cv::NORM_HAMMING);

  for (int imgId = 0; imgId < 10; imgId++) {
    // capture a frame
    cv::Mat imgRead;
    capture >> imgRead;
    printf("%d: image captured\n", imgId);

    std::string imgIdString{"imgRead"};
    imgIdString += toString(imgId);
		cvv::showImage(imgRead, CVVISUAL_LOCATION, imgIdString.c_str());

    // convert to grayscale
    cv::Mat imgGray;
    cv::cvtColor(imgRead, imgGray, CV_BGR2GRAY);
		cvv::debugFilter(imgRead, imgGray, CVVISUAL_LOCATION, "to gray");

    // detect ORB features
    std::vector<cv::KeyPoint> keypoints;
    cv::Mat descriptors;
Maksim Shabunin's avatar
Maksim Shabunin committed
111
    detector->detectAndCompute(imgGray, cv::noArray(), keypoints, descriptors);
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
    printf("%d: detected %zd keypoints\n", imgId, keypoints.size());

    // match them to previous image (if available)
    if (!prevImgGray.empty()) {
      std::vector<cv::DMatch> matches;
      matcher.match(prevDescriptors, descriptors, matches);
      printf("%d: all matches size=%zd\n", imgId, matches.size());
      std::string allMatchIdString{"all matches "};
      allMatchIdString += toString(imgId-1) + "<->" + toString(imgId);
      cvv::debugDMatch(prevImgGray, prevKeypoints, imgGray, keypoints, matches, CVVISUAL_LOCATION, allMatchIdString.c_str());

      // remove worst (as defined by match distance) bestRatio quantile
      double bestRatio = 0.8;
      std::sort(matches.begin(), matches.end());
      matches.resize(int(bestRatio * matches.size()));
      printf("%d: best matches size=%zd\n", imgId, matches.size());
      std::string bestMatchIdString{"best " + toString(bestRatio) + " matches "};
      bestMatchIdString += toString(imgId-1) + "<->" + toString(imgId);
      cvv::debugDMatch(prevImgGray, prevKeypoints, imgGray, keypoints, matches, CVVISUAL_LOCATION, bestMatchIdString.c_str());
    }

    prevImgGray = imgGray;
    prevKeypoints = keypoints;
    prevDescriptors = descriptors;
  }

  cvv::finalShow();

  return 0;
}