OpenCV学习(81)

特征检测与匹配(3):使用FLANN进行特征点匹配

一,FlannBasedMatcher类的简单分析;

二,找到最佳匹配:DescriptorMatcher::match方法;

三,示例程序:使用FLANN进行特征点匹配;

四,综合示例程序:FLANN结合SURF进行关键点的描述和匹配;

五,综合示例程序:SIFT配合暴力匹配进行关键点描述和提取;

一,FlannBasedMatcher类的简单分析

在 OpenCV源代码中,找到FlannBasedMatcher类的脉络如下。OpenCV学习(81)_第1张图片
 

        可以发现 FlannBasedMatcher类也是继承自 DescriptorMatcher,并且同样主要使用来自 DescriptorMatcher类的match方法进行匹配。下面,让我们讲解一下此类方法的用法。

二,找到最佳匹配:DescriptorMatcher::match方法

       DescriptorMatcher:.match()函数从每个描述符查询集中找到最佳匹配,有两个版本的源码,下面用注释对其进行讲解。
 OpenCV学习(81)_第2张图片

 

三,示例程序:使用FLANN进行特征点匹配

#include
#include
#include
#include

using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

//检测计算和绘制时,源图(img1)在前面,目标图像(img2)在后面
Mat img1, img2;
int main(int argc, char** argv)
{
	img1 = imread("E:/pictures/2.jpg", 0);
	img2 = imread("E:/pictures/3.2.jpg", 0);


	if (!img1.data || !img2.data)
	{
		cout << "图片为空!" << endl;
		return -1;
	}
	int minHesssion = 400;
	Ptr detector = SURF::create(minHesssion);   //也可以用SIRF,但是效率比SURF低
	vector keypoints_obj;         //存放img1的特征值
	vector keypoints_scene;    //存放img2的特征值
	Mat descript_obj, descript_scene;
	detector->detectAndCompute(img1, Mat(), keypoints_obj, descript_obj);  //检测并计算特征描述子
	detector->detectAndCompute(img2, Mat(), keypoints_scene, descript_scene);

	FlannBasedMatcher fbmatcher;
	vectormatches;
	fbmatcher.match(descript_obj, descript_scene, matches); //特征描述子匹配

	//找出最优特征点
	double minDist = 1000;    //初始化最大最小距离
	double maxDist = 0;
		for (int i = 0; i < descript_obj.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist > maxDist)
		{
			maxDist = dist;
		}
		if (dist < minDist)
		{
			minDist = dist;
		}
	}
	printf("maxDist:%f\n", maxDist);
	printf("minDist:%f\n", minDist);

	vector goodMatches;
	for (int i = 0; i < descript_obj.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist < max(2 * minDist, 0.02)) {
			goodMatches.push_back(matches[i]);
		}
	}
	Mat resultImg;
	drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, resultImg, Scalar::all(-1),
		Scalar::all(-1), vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS
	);


	imshow("input image1", img1);
	imshow("input image2", img2);
	imshow("FlannBasedMatcher demo", resultImg);
	waitKey(0);
	return 0;


}

四,综合示例程序:FLANN结合SURF进行关键点的描述和匹配

#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;

int main()
{
    Mat trainImage = imread("E:/pictures/2.jpg", 1);
    Mat trainImage_gray;
    imshow("原始图", trainImage);
    cvtColor(trainImage, trainImage_gray, CV_BGR2GRAY);

    vectortrain_keypoint;
    Mat trainDescriptor;
    Ptr Detector = SurfFeatureDetector::create(80);
    Detector->detectAndCompute(trainImage_gray, Mat(), train_keypoint, trainDescriptor);

    vector train_desc_collection(1, trainDescriptor);
    FlannBasedMatcher matcher;
    matcher.add(train_desc_collection);
    matcher.train();

    VideoCapture cap(0);
    unsigned int frameCount = 0;

    while (char(waitKey(1) != 'q'))
    {
        int64 time0 = getTickCount();
        Mat testImage, testImage_gray;
        cap >> testImage;
        if (testImage.empty())
            continue;
        cvtColor(testImage, testImage_gray, CV_BGR2GRAY);
        vectortest_keypoint;
        Mat testDescriptor;
        Detector->detectAndCompute(testImage_gray, Mat(), test_keypoint, testDescriptor);

        vector>matches;
        matcher.knnMatch(testDescriptor, matches, 2);

        vectorgoodMatches;
        for (unsigned int i = 0; i < matches.size(); i++)
        {
            if (matches[i][0].distance < 0.6 * matches[i][1].distance)
                goodMatches.push_back(matches[i][0]);
        }

        Mat dstImage;
        drawMatches(testImage, test_keypoint, trainImage, train_keypoint, goodMatches, dstImage);
        imshow("匹配窗口", dstImage);
        cout << "当前帧率为" << getTickFrequency() / (getTickCount() - time0) << endl;
    }
    return 0;
}

 

五,综合示例程序:SIFT配合暴力匹配进行关键点描述和提取

OpenCV学习(81)_第3张图片

#include
#include
#include
#include
using namespace std;
using namespace cv;

int main()
{
	Mat trainImage = imread("E:/pictures/2.jpg"), trainImage_gray;
	//imshow("trainImage", trainImage);
	cvtColor(trainImage, trainImage_gray, COLOR_BGR2GRAY);
	vectortrain_keyPoint;
	Mat trainDescription;

	//SiftFeatureDetector featureDetector;
	//featureDetector.detect(trainImage_gray, train_keyPoint);
	Ptr featureDetector = xfeatures2d::SiftFeatureDetector::create();
	featureDetector->detect(trainImage_gray, train_keyPoint);


	Ptr featureExtractor = xfeatures2d::SiftDescriptorExtractor::create();
	featureExtractor->compute(trainImage_gray, train_keyPoint, trainDescription);
	BFMatcher matcher;
	vectortrain_desc_collection(1, trainDescription);
	matcher.add(train_desc_collection);
	matcher.train();


	Mat captureImage, captureImage_gray;
	captureImage = imread("D:/script/myGit/autojs-flann-feature-matching/图片素材/game001_女生头像.png");
	cvtColor(captureImage, captureImage_gray, COLOR_BGR2GRAY);
	vectortest_keyPoint;
	Mat testDescriptor;
	featureDetector->detect(captureImage_gray, test_keyPoint);
	featureExtractor->compute(captureImage_gray, test_keyPoint, testDescriptor);

	vector>matches;
	matcher.knnMatch(testDescriptor, matches, 2);

	vectorgoodMatches;
	for (unsigned int i = 0; i < matches.size(); i++)
	{
		if (matches[i][0].distance < 0.6 * matches[i][1].distance)
			goodMatches.push_back(matches[i][0]);
	}
	Mat dstImage;
	drawMatches(captureImage, test_keyPoint, trainImage, train_keyPoint, goodMatches, dstImage);
	imshow("dstImage", dstImage);

	cv::waitKey(0);
	return 0;
}

你可能感兴趣的:(opencv,学习,计算机视觉,人工智能,c++)