zoukankan      html  css  js  c++  java
  • 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:

  • 相关阅读:
    动态数组的实现案例
    随机验证码实现案例
    wince下的CPU和内存占用率计算
    RT-Thread--时间管理
    RT-Thread--线程管理
    RT-Thread--内核基础
    RT-Thread--简介
    Git基本操作
    STM32F103/429串口IAP+Ymodem升级
    KEIL_MDK生成Bin文件
  • 原文地址:https://www.cnblogs.com/starlitnext/p/3875582.html
Copyright © 2011-2022 走看看