【opencv3.4.1-基于图像特征描述子的物体查找】

最近刚接手一个项目:从给定的布料图片中在布料库中寻找相似或相同的布料。

刚开始把项目想的很复杂,深度学习,机器学习都想了一遍,感觉无从下手。查阅资料想到自己之前做过全景拼接,灵感就来了,使用图像的特征描述子不就可以基本解决问题了。

如上是少量的样本库,



#include<opencv2/opencv.hpp>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<sstream>
#include<vector>
#include <iostream>
#include<fstream>

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

int main() {
	const char *p = "list.txt";
	ifstream fin(p);
	string str;
	Mat image01 = imread("1.jpg");
	imshow("原始测试图像", image01);
	Ptr<SurfFeatureDetector> detector = SurfFeatureDetector::create(800);
	vector<int>index;
	resize(image01, image01, Size(512, 512));

	double start = static_cast<double>(getTickCount());
	


	while (getline(fin, str)) {
		if (str.length() != 0) {
			str = "C:\\Users\\wangz\\Desktop\\picture\\" + str;

			Mat image02 = imread(str);
			if (image02.empty()) {
				cout << "none" << endl;

			}
			resize(image02, image02, Size(512, 512));
			imshow("a", image02);

			Mat srcImage1, srcImage2;
			cvtColor(image01, srcImage1, CV_RGB2GRAY);
			cvtColor(image02, srcImage2, CV_RGB2GRAY);
			vector<cv::KeyPoint> key_points_1, key_points_2;

			Mat dstImage1, dstImage2;
			detector->detectAndCompute(srcImage1, Mat(), key_points_1, dstImage1);
			detector->detectAndCompute(srcImage2, Mat(), key_points_2, dstImage2);//可以分成detect和compute

			Mat img_keypoints_1, img_keypoints_2;
			drawKeypoints(srcImage1, key_points_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
			drawKeypoints(srcImage2, key_points_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT);

			Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
			vector<DMatch>mach;

			matcher->match(dstImage1, dstImage2, mach);

			//sort(mach.begin(), mach.end()); //特征点排序	
			double Max_dist = 0;
			double Min_dist = 100;
			for (int i = 0; i < dstImage1.rows; i++)
			{
				double dist = mach[i].distance;
				if (dist <= Min_dist)Min_dist = dist;
				if (dist > Max_dist)Max_dist = dist;
			}
			std::cout << "最短距离" << Min_dist << endl;
			std::cout << "最长距离" << Max_dist << endl;

			vector<DMatch>goodmaches;
			for (int i = 0; i < dstImage1.rows; i++)
			{
				if (mach[i].distance < 2 * Min_dist)
					goodmaches.push_back(mach[i]);
			}
			cout << goodmaches.size() << endl;
			index.push_back(goodmaches.size());
			cout << index.size() << endl;

			/*
			Mat img_maches;
			drawMatches(srcImage1, key_points_1, srcImage2, key_points_2, goodmaches, img_maches);
			vector<Point2f> imagePoints1, imagePoints2;

			for (int i = 0; i<10; i++) {
			imagePoints1.push_back(key_points_1[mach[i].queryIdx].pt);
			imagePoints2.push_back(key_points_2[mach[i].trainIdx].pt);
			}
			*/
		}

	}
	/*
	for (vector<int>::iterator it = index.begin(); it != index.end(); it++) {
		cout << *it << endl;
	}
	*/
	
	double time = ((double)getTickCount() - start) / getTickFrequency();;//开始时间
	cout << "time is "<<time << endl;
	

	vector<int>::iterator it = max_element(begin(index), end(index));
	std::cout << "max distance is" << *it << "index is" << distance(begin(index), it) << endl;


	for (vector<int>::iterator it1 = index.begin(); it1 != index.end(); it1++) {
	if (*it1 == *it) {
	index.erase(it1);
	it1--;
	}
	vector<int>::iterator it11 = max_element(begin(index), end(index));
	std::cout << "max distance is" << *it11 << "index is" << distance(begin(index), it11) << endl;

	}

	





	//灰度图转换


	waitKey(0);
	return 0;



}

经过测试我们发现,图像resize到512*512时候在我的surfacebook的处理器上平均耗时10s左右,运行如下:

dir /b >list.txt

最后分享一个GPU编译opencv的博客:https://blog.csdn.net/qq_15947787/article/details/78534272

https://blog.csdn.net/mangobar/article/details/80459866

猜你喜欢

转载自blog.csdn.net/qq_35054151/article/details/83146853