Changchang Wu-SiftGPU-Ubuntu16.04

API文档:

http://docs.ros.org/hydro/api/siftgpu/html/SiftGPU_8h.html 

visualsfm

https://github.com/mrquincle/visualsfm/blob/master/SiftGPU/src/ServerSiftGPU/server.cpp

可视化显示:

https://github.com/district10/sfmViewer

sudo apt-get install build-essential libgl1-mesa-dev
sudo apt-get install freeglut3-dev
sudo apt-get install libglew-dev libsdl2-dev libsdl2-image-dev libglm-dev libfreetype6-dev
sudo apt-get install libglu1-mesa-dev freeglut3-dev

写在前面的话,关于示例有两种

一种是SiftGPU *sift = *********;

原版示例就是这样,https://github.com/pitzer/SiftGPU/blob/master/src/TestWin/SimpleSIFT.cpp

一种是 SiftGPU sift;

高翔的示例是这样 SLAM拾萃(3):siftGPU

cmake_minimum_required(VERSION 2.8.3)
project(test_siftgpu)

# OpenCV依赖
find_package( OpenCV REQUIRED )

# OpenGL
find_package(OpenGL REQUIRED)

# GLUT
find_package(GLUT REQUIRED)

# Glew
find_package(GLEW REQUIRED)

# SiftGPU:手动设置其头文件与库文件所在位置
include_directories("/home/spple/CLionProjects/SIFT-GPU/src/SiftGPU/" ${OpenGL_INCLUDE_DIR})
set(SIFTGPU_LIBS "/home/spple/CLionProjects/SIFT-GPU/cmake-build-debug/src/SiftGPU/libsiftgpu.so")

add_executable( testSIFTGPU main.cpp )

target_link_libraries( testSIFTGPU
    ${OpenCV_LIBS}
    ${SIFTGPU_LIBS}
    ${GLEW_LIBRARIES} ${GLUT_LIBRARIES} ${OPENGL_LIBRARIES}
)

参考文章:

https://www.cnblogs.com/RichardYao/p/9907860.html

SiftGPU在Ubuntu和Windows下的编译与使用

https://www.cnblogs.com/wangguchangqing/p/10132052.html

SLAM拾萃(3):siftGPU

https://www.cnblogs.com/gaoxiang12/p/5149067.html

https://github.com/pitzer/SiftGPU/pull/3/commits/831aa0d3fda201afd94d930bf3850c7cba5e499e

https://blog.csdn.net/qq_27550989/article/details/73614758

 

还有别人直接处理好的Ubuntu版本:

https://github.com/QianshengGu/SiftGPU_Linux

或者修改:

第一处:

SiftGPU/src/SiftGPU/SiftGPU.h文件,在上头加入一个
#include

第二处:

SiftGPU/src/SiftGPU/CMakeLists.txt

删除find_package(Glew)
添加find_package(GLEW)

第三处:

src/SiftGPU/LiteWindow.h:

virtual ~LiteWindow() { if(glut_id > 0) glutDestroyWindow(glut_id); }

修改为

	virtual ~LiteWindow()
	{
		if(glut_id > 0)
		{
			int argc = 0;
			char** argv;
			glutInit(&argc, argv);
			glutDestroyWindow(glut_id);
		}
	}

关于第三处这个问题,其实是一个内存释放问题,你用上面的也可以通过,

如果你想知道怎么不用上面的改,请看一下我之前的博客:

SiftGPU一些细节整理

https://blog.csdn.net/baidu_40840693/article/details/84503083

通过这种改法,不用改 virtual ~LiteWindow() { if(glut_id > 0) glutDestroyWindow(glut_id); }

我个人觉得关于内存释放的改法才是问题的解决办法所在

 

main.cpp

关于SLAM拾萃(3):siftGPU这个例子,有点问题

彩图的话一些地方需要改:

sift.RunSIFT(width, height, img.data, GL_BGR, GL_UNSIGNED_BYTE);

具体看我之前的博客:

https://blog.csdn.net/baidu_40840693/article/details/84503083

