vs2015使用SiftGPU

环境:win10、vs2015、x64

编译过程参考:

  1. http://www.cnblogs.com/wangguchangqing/p/10132052.html
  2. https://www.cnblogs.com/gaoxiang12/p/5149067.html

需要的第三方库:

  1. Glew
  2. DevIL-Windows-SDK-1.8.0

使用:

  1. 项目属性设置include路径到SiftGPU目录下
  2. 项目属性设置库路径到编译生成的SIFTGPU.lib路径下
  3. 将动态库SiftGPU.dll、DevIL.dll、glew32.dll拷贝到工程目录

测试代码(需配置OpenCV,这里不介绍配置过程):

SiftGPU.h

#ifndef _SIFTGPU_H
#define _SIFTGPU_H

#include <Windows.h>
#include <gl\GL.h>
#include <opencv2\opencv.hpp>
#include <SiftGPU\SiftGPU.h>

using namespace std;
using namespace cv;

enum InitStatus {
	INIT_OK,
	INIT_IS_NOT_SUPPORT,
	INIT_VERIFY_FAILED
};

class GpuFeatureDetector {

	private:
		SiftGPU *m_siftGpuDetector;
		SiftMatchGPU *m_siftGpuMatcher;

		//m_maxMatch是进行匹配时,最多的匹配点的个数,默认为4096
		int m_maxMatch;

	public:
		GpuFeatureDetector() = default;
		~GpuFeatureDetector() {
			if (m_siftGpuDetector) 
				delete m_siftGpuDetector;
			if (m_siftGpuMatcher)  
				delete m_siftGpuMatcher;
		}
		InitStatus create() {
			m_siftGpuDetector = new SiftGPU();

			char* myargv[4] = { "-fo","-1","-v","1" };
			m_siftGpuDetector->ParseParam(4, myargv);
			// Set edge threshold, dog threshold

			if (m_siftGpuDetector->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) {
				cerr << "SiftGPU is not supported!" << endl;
				return InitStatus::INIT_IS_NOT_SUPPORT;
			}

			m_siftGpuMatcher = new SiftMatchGPU();
			m_siftGpuMatcher->VerifyContextGL();

			m_maxMatch = 4096;

			return INIT_OK;
		}

		void detectAndCompute(const Mat &img, Mat &descriptors, vector<KeyPoint> &kpts) {
			clock_t startTimeDetector = clock();

			//必须是RGB图像
			assert(img.channels() == 3); 

			m_siftGpuDetector->RunSIFT(img.cols, img.rows, img.data, GL_RGB, GL_UNSIGNED_BYTE);


			auto num1 = m_siftGpuDetector->GetFeatureNum();

			vector<float> des(128 * num1);
			vector<SiftGPU::SiftKeypoint> keypoints(num1);

			m_siftGpuDetector->GetFeatureVector(&keypoints[0], &des[0]);

			// Trans to Mat
			Mat m(des);
			descriptors = m.reshape(1, num1).clone();

			for (const SiftGPU::SiftKeypoint &kp : keypoints) {
				KeyPoint t(kp.x, kp.y, kp.s, kp.o);
				kpts.push_back(t);
			}

			clock_t endTimeDetector = clock();
			cout << "cost time by feature detected: "
				<< static_cast<double>(endTimeDetector - startTimeDetector) / CLOCKS_PER_SEC
				<< endl;
		}

		void transToRootSift(const cv::Mat &siftFeature, cv::Mat &rootSiftFeature) {
			for (int i = 0; i < siftFeature.rows; i++) {
				// Conver to float type
				Mat f;
				siftFeature.row(i).convertTo(f, CV_32FC1);

				normalize(f, f, 1, 0, NORM_L1); // l1 normalize
				sqrt(f, f); // sqrt-root  root-sift
				rootSiftFeature.push_back(f);
			}
		}

		int gpuMatch(const Mat &des1, const Mat &des2, vector<DMatch>& matches) {
			clock_t startTimeMatch = clock();

			m_siftGpuMatcher->SetDescriptors(0, des1.rows, (float*)des1.data);
			m_siftGpuMatcher->SetDescriptors(1, des2.rows, (float*)des2.data);

			int(*match_buf)[2] = new int[m_maxMatch][2];

			auto matchNum = m_siftGpuMatcher->GetSiftMatch(m_maxMatch, match_buf);

			for (int i = 0; i < matchNum; i++) {
				DMatch dm(match_buf[i][0], match_buf[i][1], 0);
				matches.push_back(dm);
			}

			delete[] match_buf;

			clock_t endTimeMatch = clock();
			cout << "cost time by match: "
				<< static_cast<double>(endTimeMatch - startTimeMatch) / CLOCKS_PER_SEC
				<< endl;

			return matchNum;
		}

};

#endif // !_SIFTGPU_H

main.cpp

#include "SiftGPU.h"
#include <opencv2\opencv.hpp>
#include <iostream>
#include <string>
#include <vector>

using namespace std;
using namespace cv;

int main(int argc, char **argv) {
	char imageDir[] = "..\\解帧";

	GpuFeatureDetector fp;
	InitStatus initState = fp.create();
	if (initState != InitStatus::INIT_OK)
	{
		exit(0);
	}

	Mat image1, image2, des1, des2;
	vector<KeyPoint> kp1, kp2;
	vector<DMatch> matches;
	for (int i = 0; i < 200; i++) {
		for (int j = i + 1; j < 200; j++) {
			char imgPath1[256];
			sprintf(imgPath1, "%s\\%04d.jpg", imageDir, i);
			image1 = imread(imgPath1, IMREAD_UNCHANGED);

			char imgPath2[256];
			sprintf(imgPath2, "%s\\%04d.jpg", imageDir, j);
			image2 = imread(imgPath2, IMREAD_UNCHANGED);

			kp1.clear();
			kp2.clear();
			matches.clear();

			fp.detectAndCompute(image1, des1, kp1);
			fp.detectAndCompute(image2, des2, kp2);

			fp.gpuMatch(des1, des2, matches);

			Mat matchImg;
			drawMatches(image1, kp1, image2, kp2, matches, matchImg);
			imshow("matchImg", matchImg);
			waitKey(10);
		}
	}
}

运行结果如下:

如果自己不想进行编译的话,可以直接下载我编译好的库。

https://download.csdn.net/download/llfjcmx/11041304

扫描二维码关注公众号,回复: 8646018 查看本文章
发布了47 篇原创文章 · 获赞 23 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/llfjcmx/article/details/88683104