图像特征提取中需要用到SIFT等算法,因此不得不安装从源码编译安装opencv_contrib,网上有很多教程,但是在不同的环境下多少会出现一些错误,针对Ubuntu20.04、gcc-7环境下对opencv+opencv_contrib编译、安装、测试总结如下:
一、依赖环境安装
sudo apt-get installbuild-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
二、opencv3.2和opencv_contrib-3.2下载
网上有很多的版本,我下载编译的原始版本为
https://github.com/hanxuan123/opencv3.2/tree/master/all
我修改及编译好的文件下载地址:https://download.csdn.net/download/qq_41721951/85095064
三、cmake
cmake -D CMAKE_EXE_LINKER_FLAGS=-lcblas -D WITH_TBB=ON -D WITH_OPENMP=ON
-D WITH_IPP=ON -D WITH_CUDA=OFF -D ENABLE_CXX11=1 -D BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release -DOPENCV_GENERATE_PKGCONFIG=ON -DCMAKE_INSTALL_PREFIX=/usr/local/opencv32
-DOPENCV_EXTRA_MODULES_PATH=/home/zhoudk/rgbdslam_catkin_ws/opencv3.2/opencv-3.2.0/opencv_contrib-3.2.0/modules
-D ENABLE_PRECOMPILED_HEADERS=OFF ..
注意:
-DCMAKE_INSTALL_PREFIX为opencv最后的安装路径
-DOPENCV_EXTRA_MODULES_PATH为opencv_contrib-3.2中的modules文件路径
cmake中可能会出现如下错误,错误及解决办法总结如下
1、cmake时可能因为网络原因出现ippicv_linux_20151201.tgz、protobuf-cpp-3.1.0.tar.gz、boostdesc_lbgm.i、vgg_generated_80.i等文件下载失败,在搜索相关文件下载即可,下载后放到相应文件夹即可。
2、opencv cmake编译中出现fatal error:stdlib.h:没有那个文件或目录,如下
解决方案:cmake命令中添加-DENABLE_PRECOMPILED_HEADERS = OFF
3、CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
CUDA_nppi_LIBRARY (ADVANCED)
如下所示:
解决方案参考:
https://blog.csdn.net/zqjackking/article/details/80546197
https://blog.csdn.net/u014613745/article/details/78310916
原因解析:
cuda9不再支持2.0架构
解决方案如下:
(1)opencv3.2文件夹下找到FindCUDA.cmake文件
1)找到行
find_cuda_helper_libs(nppi)
改为
find_cuda_helper_libs(nppial)
find_cuda_helper_libs(nppicc)
find_cuda_helper_libs(nppicom)
find_cuda_helper_libs(nppidei)
find_cuda_helper_libs(nppif)
find_cuda_helper_libs(nppig)
find_cuda_helper_libs(nppim)
find_cuda_helper_libs(nppist)
find_cuda_helper_libs(nppisu)
find_cuda_helper_libs(nppitc)
2)找到行
set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppi_LIBRARY};${CUDA_npps_LIBRARY}")
改为
set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppial_LIBRARY};${CUDA_nppicc_LIBRARY};${CUDA_nppicom_LIBRARY};${CUDA_nppidei_LIBRARY};${CUDA_nppif_LIBRARY};${CUDA_nppig_LIBRARY};${CUDA_nppim_LIBRARY};${CUDA_nppist_LIBRARY};${CUDA_nppisu_LIBRARY};${CUDA_nppitc_LIBRARY};${CUDA_npps_LIBRARY}")
3)找到行
unset(CUDA_nppi_LIBRARY CACHE)
改为
unset(CUDA_nppial_LIBRARY CACHE)
unset(CUDA_nppicc_LIBRARY CACHE)
unset(CUDA_nppicom_LIBRARY CACHE)
unset(CUDA_nppidei_LIBRARY CACHE)
unset(CUDA_nppif_LIBRARY CACHE)
unset(CUDA_nppig_LIBRARY CACHE)
unset(CUDA_nppim_LIBRARY CACHE)
unset(CUDA_nppist_LIBRARY CACHE)
unset(CUDA_nppisu_LIBRARY CACHE)
unset(CUDA_nppitc_LIBRARY CACHE)
(2)找到文件 OpenCVDetectCUDA.cmake,修改以下几行
...
set(__cuda_arch_ptx "")
if(CUDA_GENERATION STREQUAL "Fermi")
set(__cuda_arch_bin "2.0")
elseif(CUDA_GENERATION STREQUAL "Kepler")
set(__cuda_arch_bin "3.0 3.5 3.7")
...
改为
...
set(__cuda_arch_ptx "")
if(CUDA_GENERATION STREQUAL "Kepler")
set(__cuda_arch_bin "3.0 3.5 3.7")
elseif(CUDA_GENERATION STREQUAL "Maxwell")
set(__cuda_arch_bin "5.0 5.2")
...
(3)cuda9中有一个单独的halffloat(cuda_fp16.h)头文件,也应该被包括在opencv的目录里,将头文件cuda_fp16.h添加至 opencv\modules\cudev\include\opencv2\cudev\common.hpp,即在common.hpp中添加#include <cuda_fp16.h>,重新生成即可 。
四、make
使用命令sudo make -j8
1、如果使用make -i8,可能会出现如下错误
Built target libprotobuf
make: *** [Makefile:163:all] 错误 2
解决方法:使用sudo make -j8
2、错误:make[2]: *** [modules/python3/CMakeFiles/opencv_python3.dir/build.make:56: modules/python3/CMakeFiles/opencv_python3.dir/__/src2/cv2.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:21149: modules/python3/CMakeFiles/opencv_python3.dir/all] Error 2
make: *** [Makefile:138: all] Error 2
解决方案参考:https://www.likecs.com/show-204892088.html
解决办法如下:在路径opencv3.2/modules/python/src2路径下找到cv2.cpp文件
在730修改为PyString_AsString(obj)前添加(char *)
修改为如下所示
bool pyopencv_to(PyObject* obj, String& value, const char* name)
{
(void)name;
if(!obj || obj == Py_None)
return true;
char* str = (char *)PyString_AsString(obj); //char* str = (PyString_AsString(obj)
if(!str)
return false;
value = String(str);
return true;
}
3、出现AVFMT_RAWPICTURE, CODEC_FLAG_GLOBAL_HEADER报错
解决方法:根据报错文件,将相应位置
AVFMT_RAWPICTURE 修改为 AVFMT_NOFILE;
CODEC_FLAG_GLOBAL_HEADER 修改为 AV_CODEC_FLAG_GLOBAL_HEADER;
五、sudo make install
opencv最后安装在/usr/local/opencv32 路径下,如图
六、opencv及SIFT特征图像检测
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
cv::Mat img = cv::imread("rgb.png", CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat out_img,des;
vector<cv::KeyPoint> pts;
Ptr<xfeatures2d::SIFT> sift=cv::xfeatures2d::SIFT::create();
sift->detectAndCompute(img,cv::noArray(),pts,des);
//检测到的特征为pts,同时计算描述子为des
// sift->detect(img,pts);//只进行检测特征
/*
Ptr<xfeatures2d::SURF> surf=cv::xfeatures2d::SURF::create();
surf->detectAndCompute(img,cv::noArray(),pts,des);
// surf->detect(img,pts);
*/
cv::drawKeypoints(img,pts,out_img);
cv::imshow("Image", out_img);
//cv::imwrite("sift.png",out_img);
cv::waitKey(0);
return 0;
}
CMakeLists.txt,当系统安装多个opencv时,通过find_package()指定需要的特定opencv版本,避免链接到其他版本。
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE "Release")
# 添加c++ 11标准支持
set(CMAKE_CXX_FLAGS "-std=c++11 -O2")
# 寻找OpenCV库,指定路径
find_package(OpenCV REQUIRED
PATHS /usr/local/opencv32 #指定了PATHS查找路径
NO_DEFAULT_PATH) #NO_DEFAULT_PATH表示不启用默认路径,即剔除掉系统路径
# 添加头文件
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(siftTest siftTest.cpp)
target_link_libraries(siftTest ${OpenCV_LIBS})
sift特征提取结果如下