Environment

  • Operating System: Win 10
  • Android Studio: Version 4.2
  • SDK: API 26: Android 8.0(Oreo)
  • Requirement: OpenCV

DBoW2的运行需要OpenCV,导入步骤详见在安卓项目中引入OpenCV库

Introduction

DBoW2 is an improved version of the DBow library, an open source C++ library for indexing and converting images into a bag-of-word representation. It implements a hierarchical tree for approximating nearest neighbours in the image feature space and creating a visual vocabulary. DBoW2 also implements an image database with inverted and direct files to index images and enabling quick queries and feature comparisons. The main differences with the previous DBow library are:

  • DBoW2 classes are templated, so it can work with any type of descriptor.
  • DBoW2 is shipped with classes to directly work with ORB or BRIEF descriptors.
  • DBoW2 adds a direct file to the image database to do fast feature comparison. This is used by DLoopDetector.
  • DBoW2 does not use a binary format any longer. On the other hand, it uses the OpenCV storage system to save vocabularies and databases. This means that these files can be stored as plain text in YAML format, making compatibility easier, or compressed in gunzip format (.gz) to reduce disk usage.
  • Some pieces of code have been rewritten to optimize speed. The interface of DBoW2 has been simplified.
  • For performance reasons, DBoW2 does not support stop words.

DBoW2 requires OpenCV and the Boost::dynamic_bitset class in order to use the BRIEF version.

DBoW2, along with DLoopDetector, has been tested on several real datasets, yielding an execution time of 3 ms to convert the BRIEF features of an image into a bag-of-words vector and 5 ms to look for image matches in a database with more than 19000 images.

Step1

创建以Native C++为模板的安卓项目

  1. 打开Android Studio并点击创建项目

1

  1. 选择Native C++模板并点击Next

2

  1. 填写相应字段后点击Next

3

  1. 选择C++版本并点击Finish创建项目
  • 这里我选择的是标准C++14

4

Step2

官网Github仓库下载DBoW2源码并导入到项目中

  1. 将源码解压到本地
  2. /main/cpp/路径下创建DBoW2文件夹用来存放源码
  3. 将下载好的源码中的includesrc放在刚刚创建的文件夹中

5

  1. 修改CMakeLists.txt文件,添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
####### OpenCV #######

set( OpenCV_DIR D:\\AndroidStudio\\OpenCV-android-sdk\\sdk\\native\\jni )
find_package(OpenCV REQUIRED)

####### ###### #######

####### DBoW2 #######

include_directories(DBoW2/include/DBoW2)

set(HDRS
DBoW2/include/DBoW2/BowVector.h DBoW2/include/DBoW2/FBrief.h
DBoW2/include/DBoW2/QueryResults.h DBoW2/include/DBoW2/TemplatedDatabase.h DBoW2/include/DBoW2/FORB.h
DBoW2/include/DBoW2/DBoW2.h DBoW2/include/DBoW2/FClass.h DBoW2/include/DBoW2/FeatureVector.h
DBoW2/include/DBoW2/ScoringObject.h DBoW2/include/DBoW2/TemplatedVocabulary.h)
set(SRCS
DBoW2/src/BowVector.cpp DBoW2/src/FBrief.cpp DBoW2/src/FORB.cpp
DBoW2/src/FeatureVector.cpp DBoW2/src/QueryResults.cpp DBoW2/src/ScoringObject.cpp)

add_library(DBoW2 SHARED ${HDRS} ${SRCS})

target_link_libraries(DBoW2 ${OpenCV_LIBS})

####### ##### #######
  1. 同步编译
  • FileSync with Gradle Files
  • 若结果如下所示,说明引入成功

6

Step3

编码测试

  1. main/cpp/DBoW2/src/路径下创建DBoW2-Test.cpp作为测试程序

7

  1. 修改CMakeLists.txt文件,添加如下内容
  • 由于Step2CMakeLists.txt未使用AUX_SOURCE_DIRECTORY或类似的方法获取源文件,而是逐一列出,所以这里需要手动添加
  • 修改内容如下,其他内容不变
1
2
3
4
set(SRCS
DBoW2/src/BowVector.cpp DBoW2/src/FBrief.cpp DBoW2/src/FORB.cpp
DBoW2/src/FeatureVector.cpp DBoW2/src/QueryResults.cpp DBoW2/src/ScoringObject.cpp
DBoW2/src/DBoW2-Test.cpp)
  1. 同步编译
  2. DBoW2-Test文件中添加测试代码,如下所示
  • 在其中引入DBoW2库中的头文件,以及声明一个相关的变量
  • 若程序可正常运行,说明DBoW2库引入成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <jni.h>
#include <string>

#include "BowVector.h"

using namespace std;
using namespace DBoW2;

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_androidstudiodbow2_MainActivity_DBoW2_1Test(
JNIEnv* env,
jobject) {
string DBoW2_Test_String = "DBoW2";
BowVector::iterator it;
return env->NewStringUTF(DBoW2_Test_String.c_str());
}
  1. 修改MainActivity.java中的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.example.androidstudiodbow2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import com.example.androidstudiodbow2.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
System.loadLibrary("DBoW2");
}

private ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

// Example of a call to a native method
TextView tv = binding.sampleText;
tv.setText(stringFromJNI());

// DBoW2
tv.setText(DBoW2_Test());

}

/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
public native String DBoW2_Test();
}
  1. 运行项目查看结果
  • MainActivity.java中原本将tv中的文本置为stringFromJNI()函数的返回值
  • 修改后应为我们自己编写的函数的结果,即DBoW2

8

导入成功!