复现PREVIeW

环境准备

linux系统上已经安装了opencv3.4.0,路径是
OPENCV_INCLUDE=/usr/local/include
OPENCV_LIB_PATH=/usr/local/include/lib
然而作者提供的代码里,需要的环境是opencv2,为了更顺畅地复现代码,我们就在系统中再装一个opencv2.4.13.7。首先,去github上下载opencv2.4.13.7的源码,然后把它解压,得到opencv-2.4.13.7的文件夹,接下来的步骤是:

cd opencv-2.4.13.7 
mkdir build
cd build
//依赖项就不安装了,因为之前装过了
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local/include/opencv2.4.13.7 ..
sudo make -j8
sudo make install

其中在make的过程中,出现了错误:

../../lib/libopencv_highgui.so.2.4.13: undefined reference to `png_set_longjmp_fn'

看网上说(link),是libpng太老了,但网上所说的方法并没有解决我的问题,经过自己摸索,发现可以这样做:
1.打开opencv2.4.13.7中的CMakeLists.txt,定位到840行左右,找到:

if(WITH_PNG)
  status("    PNG:"        PNG_FOUND     THEN "${PNG_LIBRARY} (ver ${PNG_VERSION})"              ELSE "build (ver ${PNG_VERSION})")

把它修改为:

status("    PNG:"        PNG_FOUND     THEN "build (ver ${PNG_VERSION})"              ELSE "build (ver ${PNG_VERSION})")

然后这个bug就解决了,就可以接着编译了。我对这个的理解就是,找到png库之后,重新进行编译,因为我看系统库里有一个libpng12,还有一个libpng16…(因为是解决问题后几天才进行此纪录,所以当时具体怎么想的我记不清了)

复现代码

进入PREVIeW文件夹,里面有一个MakeFile文件,据作者介绍link,直接运行脚本:

sh buildDesktop.sh

即可进行编译。编译过程比较顺利,最终在Desktop_bin文件夹下生成可执行文件demo,在运行该文件时,会报错:

symbol lookup error: ./Desktop_bin/demo: undefined symbol: _ZN2cv15FeatureDetector6createERKNSt7

反正一开始就会报这种undefined symbol的错误,我一直以为这上面显示的是乱码,根本无从下手,但是定睛一看,上面会显示是哪个里面存在未定义的字符,比如上面这个报错里就有字眼FeatureDetector::create,这是opencv里面的内容呀,根据网上的介绍,我们可以用以下命令查看可执行文件demo链接的库有哪些:

ldd ./Desktop_bin/demo

得到结果:
在这里插入图片描述
可以看到,有关opencv的几个库,都链接到了

/home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/

而理想中的情况应该是链接到我们编译生成好的opencv2.4.13.7库中,即

/usr/local/include/opencv2.4.13.7/lib/

这也就是说编译时用到的动态库和运行时用到的动态库不一致,导致错误,虽然我也不知道为啥这么不智能。可以看到MakeFile中关于opencv库的语句是:

OPENCV_INCLUDE=/usr/local/include/opencv2.4.13.7/include
OPENCV_LIB_PATH=/usr/local/include/opencv2.4.13.7/lib

OBJS = $(TARGET_DIR)/image.o $(TARGET_DIR)/feature_extractor.o $(TARGET_DIR)/image_matching.o $(TARGET_DIR)/image_stream.o $(TARGET_DIR)/sequence.o $(TARGET_DIR)/sequence_matching.o $(TARGET_DIR)/sequence_stream.o $(TARGET_DIR)/vocabulary_tree.o $(TARGET_DIR)/PREVIeW.o $(TARGET_DIR)/demo.o
INCS = -I3rd_party/Eigen -I3rd_party/tbb/include/desktop -Ijni/headers -I$(OPENCV_INCLUDE)
LIBS_PATHS = -L$(OPENCV_LIB_PATH) -L3rd_party/tbb/lib/desktop/intel64/gcc4.4

COMPILER_FLAGS = -std=c++11 -O3 -fPIC -Xlinker -fexceptions -ffunction-sections -funwind-tables \
  -fstack-protector -no-canonical-prefixes\
  -fpermissive -fexceptions -fomit-frame-pointer -fno-strict-aliasing \
  -finline-limit=64 -D__DESKTOP__ -Wa,--noexecstack

LINKER_FLAGS = -fPIC

LDFLAGS = -L$(OPENCV_LIB_PATH)
LIBS = -lopencv_core -L$(OPENCV_LIB_PATH) -lopencv_nonfree -L$(OPENCV_LIB_PATH) -lopencv_highgui -L$(OPENCV_LIB_PATH) -lopencv_imgproc -L$(OPENCV_LIB_PATH) -lopencv_features2d -L$(OPENCV_LIB_PATH) -lopencv_flann -ltbb

其中倒数第二句代码LDFLAGS是我自己加的,我以为这样具体指定搜索库的路径就能解决问题,但实际上并不能,这样加完以后,重新编译生成的可执行文件demo链接的动态库仍然是

/home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/

好吧,既然这么执着地链接到这个地方,那我就使用一点暴力手段,直接修改软连接:

sudo ln -snf /usr/local/include/opencv2.4.13.7/lib/libopencv_core.so.2.4 /home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/libopencv_core.so.2.4
sudo ln -snf /usr/local/include/opencv2.4.13.7/lib/libopencv_features2d.so.2.4 /home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/libopencv_features2d.so.2.4
sudo ln -snf /usr/local/include/opencv2.4.13.7/lib/libopencv_imgproc.so.2.4 /home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/libopencv_imgproc.so.2.4
sudo ln -snf /usr/local/include/opencv2.4.13.7/lib/libopencv_nonfree.so.2.4 /home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/libopencv_nonfree.so.2.4
sudo ln -snf /usr/local/include/opencv2.4.13.7/lib/libopencv_highgui.so.2.4 /home/yuwei/anaconda3/pkgs/opencv-2.4.11-nppy27_0/lib/libopencv_highgui.so.2.4

然后就不会报undefined symbol的错误了,这个bug已解决,接下来安心跑代码。

复现时需要注意的是如何把用DBoW3生成的.yml格式的字典进行导入,为此需要修改相应的代码。
导入到一定数量的图片时,出现Segmentation fault,我以为是数组定义问题。然而由于我不会在linux系统中调试C++,所以就手动cout进行“调试”,调试到最后发现,程序没问题,是机器的内存不足了,所以就修改参数文件,使每张图片提取的ORB特征数量由500降到400。

temporal consistency

以前一直错误理解该术语的意思,今天看了程序才明白。

unsigned int max_imageMatchesAggregation = imageMatchesAggregation.maxCoeff();

		if (float(max_imageMatchesAggregation)/float(lastSeq_image_members_Size) > TEMPORAL_CONSISTENCY_TOLERANCE ) // if the majority of matches have been done with the same image from the matched_sequence = if that database image hase very few feature points
		{
			imageMatches.resize(0);
			return false;
		}

现在有当前序列lastSeq和匹配序列matchedSeq,我们为lastSeq中的每一幅图像在matchedSeq中找到最为相似的图像,max_imageMatchesAggregation就是matchedSeq中的图像被认为是最相似图像的最大次数,极端情况下,if中的条件分子等于分母,这意味着lastSeq中的每一幅图像都只与matchedSeq中的同一幅图像最匹配,这就不符合时间一致性,可能只是个外表相似的falsepositive,需要滤除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值