图像特征提取--ORB算法

实时性特征检测
可以分为两个部分:图像特征提取与匹配
ORB(Oriented FAST and Rotated BRIEF)该特征检测算法是在著名的FAST特征检测和BRIEF特征描述子的基础上提出来的,其运行时间远远优于SIFT和SURF,可应用于实时性特征检测。

遇到过这样一个问题,在双目视觉中,使用矫正的两张图片,计算视差时,需要找到匹配点。
自己写了一个基于灰度值的线特征匹配算法,但是效果会受到图像效果的影响,且二值化的阈值是不固定的。
于是就在网上查资料,发现ORB特征匹配算法,速度很快,实时性好,准确度高,非常有帮助。

话不多说:附上我的测试代码
自己配置一下opencv,我这里测试时用的opencv4.1,如果需要,可以联系我。
两张相似的照片,导入路径,即可使用。

#include
#include
#include

using namespace cv;
using namespace std;


Mat img1, img2;
void ORB_demo(int, void*);
int main(int argc, char** argv)
{
	 img1 = imread("D:/test/box.png");//替换你自己的路径
	 img2 = imread("D:/test/box_in_scene.png");
	if (!img1.data|| !img2.data)
	{
		cout << "图片未找到!" << endl;
		return -1;
	}
	namedWindow("ORB_demo",CV_WINDOW_AUTOSIZE);
	
	ORB_demo(0,0);
	
	imshow("input image of box",img1);
	imshow("input image of box_in_scene", img2);

	
	waitKey(0);
	return 0;


}

/*---------------检测与匹配--------------*/
void ORB_demo(int, void *)
{
	int Hession = 400;
	double t1 = getTickCount();
	//特征点提取
	Ptr<ORB> detector = ORB::create(400);
	vector<KeyPoint> keypoints_obj;
	vector<KeyPoint> keypoints_scene;
	//定义描述子
	Mat descriptor_obj, descriptor_scene;
	//检测并计算成描述子
	detector->detectAndCompute(img1, Mat(), keypoints_obj, descriptor_obj);
	detector->detectAndCompute(img2, Mat(), keypoints_scene, descriptor_scene);

	double t2 = getTickCount();
	double t = (t2 - t1) * 1000 / getTickFrequency();
	//特征匹配
	FlannBasedMatcher fbmatcher(new flann::LshIndexParams(20, 10, 2));
	vector<DMatch> matches;
	//将找到的描述子进行匹配并存入matches中
	fbmatcher.match(descriptor_obj, descriptor_scene, matches);

	double minDist = 1000;
	double maxDist = 0;
	//找出最优描述子
	vector<DMatch> goodmatches;
	for (int i = 0; i < descriptor_obj.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist < minDist)
		{
			minDist=dist ;
		}
		if (dist > maxDist)
		{
			maxDist=dist;
		}

	}
	for (int i = 0; i < descriptor_obj.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist < max(2 * minDist, 0.02))
		{
			goodmatches.push_back(matches[i]);
		}
	}
	Mat orbImg;

	drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodmatches, orbImg,
		Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

	//----------目标物体用矩形标识出来------------
	vector<Point2f> obj;
	vector<Point2f>scene;
	for (size_t i = 0; i < goodmatches.size(); i++)
	{
		obj.push_back(keypoints_obj[goodmatches[i].queryIdx].pt);
		scene.push_back(keypoints_scene[goodmatches[i].trainIdx].pt);
	}
	vector<Point2f> obj_corner(4);
	vector<Point2f> scene_corner(4);
	//生成透视矩阵
	Mat H = findHomography(obj, scene, RANSAC);

	obj_corner[0] = Point(0, 0);
	obj_corner[1] = Point(img1.cols, 0);
	obj_corner[2] = Point(img1.cols, img1.rows);
	obj_corner[3] = Point(0, img1.rows);
	//透视变换
	perspectiveTransform(obj_corner, scene_corner, H);
	Mat resultImg=orbImg.clone();
	

	for (int i = 0; i < 4; i++)
	{
		line(resultImg, scene_corner[i]+ Point2f(img1.cols, 0), scene_corner[(i + 1) % 4]+ Point2f(img1.cols, 0), Scalar(0, 0, 255), 2, 8, 0);
	}
	imshow("result image",resultImg);

	


	cout << "ORB执行时间为:" << t << "ms" << endl;
	cout << "最小距离为:" <<minDist<< endl;
	cout << "最大距离为:" << maxDist << endl;
	imshow("ORB_demo", orbImg);
}

关于具体的理论部分可以参考下面两篇文章:
参考文章:https://blog.csdn.net/gaotihong/article/details/78712017
参考文章:https://blog.csdn.net/guoyunfei20/article/details/78792770

你可能感兴趣的:(特征匹配检测算法,算法,c++,开发语言)