// SiftGPU模块
#include 

//标准C++
#include 
#include 

// OpenCV图像
#include 
#include 

// boost库中计时函数
#include 

// OpenGL
#include 

using namespace std;

int main( int argc, char** argv)
{
    //声明SiftGPU并初始化
    SiftGPU sift;
    char* myargv[4] ={ "-fo", "-1", "-v", "1"};
    sift.ParseParam(4, myargv);

    //检查硬件是否支持SiftGPU
    int support = sift.CreateContextGL();
    if ( support != SiftGPU::SIFTGPU_FULL_SUPPORTED )
    {
        cerr<<"SiftGPU is not supported!"<cmake_minimum_required(VERSION 2.8.3)
project(test_siftgpu)

# OpenCV依赖
find_package( OpenCV REQUIRED )

# OpenGL
find_package(OpenGL REQUIRED)

# GLUT
find_package(GLUT REQUIRED)

# Glew
find_package(Glew REQUIRED)

# SiftGPU:手动设置其头文件与库文件所在位置
include_directories("/home/xiang/Downloads/SiftGPU/src/SiftGPU/" ${OpenGL_INCLUDE_DIR})
set(SIFTGPU_LIBS "/home/xiang/Downloads/SiftGPU/bin/libsiftgpu.so")

add_executable( testSIFTGPU main.cpp )

target_link_libraries( testSIFTGPU
    ${OpenCV_LIBS}
    ${SIFTGPU_LIBS}
    ${GLEW_LIBRARIES} ${GLUT_LIBRARIES} ${OPENGL_LIBRARIES}
)

还遇到过一个:

CMake Error at src/TestWin/CMakeLists.txt:3 (find_package):
  By not providing "FindGlEW.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "GlEW", but
  CMake did not find one.

  Could not find a package configuration file provided by "GlEW" with any of
  the following names:

    GlEWConfig.cmake
    glew-config.cmake

  Add the installation prefix of "GlEW" to CMAKE_PREFIX_PATH or set
  "GlEW_DIR" to a directory containing one of the above files.  If "GlEW"
  provides a separate development package or SDK, be sure it has been
  installed.

 参考:

https://www.cnblogs.com/gaoxiang12/p/5149067.html

因为我使用的是clion,去找的时候发现有:

/home/spple/clion-2018.2.5/bin/cmake/linux/share/cmake-3.12/Modules/FindGLEW.cmake

但是还是报错。定睛一看,。。。。好吧他是GlEW,加个软链接吧

ln -s FindGLEW.cmake FindGlEW.cmake,

或者修改:

SIFT-GPU/src/TestWin/CMakeLists.txt下的

find_package(GLEW REQUIRED)

新错误:

/home/spple/CLionProjects/SIFT-GPU/src/TestWin/SimpleSIFT.cpp:88:对‘dlopen’未定义的引用
/home/spple/CLionProjects/SIFT-GPU/src/TestWin/SimpleSIFT.cpp:102:对‘dlsym’未定义的引用
/home/spple/CLionProjects/SIFT-GPU/src/TestWin/SimpleSIFT.cpp:103:对‘dlsym’未定义的引用
/home/spple/CLionProjects/SIFT-GPU/src/TestWin/SimpleSIFT.cpp:286:对‘dlclose’未定义的引用

https://blog.csdn.net/qq_22122811/article/details/52738134

https://www.cnblogs.com/Rainlee007/p/6930386.html

https://bbs.csdn.net/topics/392137961

SIFT-GPU/src/TestWin/CMakeLists.txt:

find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(GLEW REQUIRED)

include_directories( ${GLEW_INCLUDE_DIRS} )

ADD_EXECUTABLE(SimpleSIFT SimpleSIFT.cpp)
TARGET_LINK_LIBRARIES(SimpleSIFT siftgpu)
TARGET_LINK_LIBRARIES(SimpleSIFT dl)
#ADD_EXECUTABLE(TestWinGlut TestWinGlut.cpp BasicTestWin.cpp )
#TARGET_LINK_LIBRARIES(TestWinGlut siftgpu)

set(CMAKE_VERBOSE_MAKEFILE ON)

编译成功,但是还有一种问题,

就是程序没反应,

Changchang Wu-SiftGPU-Ubuntu16.04_第1张图片

原来代码中是:

SIFT-GPU/src/TestWin/SimpleSIFT.cpp

    #ifdef _WIN32
        #ifdef _DEBUG
            HMODULE  hsiftgpu = LoadLibrary("siftgpu_d.dll");
        #else
            HMODULE  hsiftgpu = LoadLibrary("siftgpu.dll");
        #endif
    #else
        void * hsiftgpu = dlopen("libsiftgpu.so", RTLD_LAZY);
    #endif

但是我没找到 libsiftgpu.so,我编译出来的是:libsiftgpu.a

静态库动态库问题,我们改一下;

SIFT-GPU/src/SiftGPU/CMakeLists.txt

#siftgpu STATIC
#siftgpu SHARED
ADD_LIBRARY(siftgpu SHARED FrameBufferObject.cpp GlobalUtil.cpp GLTexImage.cpp ProgramGLSL.cpp
            ProgramGPU.cpp ShaderMan.cpp SiftGPU.cpp SiftPyramid.cpp PyramidGL.cpp SiftMatch.cpp)

好了,此时就有了 libsiftgpu.so

Changchang Wu-SiftGPU-Ubuntu16.04_第2张图片

在代码中给一个绝对路径就可以了:

SIFT-GPU/src/TestWin/SimpleSIFT.cpp

    #ifdef _WIN32
        #ifdef _DEBUG
            HMODULE  hsiftgpu = LoadLibrary("siftgpu_d.dll");
        #else
            HMODULE  hsiftgpu = LoadLibrary("siftgpu.dll");
        #endif
    #else
        void * hsiftgpu = dlopen("/home/spple/CLionProjects/SIFT-GPU/cmake-build-debug/src/SiftGPU/libsiftgpu.so", RTLD_LAZY);
    #endif

 

Changchang Wu-SiftGPU-Ubuntu16.04_第3张图片

成功运行了,至于这个新错误,我们前面遇到过:

彩图的话一些地方需要改:

sift.RunSIFT(width, height, img.data, GL_BGR, GL_UNSIGNED_BYTE);

具体看我之前的博客:

https://blog.csdn.net/baidu_40840693/article/details/84503083

或者直接用绝对路径载入,程序内部会将彩图转灰度

    if(sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) return 0;

    if(sift->RunSIFT("/home/spple/CLionProjects/SIFT-GPU/data/800-1.jpg"))
    {
        //Call SaveSIFT to save result to file, the format is the same as Lowe's
        //sift->SaveSIFT("../data/800./-1.sift"); //Note that saving ASCII format is slow

        //get feature count
        num1 = sift->GetFeatureNum();

        //allocate memory
        keys1.resize(num1);    descriptors1.resize(128*num1);

        //reading back feature vectors is faster than writing files
        //if you dont need keys or descriptors, just put NULLs here
        sift->GetFeatureVector(&keys1[0], &descriptors1[0]);
        //this can be used to write your own sift file.            
    }

    //You can have at most one OpenGL-based SiftGPU (per process).
    //Normally, you should just create one, and reuse on all images. 
    if(sift->RunSIFT("/home/spple/CLionProjects/SIFT-GPU/data/640-1.jpg"))
    {
        num2 = sift->GetFeatureNum();
        keys2.resize(num2);    descriptors2.resize(128*num2);
        sift->GetFeatureVector(&keys2[0], &descriptors2[0]);
    }

修改SIFT-GPU/src/TestWin/CMakeLists.txt::

find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(GLEW REQUIRED)
# OpenCV依赖
find_package( OpenCV REQUIRED )


include_directories( ${GLEW_INCLUDE_DIRS} )
include_directories( ${OpenGL_INCLUDE_DIR} )


ADD_EXECUTABLE(SimpleSIFT SimpleSIFT.cpp)
TARGET_LINK_LIBRARIES(SimpleSIFT siftgpu)
TARGET_LINK_LIBRARIES(SimpleSIFT dl)
target_link_libraries(SimpleSIFT
        ${OpenCV_LIBS}
        )
#ADD_EXECUTABLE(TestWinGlut TestWinGlut.cpp BasicTestWin.cpp )
#TARGET_LINK_LIBRARIES(TestWinGlut siftgpu)


set(CMAKE_VERBOSE_MAKEFILE ON)

SIFT-GPU/src/TestWin/SimpleSIFT.cpp:88:对‘dlopen’未定义的引用
SIFT-GPU/src/TestWin/SimpleSIFT.cpp:102:对‘dlsym’未定义的引用
SIFT-GPU/src/TestWin/SimpleSIFT.cpp:103:对‘dlsym’未定义的引用
SIFT-GPU/src/TestWin/SimpleSIFT.cpp:286:对‘dlclose’未定义的引用 

TARGET_LINK_LIBRARIES(SimpleSIFT dl)

在:SIFT-GPU/src/TestWin/SimpleSIFT.cpp

下添加头文件和修改代码:

#include 
#include 
#include 
#include 



    cv::Mat img1 = cv::imread("/home/spple/CLionProjects/SIFT-GPU/data/800-1.jpg", 1);
    cv::Mat grayImg1;
    cv::cvtColor(img1, grayImg1, CV_BGR2GRAY);
    int width1 = grayImg1.cols;
    int height1 = grayImg1.rows;

    if(sift->RunSIFT(width1, height1, img1.data, GL_BGR, GL_UNSIGNED_BYTE))
    {
        //Call SaveSIFT to save result to file, the format is the same as Lowe's
        //sift->SaveSIFT("../data/800-1.sift"); //Note that saving ASCII format is slow

        //get feature count
        num1 = sift->GetFeatureNum();

        //allocate memory
        keys1.resize(num1);    descriptors1.resize(128*num1);

        //reading back feature vectors is faster than writing files
        //if you dont need keys or descriptors, just put NULLs here
        sift->GetFeatureVector(&keys1[0], &descriptors1[0]);
        //this can be used to write your own sift file.            
    }

    //You can have at most one OpenGL-based SiftGPU (per process).
    //Normally, you should just create one, and reuse on all images.

    cv::Mat img2 = cv::imread("/home/spple/CLionProjects/SIFT-GPU/data/640-1.jpg", 1);
    cv::Mat grayImg2;
    cv::cvtColor(img2, grayImg2, CV_BGR2GRAY);
    int width2 = grayImg2.cols;
    int height2 = grayImg2.rows;
    if(    sift->RunSIFT(width2, height2, img2.data, GL_BGR, GL_UNSIGNED_BYTE))
    {
        num2 = sift->GetFeatureNum();
        keys2.resize(num2);    descriptors2.resize(128*num2);
        sift->GetFeatureVector(&keys2[0], &descriptors2[0]);
    }

 

Changchang Wu-SiftGPU-Ubuntu16.04_第4张图片

或者安装好devil

然后:

修改:

SIFT-GPU/src/SiftGPU/CMakeLists.txt

find_package(DevIL)



#FALSE 为开启DEVIL
SET(SIFTGPU_DISABLE_DEVIL FALSE)

makefile文件默认是开启devil的,但是CMAKELIST不是,我们开启后,很多地方就会使用devil去载入图像

 

 

最后可以改一下:修改SIFT-GPU/src/TestWin/CMakeLists.txt::

project(SimpleSIFT)
project(TestWinGlut)

find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(GLEW REQUIRED)
# OpenCV依赖
find_package( OpenCV REQUIRED )


include_directories( ${GLEW_INCLUDE_DIRS} )
include_directories( ${OpenGL_INCLUDE_DIR} )


ADD_EXECUTABLE(SimpleSIFT SimpleSIFT.cpp)
TARGET_LINK_LIBRARIES(SimpleSIFT siftgpu)
TARGET_LINK_LIBRARIES(SimpleSIFT dl)
target_link_libraries(SimpleSIFT
        ${OpenCV_LIBS}
        )

ADD_EXECUTABLE(TestWinGlut TestWinGlut.cpp BasicTestWin.cpp )
TARGET_LINK_LIBRARIES(TestWinGlut siftgpu)


set(CMAKE_VERBOSE_MAKEFILE ON)

关于TestWinGlut运行没反应是因为需要参数:

./TestWinGlut -i /home/spple/CLionProjects/SIFT-GPU/data/1600.jpg
./TestWinGlut -il ../data/list640.txt  
./TestWinGlut -il ../data/listx.txt
./TestWinGlut -i ../doc/evaluation/box.pgm -o ../doc/evaluation/box.siftgpu -w 3 -fo -1 -loweo -exit

 

Changchang Wu-SiftGPU-Ubuntu16.04_第5张图片




还有一种方式是:

https://www.cnblogs.com/wangguchangqing/p/10132052.html

通过本身的makefile去编译,我这边出现了和博客一样的问题:

src/SiftGPU/GLTexImage.cpp:47:23: fatal error: IL/il.h: 没有那个文件或目录
     #include "IL/il.h"
                       ^
compilation terminated.
makefile:140: recipe for target 'build/GLTexImage.o' failed
make: *** [build/GLTexImage.o] Error 1

在执行make 编译,如果遇到fatal error: IL/il.h: No such file or directory,使用下面的命令安装dev image library.

sudo apt-get install libdevil-dev


下列软件包有未满足的依赖关系:
 libdevil-dev : 依赖: liblcms2-dev 但是它将不会被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

sudo apt-get install liblcms2-dev

下列软件包有未满足的依赖关系:
 liblcms2-dev : 依赖: liblcms2-2 (= 2.6-3ubuntu2) 但是 2.6-3ubuntu2.1 正要被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

sudo apt-get install liblcms2-2

spple@spple:~/CLionProjects/SIFT-GPU$ sudo apt-get install liblcms2-2
正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
liblcms2-2 已经是最新版 (2.6-3ubuntu2.1)。
下列软件包是自动安装的并且现在不需要了:

我已经安装了一个不正确的依赖,所以这条路必须重新编译一个devil

然后地址加载makefile的文件上

使用vcpkg吧,等等突然找到了解决方法

找到了解决方式:

sudo apt install liblcms2-2=2.6-3ubuntu2
sudo apt-get install liblcms2-dev
sudo apt-get install libdevil-dev

这一块使用make 不要-j4

make clean

make 

Changchang Wu-SiftGPU-Ubuntu16.04_第6张图片

Changchang Wu-SiftGPU-Ubuntu16.04_第7张图片

生成的bin目录下的文件运行:

./SimpleSIFT

[SiftGPU Language]:	GLSL
[GPU VENDOR]:	Intel Open Source Technology Center
TEXTURE:	16384
Image size :	800x600
Image loaded :	/home/spple/CLionProjects/SIFT-GPU/data/800-1.jpg
#Features:	3359
#Features MO:	3927
[RUN SIFT]:	0.118

Image size :	640x480
Image loaded :	/home/spple/CLionProjects/SIFT-GPU/data/640-1.jpg
#Features:	2377
#Features MO:	2784
[RUN SIFT]:	0.047

[SiftMatchGPU]: GLSL

2276 sift matches were found;

如果使用cuda,那么找到SimpleSIFT.cpp

修改为:

    //char * argv[] = {"-fo", "-1",  "-v", "1"};//
    char * argv[] = {"-fo", "-1", "-v", "1", "-cuda", "0"};

使用makefile重新编译,使用:

spple@spple:~/CLionProjects/SIFT-GPU/bin$ ./SimpleSIFT 
NOTE: changing maximum texture dimension to 32768

[SiftGPU Language]:	CUDA
Image size :	800x600
Image loaded :	/home/spple/CLionProjects/SIFT-GPU/data/800-1.jpg
#Features:	3348
#Features MO:	3911
[RUN SIFT]:	0.09

Image size :	640x480
Image loaded :	/home/spple/CLionProjects/SIFT-GPU/data/640-1.jpg
#Features:	2372
#Features MO:	2767
[RUN SIFT]:	0.029

NOTE: changing maximum texture dimension to 32768
[SiftMatchGPU]: CUDA

2247 sift matches were found;

 

暂时只有windows 还有Ubuntu的makefile可以开启使用cuda,

如果是Ubuntu的CmakeList.txt

SIFT-GPU/src/SiftGPU/CMakeLists.txt

SET(SIFTGPU_ENABLE_CUDA FALSE)

并没有用,还是会显示

---------------------------------------------------------------------------
CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable
solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile
----------------------------------------------------------------------------

 

./TestWinGlut -il /home/spple/CLionProjects/SIFT-GPU/data/list640.txt

[SiftGPU Language]:	GLSL
[GPU VENDOR]:	Intel Open Source Technology Center
TEXTURE:	16384

[Load Programs]:	begin ...
Filter: sigma = 1.51987, size = 13x13
Filter: sigma = 1.22627, size = 11x11
Filter: sigma = 1.54501, size = 13x13
Filter: sigma = 1.94659, size = 17x17
Filter: sigma = 2.45255, size = 21x21
Filter: sigma = 3.09002, size = 25x25
[Load Programs]:	0.394

[Load Input Image]:	begin ...
Image size :	640x480
Image loaded :	640-1.jpg
[Load Input Image]:	0.006

[Initialize Pyramid]:	begin ...
[Allocate Pyramid]:	640x480
[Allocate Pyramid]:	40MB
[Initialize Pyramid]:	0.006

[Build    Pyramid]:	begin ...
#0	0.004	0.001	0	0	0	0	|	0.006
#1	0.001	0	0	0	0	0	|	0.001
#2	0	0	0.001	0	0	0	|	0.001
#3	0	0	0	0	0	0	|	0
#4	0.001	0	0	0	0	0	|	0.001
[Build    Pyramid]:	0.009

[Detect Keypoints]:	begin ...
#0	0.003	0	0	|	0.003
#1	0	0	0	|	0
#2	0.001	0	0	|	0.001
#3	0.001	0	0	|	0.001
#4	0	0	0	|	0
	0.004
	0.005
[Detect Keypoints]:	0.009

[Get Feature List]:	begin ...
#0:	210	137	83	| 	430 :	(0.002)
#1:	72	40	19	| 	131 :	(0.001)
#2:	18	10	13	| 	41 :	(0)
#3:	3	5	2	| 	10 :	(0.001)
#4:	1	3	0	| 	4 :	(0)
#Features:	616
[Get Feature List]:	0.005

[Feature Orientations]:	begin ...
[Feature Orientations]:	0.003

[MultiO Feature List]:	begin ...
#Features MO:	726
[MultiO Feature List]:	0.001

[Download Keypoints]:	begin ...
[Download Keypoints]:	0

[Get Descriptor]:	begin ...
[Get Descriptor]:	0.005

[Gen. Display VBO]:	begin ...
[Gen. Display VBO]:	0.001
[RUN SIFT]:	0.046


./speed -i /home/spple/CLionProjects/SIFT-GPU/data/1600.jpg  -fo -1

Initialize and warm up...
Loading image: 73ms, Tex initialization: 66ms

Start 2x30 repetitions...
++++++++++++++++++++++++++++++
##############################

****************************************
[Feature Count]:	10998
[Average Time]:		113.133ms
[Average Speed]:	8.83913hz
[Build Pyramid]:	22.5667ms
[Detection]:		33.9ms
[Feature List]:		8.4ms
[Orientation]:		7.43333ms
[MO Feature List]:	1.36667ms
[Download Keys]:	0ms
[Descriptor]:		39.6ms
****************************************

./MultiThreadSIFT :

修改:

SIFT-GPU/src/TestWin/MultiThreadSIFT.cpp

int main()
{
    //NOTE that SiftGPU must be compiled with CUDA for this demo
    MultiThreadDemo thread1(0, "/home/spple/CLionProjects/SIFT-GPU/data/640-1.jpg");
    MultiThreadDemo thread2(1, "/home/spple/CLionProjects/SIFT-GPU/data/800-1.jpg");
    ......
}

运行时候出错:

CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable
solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile

修改 makefile

https://blog.csdn.net/yrc19950911/article/details/83785908

https://blog.csdn.net/hehehetanchaow/article/details/90378010


ifneq ($(simple_find_cuda), )
     siftgpu_enable_cuda = 1
else
    siftgpu_enable_cuda = 0
endif

........

siftgpu_cuda_options = -arch sm_61

关于GPU算力:

https://www.cnblogs.com/ahuo/p/6904820.html

Changchang Wu-SiftGPU-Ubuntu16.04_第8张图片

但是我这里只有一个GPU,0,1代表GPU的驱动号

    MultiThreadDemo thread1(0, "/home/spple/CLionProjects/SIFT-GPU/data/640-1.jpg");
    MultiThreadDemo thread2(1, "/home/spple/CLionProjects/SIFT-GPU/data/800-1.jpg");

GPU-SIFT封装:

https://www.cnblogs.com/wangguchangqing/p/10132052.html

#include 

#include 
#include 

#include 
#include 
#include 

#include 

using namespace std;
using namespace cv;

class GpuFeatureDetector{

    enum InitStatus{
        INIT_OK,
        INIT_IS_NOT_SUPPORT,
        INIT_VERIFY_FAILED
    };

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 &kpts){

        assert(img.channels() == 3); // RGB

        m_siftGpuDetector->RunSIFT(img.cols,img.rows,img.data,GL_RGB,GL_UNSIGNED_BYTE);
        auto num1 = m_siftGpuDetector->GetFeatureNum();

        vector des(128 * num1);
        vector 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);
        }     
    }

    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){
        
        m_siftGpuMatcher->SetDescriptors(0,des1.rows,des1.data);
        m_siftGpuMatcher->SetDescriptors(1,des2.rows,des2.data);

        int (*match_buf)[2] = new int[m_maxMatch][2];
        
        auto matchNum = m_siftGpuMatcher->GetSiftMatch(m_maxMatch,match_buf);
        
        delete[] match_buf;
        
        return matchNum;
    }

    int gpuMatch(const Mat &des1,const Mat &des2,vector& matches){
        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;
        return matchNum;
    }
