前言
对于特征提取算法的理论学习以及代码实现有很多,本文主要对自己用到的部分进行总结。主要包括特征点的提取,以及图像匹配和融合。
- 这里将特征提取单独拿出来,是为了想更清楚的学习如果实现特征提取,同时统计特征点的数量。
- 另外总结基于SIFT、ORB的特征匹配的实现方式。
- 针对误匹配对的情况,用RANSAC算法进行剔除。
SIFT特征点提取
- 该部分我们可以选择在彩色图或者灰度图的基础上进行特征点提取。
- 也可以选择具体特征点数目或者自动生成特征点个数
- KeyPoint是SIFT算法里面的关键点,包含了各种特点:坐标、 特征点领域直径、特征点的方向、特征点的强度、特征点所在的图像金字塔的组、用于聚类的id
vector<KeyPoint>keypoints;
- src图像中检测到的SIFT特征点存储到keypoints中。
detector->detect(src, keypoints, Mat());
整体代码:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<vector>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
Mat src;
int main(int argc, char** argv)
{
src = imread("./data2/101.png", IMREAD_GRAYSCALE); //加载灰度图像
//src = imread("./data2/101.png"); //加载图像
if (!src.data)
{
cout << "图片加载失败" << endl;
return -1;
}
//namedWindow("加载的灰度图像", CV_WINDOW_NORMAL); //可任意改变窗口大小
imshow("加载的灰度图像", src);
int numfeature = 400; //特征点数目
Ptr<SIFT>detector = SIFT::create(numfeature);
//auto detector = SIFT::create(); //自动生成特征点的个数
vector<KeyPoint>keypoints;
detector->detect(src, keypoints, Mat());
printf("所有的特征点个数:%d", keypoints.size());
Mat resultImg;
drawKeypoints(src, keypoints, resultImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT); //特征点颜色随机
imshow("SIFT特征点提取", resultImg);
imwrite("./效果图/SIFT特征点提取.jpg", resultImg);
waitKey(0);
return 0;
}
ORB特征点提取
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<vector>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
Mat src;
int main(int argc, char** argv)
{
src = imread("./data2/101.png", IMREAD_GRAYSCALE); //加载灰度图像
//src = imread("./data2/101.png"); //加载图像
if (!src.data)
{
cout << "图片加载失败" << endl;
return -1;
}
namedWindow("加载的灰度图像", CV_WINDOW_NORMAL); //可任意改变窗口大小
imshow("加载的灰度图像", src);
int numfeature = 400; //特征点数目
Ptr<ORB>detector = ORB::create(numfeature);
//auto detector = ORB::create(); //自动生成特征点的个数
vector<KeyPoint>keypoints;
detector->detect(src, keypoints, Mat());
printf("所有的特征点个数:%d", keypoints.size());
Mat resultImg;
drawKeypoints(src, keypoints, resultImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT); //特征点颜色随机
imshow("特征点提取", resultImg);
imwrite("./效果图/特征点提取.jpg", resultImg);
waitKey(0);
return 0;
}
FAST角点检测且阈值可调节
- 阈值可自动调节,首先给予一个初值为40的阈值。
- 将特征点个数以及阈值打印出来。
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<vector>
//FAST角点检测
using namespace std;
using namespace cv;
int thre = 40;
Mat src;
void trackBar(int, void*);
int main(int argc, char** argv)
{
//src = imread("./data2/88.jpg");
src = imread("./data2/88.jpg", IMREAD_GRAYSCALE); //加载灰度图像
if (src.empty())
{
printf("无图像加载 \n");
return -1;
}
namedWindow("input", WINDOW_NORMAL);
imshow("input", src);
namedWindow("output", WINDOW_NORMAL);
createTrackbar("threshould", "output", &thre, 255, trackBar);
waitKey(0);
return 0;
}
void trackBar(int, void*)
{
std