Learning OpenCV Lecture 7 (Detecting and Matching Interest Points)

In this chapter, we will cover:

  • Detecting Harris corners
  • Detecting FAST features
  • Detecting the scale-invariant SURF features
  • Describing SURF features

Detecting Harris corners

The basic OpenCV function for detecting Harris corners is called cv::cornerHarrisand is straightforward to use. You call it on an input image and the result is an image of floats which gives the corner strength at each pixel location. A threshold is then applied on this output image in order to obtain a set of detected corners. This is accomplished by the following code:

	// Detect Harris Corners
	cv::Mat cornerStrength;
	cv::cornerHarris(image, cornerStrength,
		3,		// neighborhood size
		3,		// aperture size
		0.01	// Harris parameter
		);
	// threshold the corner strengths
	cv::Mat harrisCorners;
	double threshold = 0.0001;
	cv::threshold(cornerStrength, harrisCorners, threshold, 255, cv::THRESH_BINARY_INV);

	cv::imshow("Original Image", image);
	cv::imshow("Harris Corner Map", harrisCorners);

Here is the original image:

 

The result is a binary map image shown in the following screenshot which is inverted for better viewing (that is, we used cv::THRESH_BINARY_INVinstead of cv::THRESH_BINARYto get the detected corners in black):

The class encapsulates the Harris parameters with their default values and corresponding getter and setter methods (which are not shown here):

#if !defined HARRISDETECTOR
#define HARRISDETECTOR

#include <core/core.hpp>
#include <highgui/highgui.hpp>
#include <imgproc/imgproc.hpp>

class HarrisDetector {
private:

	// 32-bit float image of corner strength
	cv::Mat cornerStrength;
	// 32-bit float image of threshold corners
	cv::Mat cornerTh;
	// image of local maxima (internal)
	cv::Mat localMax;
	// size of neighborhood for derivatives smoothing
	int neighborhood;
	// aperture for gradient computation
	int aperture;
	// Harris parameter
	double k;
	// maximum strength for threshold computation
	double maxStrength;
	// calculated threshold (internal)
	double threshold;
	// size of neighborhood for non-max supression
	int nonMaxSize;
	// kernel for non-max supression
	cv::Mat kernel;

public:
	HarrisDetector() : neighborhood(3), aperture(3),
						k(0.01), maxStrength(0.0),
						threshold(0.01), nonMaxSize(3) {
		// create kernel used in non-max supression
		setLocalMaxWindowSize(nonMaxSize);
	}

	void setLocalMaxWindowSize(int nonMaxSize) {
		this->nonMaxSize = nonMaxSize;
	}

	// Compute Harris corners
	void detect(const cv::Mat &image) {
		// Harris computation
		cv::cornerHarris(image, cornerStrength,
			neighborhood,	// neighborhood size
			aperture,		// aperture size
			k				// Harris parameter
			);
		// internal threshold computation
		double minStrength;	// not used
		cv::minMaxLoc(cornerStrength, &minStrength, &maxStrength);
		// local maxima detection
		cv::Mat dilated;	//temporary image
		cv::dilate(cornerStrength, dilated, cv::Mat());
		cv::compare(cornerStrength, dilated, localMax, cv::CMP_EQ);
	}

	// Get the corner map from the comuted Harris values
	cv::Mat getCornerMap(double qualityLevel) {
		cv::Mat cornerMap;
		// thresholding the corner strength
		threshold = qualityLevel * maxStrength;
		cv::threshold(cornerStrength, cornerTh, threshold, 255, cv::THRESH_BINARY);
		// convert to 8-bit image
		cornerTh.convertTo(cornerMap, CV_8U);
		// non-maxima suppression
		cv::bitwise_and(cornerMap, localMax, cornerMap);
		return cornerMap;
	}

	// Get the feature points from the computed Harris value
	void getCorners(std::vector<cv::Point> &points, double qualityLevel) {
		// Get the corner map
		cv::Mat cornerMap = getCornerMap(qualityLevel);
		// Get the corners
		getCorners(points, cornerMap);
	}

	// Get the features points from the computed corner map
	void getCorners(std::vector<cv::Point> &points, const cv::Mat &cornerMap) {
		// Iterate over the pixels to obtain all features
		for (int y = 0; y < cornerMap.rows; y++) {
			const uchar *rowPtr = cornerMap.ptr<uchar>(y);
			for (int x = 0; x < cornerMap.cols; x++) {
				// if it is a feature point
				if (rowPtr[x]) {
					points.push_back(cv::Point(x, y));
				}
			}
		}
	}

	// Draw circles at feature point locations on an image
	void drawOnImage(cv::Mat &image, const std::vector<cv::Point> &points,
		cv::Scalar color = cv::Scalar(255, 255, 255),
		int radius = 3, int thickness = 2) {
		std::vector<cv::Point>::const_iterator it = points.begin();
		// for all corners
		while (it != points.end()) {
			// draw a circle at each corner location
			cv::circle(image, *it, radius, color, thickness);
			++ it;
		}
	}

};

#endif

Using this class, the detection of the Harris points is accomplished as follows:

	// Using HarrisDetector Class
	// Create Harris detector instance
	HarrisDetector harris;
	// Compute Harris values
	harris.detect(image);
	// Detect Harris corners
	std::vector<cv::Point> pts;
	harris.getCorners(pts, 0.01);
	// Draw Harris corners
	harris.drawOnImage(image, pts);

	cv::imshow("Harris Corners", image);

