Feature Detection#

Original author

Ana Huamán

Compatibility

OpenCV >= 3.0

Goal#

In this tutorial you will learn how to:

  • Use the [cv::FeatureDetector](#cv::FeatureDetector) interface in order to find interest points. Specifically:

    • Use the cv::xfeatures2d::SURF and its function cv::xfeatures2d::SURF::detect to perform the detection process

    • Use the function cv::drawKeypoints to draw the detected keypoints

\warning You need the OpenCV contrib modules to be able to use the SURF features (alternatives are ORB, KAZE, … features).

Theory#

Code#

This tutorial code’s is shown lines below. You can also download it from here

#include <iostream>
#include "opencv2/core.hpp"
#ifdef HAVE_OPENCV_XFEATURES2D
#include "opencv2/highgui.hpp"
#include "opencv2/features.hpp"
#include "opencv2/xfeatures2d.hpp"

using namespace cv;
using namespace cv::xfeatures2d;
using std::cout;
using std::endl;

int main( int argc, char* argv[] )
{
    CommandLineParser parser( argc, argv, "{@input | box.png | input image}" );
    Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ), IMREAD_GRAYSCALE );
    if ( src.empty() )
    {
        cout << "Could not open or find the image!\n" << endl;
        cout << "Usage: " << argv[0] << " <Input image>" << endl;
        return -1;
    }

    //-- Step 1: Detect the keypoints using SURF Detector
    int minHessian = 400;
    Ptr<SURF> detector = SURF::create( minHessian );
    std::vector<KeyPoint> keypoints;
    detector->detect( src, keypoints );

    //-- Draw keypoints
    Mat img_keypoints;
    drawKeypoints( src, keypoints, img_keypoints );

    //-- Show detected (drawn) keypoints
    imshow("SURF Keypoints", img_keypoints );

    waitKey();
    return 0;
}
#else
int main()
{
    std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl;
    return 0;
}
#endif

This tutorial code’s is shown lines below. You can also download it from here

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.features.Features;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.xfeatures2d.SURF;

class SURFDetection {
    public void run(String[] args) {
        String filename = args.length > 0 ? args[0] : "../data/box.png";
        Mat src = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
        if (src.empty()) {
            System.err.println("Cannot read image: " + filename);
            System.exit(0);
        }

        //-- Step 1: Detect the keypoints using SURF Detector
        double hessianThreshold = 400;
        int nOctaves = 4, nOctaveLayers = 3;
        boolean extended = false, upright = false;
        SURF detector = SURF.create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);
        MatOfKeyPoint keypoints = new MatOfKeyPoint();
        detector.detect(src, keypoints);

        //-- Draw keypoints
        Features.drawKeypoints(src, keypoints, src);

        //-- Show detected (drawn) keypoints
        HighGui.imshow("SURF Keypoints", src);
        HighGui.waitKey(0);

        System.exit(0);
    }
}

public class SURFDetectionDemo {
    public static void main(String[] args) {
        // Load the native OpenCV library
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        new SURFDetection().run(args);
    }
}

This tutorial code’s is shown lines below. You can also download it from here

from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse

parser = argparse.ArgumentParser(description='Code for Feature Detection tutorial.')
parser.add_argument('--input', help='Path to input image.', default='box.png')
args = parser.parse_args()

src = cv.imread(cv.samples.findFile(args.input), cv.IMREAD_GRAYSCALE)
if src is None:
    print('Could not open or find the image:', args.input)
    exit(0)

#-- Step 1: Detect the keypoints using SURF Detector
minHessian = 400
detector = cv.xfeatures2d_SURF.create(hessianThreshold=minHessian)
keypoints = detector.detect(src)

#-- Draw keypoints
img_keypoints = np.empty((src.shape[0], src.shape[1], 3), dtype=np.uint8)
cv.drawKeypoints(src, keypoints, img_keypoints)

#-- Show detected (drawn) keypoints
cv.imshow('SURF Keypoints', img_keypoints)

cv.waitKey()

Explanation#

Result#

  1. Here is the result of the feature detection applied to the box.png image:

  2. And here is the result for the box_in_scene.png image: