收藏的博客 http://blog.youkuaiyun.com/zhaocj/article/details/42124473
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp" //flannBaseMatcher 定义,
#include "opencv2/flann/flann.hpp" //要使用flannBaseMatcher,需要再添加"opencv2/flann/flann.hpp" 才能使用,否则报错
#include "opencv2/nonfree/features2d.hpp" // SIFT SURF 定义 xxFeaturedetector xxDescriptorExtractor 定义
#include "opencv2/legacy/legacy.hpp" //BruteForceMatcher 定义
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#ifdef _DEBUG
#pragma comment(lib,"lib/opencv_core2411d.lib")
#pragma comment(lib,"lib/opencv_highgui2411d.lib")
#pragma comment(lib,"lib/opencv_imgproc2411d.lib")
#pragma comment(lib,"lib/opencv_features2d2411d.lib")
#pragma comment(lib,"lib/opencv_flann2411d.lib")
#pragma comment(lib,"lib/opencv_legacy2411d.lib")
#pragma comment(lib,"lib/opencv_nonfree2411d.lib")
#else
#pragma comment(lib,"lib/opencv_core2411.lib")
#pragma comment(lib,"lib/opencv_highgui2411.lib")
#pragma comment(lib,"lib/opencv_imgproc2411.lib")
#pragma comment(lib,"lib/opencv_features2d2411.lib")
#pragma comment(lib,"lib/opencv_flann2411.lib")
#pragma comment(lib,"lib/opencv_legacy2411.lib")
#pragma comment(lib,"lib/opencv_nonfree2411.lib")
#endif
using namespace cv;
using namespace std;
/******************************************
加载手机图片,图片尺寸原因会导致报错
*********************************************/
int means1()
{
Mat img1 = imread("image_0001.jpg", 1);
Mat img2 = imread("image_0001.jpg", 1);
SIFT sift; //实例化SIFT类SIFT. 想检测20个特征点 sift(20);
vector<KeyPoint> key_points1; //特征点
Mat descriptors1, mascara; // descriptors为描述符,mascara为掩码矩阵
sift(img1, mascara,key_points1,descriptors1); //执行SIFT运算
Mat output_img1; //输出图像矩阵
drawKeypoints(img1, //输入图像
key_points1, //特征点矢量
output_img1, //输出图像
//Scalar::all(-1), //绘制特征点的颜色,为随机
Scalar(0,0,255),
DrawMatchesFlags::DRAW_RICH_KEYPOINTS); //以特征点为中心画圆,圆的半径表示特征点的大小,直线表示特征点的方向
vector<KeyPoint> key_points2;
Mat descriptors2;
sift(img2, mascara, key_points2, descriptors2);
Mat output_img2;
drawKeypoints(
img2,
key_points2,
output_img2,
//Scalar::all(-1),
Scalar(0, 0, 255),
DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//BruteForceMatcher<L2<float>> matcher; //实例化暴力匹配器——BruteForceMatcher ,二者的区别在于BFMatcher总是尝试所有可能的匹配,从而使得它总能够找到最佳匹配,这也是Brute Force(暴力法)的原始含义。
FlannBasedMatcher matcher; //而FlannBasedMatcher中FLANN的含义是Fast Library forApproximate Nearest Neighbors,
//从字面意思可知它是一种近似法,算法更快但是找到的是最近邻近似匹配,所以当我们需要找到一个相对好的匹配但是不需要最佳匹配的时候往往使用FlannBasedMatcher。
vector<DMatch>matches; //定义匹配器算子
matcher.match(descriptors1, descriptors2, matches); //实现描述符之间的匹配,得到算子matches
std::nth_element( //提取出前100个最佳匹配结果
matches.begin(), //匹配器算子的初始位置
matches.begin() + 99, // 排序的数量
matches.end()); // 结束位置
matches.erase(matches.begin() + 100, matches.end()); //剔除掉其余的匹配结果
Mat img_matches;
drawMatches( //在输出图像中绘制匹配结果
img1, key_points1, //第一幅图像和它的特征点
img2, key_points2, //第二幅图像和它的特征点
matches, //匹配器算子
img_matches, //匹配输出图像
Scalar(255, 0, 0)); //用直线连接两幅图像中的特征点
//namedWindow("SIFT_matches");
//imshow("SIFT_matches", img_matches);
return 0;
}
int means2()
{
Mat img1 = imread("image_0001.jpg", 1);
Mat img2 = imread("image_0001.jpg", 1);
SiftFeatureDetector detector; //构造检测器
vector<KeyPoint> key_points1; //特征点
detector.detect(img1, key_points1); //检测特征
Mat output_img1; //输出图像矩阵
drawKeypoints(
img1, //输入图像
key_points1, //特征点矢量
output_img1, //输出图像
//Scalar::all(-1), //绘制特征点的颜色,为随机
Scalar(0, 0, 255),
DrawMatchesFlags::DRAW_RICH_KEYPOINTS); //以特征点为中心画圆,圆的半径表示特征点的大小,直线表示特征点的方向
SiftDescriptorExtractor extractor; //特征描述提取器
Mat descriptors1;
extractor.compute(img1, key_points1, descriptors1); //提取特征描述子
vector<KeyPoint> key_points2;
detector.detect(img2, key_points2);
Mat output_img2;
drawKeypoints(
img2,
key_points2,
output_img2,
//Scalar::all(-1),
Scalar(0, 0, 255),
DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
Mat descriptors2;
extractor.compute(img2, key_points2, descriptors2);
//BruteForceMatcher<L2<float>> matcher; //实例化暴力匹配器——BruteForceMatcher ,二者的区别在于BFMatcher总是尝试所有可能的匹配,从而使得它总能够找到最佳匹配,这也是Brute Force(暴力法)的原始含义。
FlannBasedMatcher matcher; //而FlannBasedMatcher中FLANN的含义是Fast Library forApproximate Nearest Neighbors,
//从字面意思可知它是一种近似法,算法更快但是找到的是最近邻近似匹配,所以当我们需要找到一个相对好的匹配但是不需要最佳匹配的时候往往使用FlannBasedMatcher。
vector<DMatch>matches; //定义匹配器算子
matcher.match(descriptors1, descriptors2, matches); //实现描述符之间的匹配,得到算子matches
std::nth_element( //提取出前100个最佳匹配结果
matches.begin(), //匹配器算子的初始位置
matches.begin() + 99, // 排序的数量
matches.end()); // 结束位置
matches.erase(matches.begin() + 100, matches.end()); //剔除掉其余的匹配结果
Mat img_matches;
drawMatches( //在输出图像中绘制匹配结果
img1, key_points1, //第一幅图像和它的特征点
img2, key_points2, //第二幅图像和它的特征点
matches, //匹配器算子
img_matches, //匹配输出图像
Scalar(255, 0, 0)); //用直线连接两幅图像中的特征点
//namedWindow("SIFT_matches");
//imshow("SIFT_matches", img_matches);
return 0;
}
int main(int argc, char** argv)
{
means1();
return 0;
}