Which results in the following image:

Additional improvements can be made to the original Harris corner algorithm. This section describes another corner detector found in OpenCV which expands the Harris detector to make its corners more uniformly distributed across the image. As we will see, this operator has an implementation in the new OpenCV 2 common interface for feature detector.

Good features to track:

// Compute good features to track
std::vector<cv::Point2f> corners;
cv::goodFeaturesToTrack(image,corners,
    500, // maximum number of corners to be returned
    0.01, // quality level
    10); // minimum allowed distance between points

In addition to the quality-level threshold value, and the minimum tolerated distance between interest points, the function also uses a maximum number of points to be returned (this is possible since points are accepted in order of strength). The preceding function call produces the following result:

  

Detecting FAST features

In this recipe, we present another feature point operator. This one has been specifically designed to allow quick detection of interest points in an image. The decision to accept or not to accept a keypoint being based on only a few pixel comparisons.

Using the OpenCV 2 common interface for feature point detection makes the deployment of any feature point detectors easy. The one presented in this recipe is the FAST detector. As the name suggests, it has been designed to be quick to compute. Note that OpenCV also proposes a generic function to draw keypoints on an image:

	// Detection FAST features
	image = cv::imread("../church01.jpg");
	// vector of keypoints
	std::vector<cv::KeyPoint> keypoints;
	// Construction of the Fast feature detector object
	cv::FastFeatureDetector fast(40); // threshold for detection
	// feature point detection
	fast.detect(image, keypoints);
	// draw keypoints on an image
	cv::drawKeypoints(image,		//original image
		keypoints,					// vector of keypoints
		image,						// the output image
		cv::Scalar(255, 255, 255),	// key point color
		cv::DrawMatchesFlags::DRAW_OVER_OUTIMG // drawing flag
		);
	cv::imshow("FAST Features", image);

By specifying the chosen drawing flag, the keypoints are drawn over the output image, thus producing the following result:

 

Detecting the scale-invariant SURF features

The OpenCV implementation of SURF features also use the cv::FeatureDetector interface. Therefore, the detection of these features is similar to what we demonstrated in the previous recipes of this chapter:

Learning OpenCV Lecture 7 (Detecting and Matching Interest Points)

时间: 2024-10-10 15:18:45

Learning OpenCV Lecture 7 (Detecting and Matching Interest Points)的相关文章

Learning OpenCV Lecture 4 (Transforming Images with Morphological Operations)

In this chapter, we will cover: Eroding and dilating images using morphological filters Opening and closing images using morphological filters Detecting edges and corners using morphological filters Segmenting images using watersheds 分水岭算法 Extracting

Learning OpenCV Lecture 5 (Filtering the Images)

In this chapter, we will cover: Filtering images using low-pass filters Filtering images using a median filter Applying directional filters to detect edges Computing the Laplacian of an image 图像各有不同因为他们有不一样的灰度级分布.如天空的灰度级不怎么变化,但是在一个对象非常多的图像里面,灰度级变化非常剧

Learning OpenCV Lecture 6 (Extracting Lines,Contours, and Components)

In this chapter, we will cover: Detecting image contours with the Canny operator Detecting lines in images with the Hough transform Fitting a line to a set of points Extracting the components' contours Computing components' shape descriptors Detectin

Learning OpenCV Lecture 3 (Counting the Pixels with Histograms)

In this chapter, we will cover: Computing the image histogram Applying look-up tables to modify image appearance Equalizing the image histogram Backprojecting a histogram to detect specific image content Using the mean shift algorithm to find an obje

Learning OpenCV Lecture 2 (Using the Strategy pattern in algorithm design)

ColorDetector.h: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> class ColorDetector { public: // empty constructor ColorDetector() : minDist(100) { // default parameter initialization here target[0] = target[1] = targe

Learning OpenCV Lecture 1 (Using OpenCV in VS2010)

1.Create a new Win32 Console Application 2.Open the Property Manager by View->Property Manage r In Visual C++ 2010, a property sheet is an XML file that describes your project settings. We will now create a new one by right-clicking on the Debug | Wi

Cygwin编译自定义OpenCV库报错:opencv_contrib: LOCAL_SRC_FILES points to a missing file

今天受命帮师弟调个OpenCV4Android 识别银行卡的程序,版本为OpenCV4Android2.4.9,使用方式为前文介绍的第一种方式,即通过jni调用opencv.如杂家前文所述,配套的NDK应使用较高版本的android-ndk-r9d.它的安装很简单,解压缩后设置环境变量到Path就ok:D:\ProgramFile\android-ndk-r9d; 但遗憾的是,同样的程序同样的配置在一台PC上通过Cygwin编译一切ok.但在新的一台电脑上却出现如下错误: Android NDK

Awesome Machine Learning

Awesome Machine Learning  A curated list of awesome machine learning frameworks, libraries and software (by language). Inspired by awesome-php. If you want to contribute to this list (please do), send me a pull request or contact me @josephmisiti Als

【CV】ICCV2015_Unsupervised Learning of Visual Representations using Videos

Unsupervised Learning of Visual Representations using Videos Motivation: - Supervised learning is popular for CNN to train an excellent model on various visual problems, while the application of unsupervised learning leaves blank. - People learn conc