b y t i a n . z D e c by \ tian.z \ Dec by tian.z Dec - 2021 2021 2021
参考了文献1
系统 Ubuntu 20.04
语言 C++11
编译器 CMake 3.16
库依赖 Opencv 3.4.15 ,opencv-contrib , Glog
关于图像拼接的两篇综述23给出了几种解决方案:
从计算速度、实现难度和课程内容结合的方面综合考虑,本设计采用基于特征点的匹配方法。
对比主流的特征点提取方法,SIFT4 计算量较大,SURF5 作为SIFT的改进提升了运算速度。而ORB6特征主要面对实时性较强的系统设计牺牲了部分精度。综合考虑本设计提取SRUF特征。
特征匹配时,若使用暴力匹配不但需要很大的计算量,并且还存在大量的误匹配,效果较差。
故本设计使用FLANN匹配提升精度和速度。
但仍会存在误匹配,本设计筛选汉明距离小于最小距离的四倍的点作为好点去除误匹配,这是一种工程上的做法,不一定有理论依据。
本设计假设两张图片的特征点落在同一平面上,这样则可以通过单应性进行匹配分析。
对应地,二视图几何中有一种常见的矩阵:单应矩阵,它描述了两个平面之间的映射关系。
使用RANSAC提升鲁棒性,计算单应矩阵。
对于图像重叠区域,直接加权平滑算法处理拼接缝
P i x e l = α × P i x e l L + ( 1 − α ) × P i x e l R Pixel=\alpha×Pixel_L+(1-\alpha)× Pixel_R Pixel=α×PixelL+(1−α)×PixelR
项目地址:https://gitee.com/ztztt/simple-image-mosaic
scr/ 存放源码
include/ 头文件
lib/ 库文件
log/ glog日志
build/ 编译中间文件
bin/ 可执行文件
dataset/ 测试图片
计划先在master分支基于opencv的算法库把功能实现,如果后面有时间和兴趣,在develop分支把个别算法手写实现一下.
(估计是没有)
小知识,为什么我们都用’opencv2’而不是‘opencv3’呢,因为这个2不是版本号,而是基于C++写成的意思,最初opencv是用C写的.来源
刚一上手编译就报错,提示
undefined reference to `cv::Mat::~Mat()
.........
似乎是opencv没有链接进来,仔细检查,发现在src文件夹中的CMakeLists文件里这一行写错了:
target_link_libraries(ImageMosaic
${THIRD_PARTY_LIBS})
应该写成
target_link_libraries(run
${THIRD_PARTY_LIBS})
run是输出的可执行文件
add_executable(run run_image_mosaic.cpp)
再次编译,问题解决
在显示图像的时候别忘了加上waitKey(0);
要不然图像一闪而过就看不到了.
在CMakeList
find_package(Glog REQUIRED)
include_directories(${GLOG_INCLUDE_DIRS})
后面还要加上
link_libraries(glog)
才能正确链接到glog,否则编译器会报错
undefined reference to `google::........
fatal error: opencv2/nonfree/nonfree.hpp: No such file or directory
显然是没有nonfree这个库,网上给出的解决方案普遍是
sudo apt-get update
sudo add-apt-repository --yes ppa:xqms/opencv-nonfree
sudo apt-get update
sudo apt-get install libopencv-nonfree-dev
但我陷入了无尽的递归debug,最终我的大脑栈溢出了。网络上有好哥哥指出安装opencv-contrib库即可。
我顺藤摸瓜,来到了opencv-contrib的github
上按照说明装上了这个库,终于可以用哩.注意,这里要安装对应opencv版本的contrib库.
opencv3.4版本的contrib库里的surf在opencv2/xfeatures2d/nonfree.hpp
路径下.而毛神的书里写的
#include
已经不适用了,缅怀.
实际运行的时候,报错
This algorithm is patented and is excluded in this configuration; Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library in function 'create'
提示我们算法受版权保护,让我们改cmakelists里面一个选项,找到它,吧最后的参数OFF
改成ON
,再编译一遍opencv
OCV_OPTION(OPENCV_ENABLE_NONFREE "Enable non-free algorithms" ON)
OCV_OPTION(INSTALL_CREATE_DISTRIB "Change install rules to build the distribution package" ON )
还是不行.
笔者在opencv的社区里找到一篇帖子
,有好哥哥给出解决方案,删除cmakecache,带上参数重新用cmake编译一遍opencv:
cmake -DOPENCV_ENABLE_NONFREE:BOOL=ON -DOPENCV_EXTRA_MODULES_PATH=/home/tian/libs/opencv-3.4.15/opencv_contrib-3.4/modules ..
cmake结束后,可以看见提示 :
-- OpenCV modules:
-- To be built: aruco bgsegm bioinspired calib3d ccalib core datasets dnn dnn_objdetect dpm face features2d flann freetype fuzzy hdf hfs highgui img_hash imgcodecs imgproc line_descriptor ml objdetect optflow phase_unwrapping photo plot reg rgbd saliency sfm shape stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab viz xfeatures2d ximgproc xobjdetect xphoto
-- Disabled: world
-- Disabled by dependency: -
-- Unavailable: cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev cvv java matlab ovis python2 python3
-- Applications: tests perf_tests apps
-- Documentation: NO
-- Non-free algorithms: YES
最后一行告诉我们nonfree的算法已经可以用了,感谢网络上的好哥哥.
笔者第一次实际进行含有多个文件的项目开发,在此记录一下遇到的问题.
在src/目录下新建了文件match.cpp,希望在里面放一些函数的实现;在include/ImageMosaic目录下新建match.h文件,作为头文件进行函数的声明.同时match.cpp文件中#include "ImageMosaic/match.h"
,match.h文件中定义:
#pragma once
#ifndef MATCH_H
#define MATCH_H
#include "common_include.h"
......
#endif //MATCH_H
这样两个文件就关联起来了.注意,包含commom_include.h
时,两个文件的索引会略有区别.
这时直接编译不会通过,还要在src/下的MakeLists中加入:
target_sources(run PUBLIC "match.cpp")
编译通过,程序运行正常.
struct CV_EXPORTS DMatch
{
DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(std::numeric_limits::max()) {}
DMatch( int _queryIdx, int _trainIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
int queryIdx; // query descriptor index
int trainIdx; // train descriptor index
int imgIdx; // train image index
float distance;
// less is better
bool operator<( const DMatch &m ) const
{
return distance < m.distance;
}
};
DMatch结构体中包含了同一关键点在两张图片中的索引,可以用迭代器和原始关键点的cv::keyPoint类进行访问,写出来非常优雅.
这里坑了我好长时间
浅拷贝
B = A
B(A)
这类拷贝方法仅创建了新的矩阵头,共用同一个内存空间,在修改新对象的时候,旧对象也会改变。
深拷贝
B = A.clone()
A.copyTo(B)
这类拷贝方法为新的矩阵申请了新的内存空间,在修改新对象的时候,旧对象不会改变。
不赘述,参阅文献5 7 ,课程PPT
FLANN是一个在高维空间内快速最近邻域搜索的算法库,它包含了对于最近邻搜索效果最好的一些算法,和一个能够自动根据数据集选取最优的算法和参数的系统。FLANN基于C++写成并提供C,MATLAB,Python和Ruby的接口。翻译自项目Github地址。
文献8中,介绍了FLANN中使用的算法,包括随机kd树算法、优先搜索k-means树算法等
RANSAC9 是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。
https://blog.csdn.net/robinhjwy/article/details/79174914
单应(Homography)是射影几何中的概念,又称为射影变换。它把一个射影平面上的点(三维齐次矢量)映射到另一个射影平面上,并且把直线映射为直线,具有保线性质。总的来说,单应是关于三维齐次矢量的一种线性变换,可以用一个 3 × 3 3×3 3×3的非奇异矩阵 H H H表示
这是一个齐次坐标的等式, H H H乘以一个非零的比例因子上述等式仍然成立,即 H H H是一个 3 × 3 3×3 3×3齐次矩阵,具有8个未知量。
假设已经取得了两图像之间的单应,则可单应矩阵H可以将两幅图像关联起来
其中, ( u 1 , v 1 , 1 ) T (u_1,v_1,1)^T (u1,v1,1)T表示图像1中的像点 ( u 2 , v 2 , 1 ) T (u_2,v_2,1)^T (u2,v2,1)T是图像2中的像点,也就是可以通过单应矩阵 H H H将图像2变换到图像1。这有了很多实际的应用,例如图像的校正、对齐以及在SLAM中估计两个相机间的运动。
单应矩阵定义为
由尺度、相机内参、外参相乘,共八个自由度,理论上四对特征点约束可解。
但实际应用中,匹配的特征点往往会远多于四对。这时就可以构建一个过约束的方程组,把问题转换为一个最小二乘的优化问题。
徐启文, 唐振民, 姚亚洲. 基于改进SURF算法的图像拼接研究[J]. 南京理工大学学报, 2021, 45(2):8. ↩︎
裴红星, 刘金达, 葛佳隆,等. 图像拼接技术综述[J]. 郑州大学学报:理学版, 2019, 51(4):11. ↩︎
王娟, 师军, 吴宪祥. 图像拼接技术综述[J]. 计算机应用研究, 2008, 25(7):5. ↩︎
Lowe D G . Distinctive Image Features from Scale-Invariant Keypoints[J]. International Journal of Computer Vision, 2004, 60(2):91-110. ↩︎
Bay H , Tuytelaars T , Gool L V . SURF: Speeded up robust features[C]// Proceedings of the 9th European conference on Computer Vision - Volume Part I. Springer-Verlag, 2006. ↩︎ ↩︎
Rublee E , Rabaud V , Konolige K , et al. ORB: an efficient alternative to SIFT or SURF[C]// IEEE International Conference on Computer Vision, ICCV 2011, Barcelona, Spain, November 6-13, 2011. IEEE, 2011. ↩︎
R.C.冈萨雷斯, P.温茨. 数字图象处理[M]. 科学出版社, 1981. ↩︎
Muja M , Lowe D G . Fast Approximate Nearest Neighbors with Automatic Algorithm Configuration[C]// International Conference on Computer Vision Theory & Application Vissapp. 2009. ↩︎
Fischler M A , Bolles R C . Random Sample Consensus: A Paradigm for Model Fitting with Applications to Image Analysis and Automated Cartography - ScienceDirect[J]. Readings in Computer Vision, 1987:726-740. ↩︎