最近刚接手一个项目:从给定的布料图片中在布料库中寻找相似或相同的布料。
刚开始把项目想的很复杂,深度学习,机器学习都想了一遍,感觉无从下手。查阅资料想到自己之前做过全景拼接,灵感就来了,使用图像的特征描述子不就可以基本解决问题了。
如上是少量的样本库,
#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