private:
    SiftGPU *m_siftGpuDetector;
    SiftMatchGPU *m_siftGpuMatcher;

    int m_maxMatch;
};

int main()
{

    /////////////////////////////////////////////////////////////////////
    ///
    /// Opencv extract sift
    ///
    ///////////////////////////////////////////////////////////////////

    // Read image  
    auto detector = cv::xfeatures2d::SIFT::create();

    Mat des;
    vector kpts;

    string file1 = "/home/liqiang/Documents/shared/8.jpg";
    auto t = getTickCount();
    auto img = imread(file1);
    detector->detectAndCompute(img,noArray(),kpts,des);
    auto end = static_cast(getTickCount() - t) / getTickFrequency();
    cout << "OpenCV get sift consume:" << end << endl;
    cout << "count:" << kpts.size() << endl;


    ////////////////////////////////////////////////////////////////
    ///
    /// SiftGPU extract sift
    ///
    ///////////////////////////////////////////////////////////////
    // Declare sift and initlize
    SiftGPU sift;
    char* myargv[4] = {"-fo","-1","-v","0"};
    //char* myargv[5] = { "-m", "-s", "-unpa", "1"};
    //char* myargv[4] = {"-fo", "-1", "-cuda", "0"};
    sift.ParseParam(4,myargv);

    // Check hardware is support siftGPU
    int support = sift.CreateContextGL();
    if(support != SiftGPU::SIFTGPU_FULL_SUPPORTED){
        cerr << "SiftGPU is not supported!" << endl;
        return 2;
    }

    auto img1 = imread("/home/liqiang/Documents/shared/3.jpg");
    auto img2 = imread("/home/liqiang/Documents/shared/4.jpg");
    auto img3 = imread("/home/liqiang/Documents/shared/5.jpg");
    auto img4 = imread("/home/liqiang/Documents/shared/6.jpg");
    auto img5 = imread("/home/liqiang/Documents/shared/7.jpg");

    auto f = [&sift](Mat &img,vector &des,vector &kpts){
        
        auto t = getTickCount();
        sift.RunSIFT(img.cols,img.rows,img.data,GL_RGB,GL_UNSIGNED_BYTE);
        auto num1 = sift.GetFeatureNum();
        
        des.resize(128 * num1);
        kpts.resize(num1);
        sift.GetFeatureVector(&kpts[0],&des[0]);
        cout << "=======================================" << endl;
        cout << "width x height : " << img.cols << "x" << img.rows << endl;
        cout << "Features count:" << num1 << endl;
        cout << "Extract features,consume:" << static_cast(getTickCount() - t) / getTickFrequency() << endl;
    };


    vector des1,des2,des3,des4,des5;
    vector kpts1,kpts2,kpts3,kpts4,kpts5;

    f(img1,des1,kpts1);
    f(img2,des2,kpts2);
    f(img3,des3,kpts3);
    f(img4,des4,kpts4);
    f(img5,des5,kpts5);


    SiftMatchGPU matcher;
    matcher.VerifyContextGL();

    matcher.SetDescriptors(0,kpts1.size(),&des1[0]);
    matcher.SetDescriptors(1,kpts2.size(),&des2[0]);

    int (*match_buf)[2] = new int[kpts1.size()][2];
    t = getTickCount();
    int num_match = matcher.GetSiftMatch(kpts1.size(), match_buf);
    cout << "====================================" << endl;
    cout << "Match keypoints count:" << num_match << endl;
    end = static_cast(getTickCount() - t) / getTickFrequency();

    cout << "Match,consume:" << end << endl;


    ////////////////////////////////////////////////////////////////////
    ///
    /// Test class GpuFeatureDetector
    ///
    ///////////////////////////////////////////////////////////////////

    GpuFeatureDetector fp;
    fp.create();

    Mat des11,des22;
    vector kpts11,kpts22;

    fp.detectAndCompute(img1,des11,kpts11);
    fp.detectAndCompute(img2,des22,kpts22);

    vector matches;
    t = getTickCount();
    auto matcheNum = fp.gpuMatch(des11,des22,matches);
    cout << "gpu matche:" <<  static_cast(getTickCount() - t) / getTickFrequency() << endl;
    cout << "gpu match count:" << matcheNum << endl;

    Mat matchImg;
    drawMatches(img1,kpts11,img2,kpts22,matches,matchImg);
    imshow("gpu matches",matchImg);
    

    //////////////////////////////////////////////////////////////////////
    ///
    /// OpenCV extract sift and match
    ///
    ////////////////////////////////////////////////////////////////////
    Mat des111,des222;
    vector kpts111,kpts222;
    detector->detectAndCompute(img1,noArray(),kpts111,des111);
    detector->detectAndCompute(img2,noArray(),kpts222,des222);

    auto ov_matcher = DescriptorMatcher::create("FlannBased");
    const float minRatio = 0.8;
    const int k = 2;

    vector> knnMatches;
    vector betterMatches;

    t = getTickCount();
    ov_matcher->knnMatch(des111, des222, knnMatches, k);

    for (size_t i = 0; i < knnMatches.size(); i++) {
        const DMatch &bestMatch = knnMatches[i][0];
        const DMatch &betterMatch = knnMatches[i][1];

        float distanceRatio = bestMatch.distance / betterMatch.distance;
        if (distanceRatio < minRatio)
            betterMatches.push_back(bestMatch);
    }
    cout << "Opencv Match:" << static_cast(getTickCount() - t) / getTickFrequency() << endl;

    Mat ovMatchImg;
    drawMatches(img1,kpts111,img2,kpts222,betterMatches,ovMatchImg);

    imshow("opencv matches",ovMatchImg);

    waitKey();


    return 0;
}

你可能感兴趣的:(SLAM+SFM)