【Opencv测试用例(六)】


Chapter08

1、interestPoints.cpp

结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试代码

#include <iostream>
#include<opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include "harrisDetector.h"

static int test();

int main()
{
	test();
	system("pause");
	return 0;
}

static int test()
{
	// Harris:

	// Read input image
	std::string path_church01 = "F:/images/church01.jpg";
	cv::Mat image = cv::imread(path_church01, 0);
	if (!image.data)
		return 0;

	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	// Display the image
	cv::namedWindow("Original");
	cv::imshow("Original", image);

	// 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);

	// Display the corners
	cv::namedWindow("Harris");
	cv::imshow("Harris", harrisCorners);

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

	// Display the corners
	cv::namedWindow("Corners");
	cv::imshow("Corners", image);

	// GFTT:

	// Read input image

	image = cv::imread(path_church01, 0);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	// Compute good features to track

	std::vector<cv::KeyPoint> keypoints;
	// GFTT detector
	cv::Ptr<cv::GFTTDetector> ptrGFTT = cv::GFTTDetector::create(
		500,	// maximum number of keypoints to be returned
		0.01,	// quality level
		10);	// minimum allowed distance between points	  
	// detect the GFTT
	ptrGFTT->detect(image, keypoints);
	// for all keypoints
	std::vector<cv::KeyPoint>::const_iterator it = keypoints.begin();
	while (it != keypoints.end()) {

		// draw a circle at each corner location
		cv::circle(image, it->pt, 3, cv::Scalar(255, 255, 255), 1);
		++it;
	}

	// Display the keypoints
	cv::namedWindow("GFTT");
	cv::imshow("GFTT", image);

	// Read input image

	image = cv::imread(path_church01, 0);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	// draw the keypoints
	cv::drawKeypoints(image,		// original image
		keypoints,					// vector of keypoints
		image,						// the resulting image
		cv::Scalar(255, 255, 255),	// color of the points
		cv::DrawMatchesFlags::DRAW_OVER_OUTIMG); //drawing flag

	// Display the keypoints
	cv::namedWindow("Good Features to Track Detector");
	cv::imshow("Good Features to Track Detector", image);

	// FAST feature:

	// Read input image

	image = cv::imread(path_church01, 0);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);
	keypoints.clear();
	// FAST detector
	cv::Ptr<cv::FastFeatureDetector> ptrFAST = cv::FastFeatureDetector::create(40);
	// detect the keypoints
	ptrFAST->detect(image, keypoints);
	// draw the keypoints
	cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);
	std::cout << "Number of keypoints (FAST): " << keypoints.size() << std::endl;

	// Display the keypoints
	cv::namedWindow("FAST");
	cv::imshow("FAST", image);

	// FAST feature without non-max suppression
	// Read input image

	image = cv::imread(path_church01, 0);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	keypoints.clear();
	// detect the keypoints
	ptrFAST->setNonmaxSuppression(false);

	ptrFAST->detect(image, keypoints);
	// draw the keypoints
	cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);

	// Display the keypoints
	cv::namedWindow("FAST Features (all)");
	cv::imshow("FAST Features (all)", image);

	// Read input image

	image = cv::imread(path_church01, 0);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	int total(100); // requested number of keypoints
	int hstep(5), vstep(3); // a grid of 4 columns by 3 rows
	// hstep= vstep= 1; // try without grid
	int hsize(image.cols / hstep), vsize(image.rows / vstep);
	int subtotal(total / (hstep*vstep)); // number of keypoints per grid
	cv::Mat imageROI;
	std::vector<cv::KeyPoint> gridpoints;

	std::cout << "Grid of " << vstep << " by " << hstep << " each of size " << vsize << " by " << hsize << std::endl;

	// detection with low threshold
	ptrFAST->setThreshold(20);
	// non-max suppression
	ptrFAST->setNonmaxSuppression(true);

	// The final vector of keypoints
	keypoints.clear();
	// detect on each grid
	for (int i = 0; i < vstep; i++)
		for (int j = 0; j < hstep; j++) {

			// create ROI over current grid
			imageROI = image(cv::Rect(j*hsize, i*vsize, hsize, vsize));
			// detect the keypoints in grid
			gridpoints.clear();
			ptrFAST->detect(imageROI, gridpoints);
			std::cout << "Number of FAST in grid " << i << "," << j << ": " << gridpoints.size() << std::endl;
			if (gridpoints.size() > subtotal) {
				for (auto it = gridpoints.begin(); it != gridpoints.begin() + subtotal; ++it) {
					std::cout << "  " << it->response << std::endl;
				}
			}

			// get the strongest FAST features
			auto itEnd(gridpoints.end());
			if (gridpoints.size() > subtotal) { // select the strongest features
				std::nth_element(gridpoints.begin(), gridpoints.begin() + subtotal, gridpoints.end(),
					[](cv::KeyPoint& a, cv::KeyPoint& b) {return a.response > b.response; });
				itEnd = gridpoints.begin() + subtotal;
			}

			// add them to the global keypoint vector
			for (auto it = gridpoints.begin(); it != itEnd; ++it) {
				it->pt += cv::Point2f(j*hsize, i*vsize); // convert to image coordinates
				keypoints.push_back(*it);
				std::cout << "  " << it->response << std::endl;
			}
		}

	// draw the keypoints
	cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);

	// Display the keypoints
	cv::namedWindow("FAST Features (grid)");
	cv::imshow("FAST Features (grid)", image);

	// SURF:

	// Read input image

	image = cv::imread(path_church01, 0);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	keypoints.clear();
	// Construct the SURF feature detector object
	//cv::Feature2D    cv::xfeatures2d::SurfFeatureDetector::create(2000.0);
	//cv::FeatureDetector  xfeatures2d::SurfFeatureDetector
	cv::Ptr<cv::FeatureDetector> ptrSURF = cv::SiftFeatureDetector::create(2000.0);
	// detect the keypoints
	ptrSURF->detect(image, keypoints);

	// Detect the SURF features
	ptrSURF->detect(image, keypoints);

	cv::Mat featureImage;
	cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	// Display the keypoints
	cv::namedWindow("SURF");
	cv::imshow("SURF", featureImage);

	std::cout << "Number of SURF keypoints: " << keypoints.size() << std::endl;

	// Read a second input image
	std::string path_church03 = "F:/images/church03.jpg";
	image = cv::imread(path_church03, cv::IMREAD_GRAYSCALE);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	// Detect the SURF features
	ptrSURF->detect(image, keypoints);

	cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	// Display the keypoints
	cv::namedWindow("SURF (2)");
	cv::imshow("SURF (2)", featureImage);

	// SIFT:

	// Read input image

	image = cv::imread(path_church01, cv::IMREAD_GRAYSCALE);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	keypoints.clear();
	// Construct the SIFT feature detector object
	cv::Ptr<cv::SiftFeatureDetector> ptrSIFT = cv::SiftFeatureDetector::create();
	// detect the keypoints
	ptrSIFT->detect(image, keypoints);

	// Detect the SIFT features
	ptrSIFT->detect(image, keypoints);

	cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	// Display the keypoints
	cv::namedWindow("SIFT");
	cv::imshow("SIFT", featureImage);

	std::cout << "Number of SIFT keypoints: " << keypoints.size() << std::endl;

	// BRISK:

	// Read input image

	image = cv::imread(path_church01, cv::IMREAD_GRAYSCALE);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	// Display the keypoints
	cv::namedWindow("BRISK");
	cv::imshow("BRISK", featureImage);

	keypoints.clear();
	// Construct another BRISK feature detector object
	cv::Ptr<cv::BRISK> ptrBRISK = cv::BRISK::create(
		60,  // threshold for BRISK points to be accepted
		5);  // number of octaves

	// Detect the BRISK features
	ptrBRISK->detect(image, keypoints);

	cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	// Display the keypoints
	cv::namedWindow("BRISK");
	cv::imshow("BRISK", featureImage);

	std::cout << "Number of BRISK keypoints: " << keypoints.size() << std::endl;

	// ORB:

	// Read input image

	image = cv::imread(path_church01, cv::IMREAD_GRAYSCALE);
	// rotate the image (to produce a horizontal image)
	cv::transpose(image, image);
	cv::flip(image, image, 0);

	keypoints.clear();
	// Construct the BRISK feature detector object
	cv::Ptr<cv::ORB> ptrORB = cv::ORB::create(
		75, // total number of keypoints
		1.2, // scale factor between layers
		8);  // number of layers in pyramid
	// detect the keypoints
	ptrORB->detect(image, keypoints);

	cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	// Display the keypoints
	cv::namedWindow("ORB");
	cv::imshow("ORB", featureImage);

	std::cout << "Number of ORB keypoints: " << keypoints.size() << std::endl;

	cv::waitKey();
	return 0;
}

harrisDetector.h头文件


#if !defined HARRISD
#define HARRISD

#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/imgproc.hpp>

class HarrisDetector {

private:

	// 32-bit float image of corner strength
	cv::Mat cornerStrength;
	// 32-bit float image of thresholded corners
	cv::Mat cornerTh;
	// image of local maxima (internal)
	cv::Mat localMax;
	// size of neighbourhood 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 neighbourhood for non-max suppression
	int nonMaxSize;
	// kernel for non-max suppression
	cv::Mat kernel;

public:

	HarrisDetector() : neighborhood(3), aperture(3), k(0.1), maxStrength(0.0), threshold(0.01), nonMaxSize(3) {

		setLocalMaxWindowSize(nonMaxSize);
	}

	// Create kernel used in non-maxima suppression
	void setLocalMaxWindowSize(int size) {

		nonMaxSize = size;
		kernel.create(nonMaxSize, nonMaxSize, CV_8U);
	}

	// 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
		cv::minMaxLoc(cornerStrength, 0, &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 computed 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 vector from the computed Harris values
	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 feature points vector from the computed corner map
	void getCorners(std::vector<cv::Point> &points, const cv::Mat& cornerMap) {

		// Iterate over the pixels to obtain all feature points
		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 = 1) {

		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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值