感谢 OpenCV3 Make · Issue #1 · feichtenhofer/gpu_flow · GitHub @blgnksy 在我解决报错的过程中给了一些灵感。主要是opencv2和3 api的定义有不同!
【环境】ubuntu 16.04 cuda 9.0 opencv 3.4.2 python 3.5.2
安装 opencv 3.4.2可以参考我的博文:linux ubuntu16.04 opencv3.4.2 cuda9 安装编译填坑记_Hello Word!-CSDN博客
【示例程序】OPENCV+GPU环境搭建以及测试代码 - 程序园
原始程序:
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/gpu/gpumat.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"using namespace std;
using namespace cv;
using namespace cv::gpu;int main ()
{ const char* imagename = "../debug.png";cv::Mat img = cv::imread(imagename);if(img.empty())return -1; //是否加载成功if(!img.data)return -1;cv::imshow("image", img); cv::Mat dst;TickMeter tm;tm.start();cv::cvtColor(img,dst,CV_RGB2GRAY);tm.stop();cout<<"the cpu caculate time is "<<tm.getTimeSec()<<"s"<<endl;tm.reset();cv::gpu::GpuMat d_src_img(img);cv::gpu::GpuMat d_dst_img;tm.start();cv::gpu::cvtColor(d_src_img,d_dst_img,CV_RGB2GRAY); tm.stop();d_dst_img.download(dst);cv::imshow("test",dst);cout<<"the gpu caculate time is "<<tm.getTimeSec()<<"s"<<endl;cv::waitKey(0);return 0;
}
【报错过程】
1,我安装好了opencv 3.4.2
2,复制了上述示例程序,命名为test_a.cpp
3,新建了CMakeLists.txt,内容如下:
cmake_minimum_required(VERSION 2.8)
project(test_a)
find_package(OpenCV REQUIRED)
add_executable(test_a test_a.cpp)
target_link_libraries(test_a ${OpenCV_LIBS})
4,放一个1.jpg图片到cpp文件所在的同一目录,因为后面的例程会用到
5,$ cmake . # 这时可能会因为include 和 using namespace语句顺序问题报一些错,后文已经提到,按照后文修改后的程序调整一下就行。
【报错内容】
$ cmake .
CMake Error at CMakeLists.txt:4 (find_package):By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project hasasked CMake to find a package configuration file provided by "OpenCV", butCMake did not find one.Could not find a package configuration file provided by "OpenCV" with anyof the following names:OpenCVConfig.cmakeopencv-config.cmakeAdd the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"provides a separate development package or SDK, be sure it has beeninstalled.-- Configuring incomplete, errors occurred!
See also "/tmp-data/user1/soft/opencv/opencv-3.4.2/test/CMakeFiles/CMakeOutput.log".
【原因】没有正确设置好opencv build所在的目录
【解决】修改CMakeLists.txt,加入一行 当时编译安装opencv时的build目录,方便cmake查找
cmake_minimum_required(VERSION 2.8)
project(test_a)# 加入这一行
set(OpenCV_DIR /tmp-data/user1/soft/opencv/opencv-3.4.2/build)find_package(OpenCV REQUIRED)
add_executable(test_a test_a.cpp)
target_link_libraries(test_a ${OpenCV_LIBS})
6,$ make
报错了。。(这个大bug纠结了我这个小白好久。。。)
【报错内容】
$ make
Scanning dependencies of target test
[ 50%] Building CXX object CMakeFiles/test.dir/test.cpp.o
[100%] Linking CXX executable test
CMakeFiles/test.dir/test.cpp.o: In function `main':
test.cpp:(.text+0x21d): undefined reference to `cv::gpu::GpuMat::GpuMat(cv::Mat const&)'
test.cpp:(.text+0x240): undefined reference to `cv::gpu::Stream::Null()'
test.cpp:(.text+0x266): undefined reference to `cv::gpu::cvtColor(cv::gpu::GpuMat const&, cv::gpu::GpuMat&, int, int, cv::gpu::Stream&)'
test.cpp:(.text+0x28b): undefined reference to `cv::gpu::GpuMat::download(cv::Mat&) const'
CMakeFiles/test.dir/test.cpp.o: In function `cv::gpu::GpuMat::~GpuMat()':
test.cpp:(.text._ZN2cv3gpu6GpuMatD2Ev[_ZN2cv3gpu6GpuMatD5Ev]+0x14): undefined reference to `cv::gpu::GpuMat::release()'
collect2: error: ld returned 1 exit status
CMakeFiles/test.dir/build.make:152: recipe for target 'test' failed
make[2]: *** [test] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/test.dir/all' failed
make[1]: *** [CMakeFiles/test.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
【报错原因】
那个示例程序可能是适用于opencv 2.4等老的版本,不适用于我的opencv 3.4新版本。可能不是什么编译opencv过程中cmake参数选的不对等等网上其他人说的原因。当然你也可以去尝试他们的做法,然后再看看有没有效果。
【解决】
修改示例程序(test_a.cpp中的代码。将所有涉及到cv::gpu的引用位置都按照新版opencv的api命名方式(参考:OpenCV: cv::cuda::GpuMat Class Reference),统一改为:cv::cuda),然后不必要的命名空间语句(如原例程中的using namespace cv::gpu;)可以删去(亲测)。注意我还调整了include各语句和using namespace各语句之间的顺序关系,否则可能会报错。另外我还修改了原例程引用图片的地址(根据自己需要)。
修改后的代码(test_a.cpp):
#include <iostream>
using namespace std;#include "opencv2/opencv.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/gpu/gpumat.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"using namespace cv;int main ()
{const char* imagename = "1.jpg";cv::Mat img = cv::imread(imagename);if(img.empty())return -1; //是否加载成功if(!img.data)return -1;cv::imshow("image", img);cv::Mat dst;TickMeter tm;tm.start();cv::cvtColor(img,dst,CV_RGB2GRAY);tm.stop();cout<<"the cpu caculate time is "<<tm.getTimeSec()<<"s"<<endl;tm.reset();cv::cuda::GpuMat d_src_img(img);cv::cuda::GpuMat d_dst_img;tm.start();cv::cuda::cvtColor(d_src_img,d_dst_img,CV_RGB2GRAY);tm.stop();d_dst_img.download(dst);cv::imshow("test",dst);cout<<"the gpu caculate time is "<<tm.getTimeSec()<<"s"<<endl;cv::waitKey(0);return 0;
}
【修改后的完整运行步骤】
# 1,查看当前目录下文件
$ ls
1.jpg CMakeLists.txt test_a.cpp# 2,开始编译
$ cmake .# 输出:
# -- The C compiler identification is GNU 5.4.0
# -- The CXX compiler identification is GNU 5.4.0
# -- Check for working C compiler: /usr/bin/cc
# -- Check for working C compiler: /usr/bin/cc -- works
# -- Detecting C compiler ABI info
# -- Detecting C compiler ABI info - done
# -- Detecting C compile features
# -- Detecting C compile features - done
# -- Check for working CXX compiler: /usr/bin/c++
# -- Check for working CXX compiler: /usr/bin/c++ -- works
# -- Detecting CXX compiler ABI info
# -- Detecting CXX compiler ABI info - done
# -- Detecting CXX compile features
# -- Detecting CXX compile features - done
# -- Looking for pthread.h
# -- Looking for pthread.h - found
# -- Looking for pthread_create
# -- Looking for pthread_create - not found
# -- Looking for pthread_create in pthreads
# -- Looking for pthread_create in pthreads - not found
# -- Looking for pthread_create in pthread
# -- Looking for pthread_create in pthread - found
# -- Found Threads: TRUE
# -- Found CUDA: /usr/local/cuda-9.0 (found suitable exact version "9.0")
# -- Found OpenCV: /usr/local (found version "3.4.2")
# -- Configuring done
# -- Generating done
# -- Build files have been written to: /home/xxx/Downloads/test# 3,继续编译
$ make
# 输出:
# Scanning dependencies of target test_a
# [ 50%] Building CXX object CMakeFiles/test_a.dir/test_a.cpp.o
# [100%] Linking CXX executable test_a
# [100%] Built target test_a# 4,试运行:
$ ./test_a
# 输出:
# the cpu caculate time is 0.0427854s
# the gpu caculate time is 0.00048128s
# 通过 watch -n 1 -d 'nvidia-smi'可以监测到gpu有动静哦!!!
# 完成opencv 3.4.2 在 gpu上的运行测试!!
在第4步,
(Ubuntu 18.04.5 LTS bionic )
$ cat /proc/version
Linux version 3.10.0-957.el7.x86_64 (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) )
运行报错1:
opencv2/gpu/gpu.hpp 没有那个文件或目录
原因:可能是版本不兼容,文件名称需要修改
解决:在test_a.cpp中修改 #include "opencv2/gpu/gpu.hpp" 为 #include "opencv2/core/cuda.hpp" ,注释掉 #include "opencv2/gpu/gpumat.hpp" ,并且增加新的命名空间引用 using namespace cv::cuda;
运行报错2: terminate called after throwing an instance of 'cv::Exception'
OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /home/nick/.Apps/opencv/modules/highgui/src/window.cpp, line 516
terminate called after throwing an instance of 'cv::Exception'what(): /home/user1/.Apps/opencv/modules/highgui/src/window.cpp:516: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvShowImg
原因:可能是因为opencv编译安装之前,libgtk2.0-dev没有安装,但是编译也通过了
解决:按照报错提示,安装libgtk2.0,重新编译安装opencv(也可以安装libgtk2.0之后先试试重新运行测试程序test_a,但是我没有试)
$ sudo apt install libgtk2.0-dev# 至此可以试一下刚才的报错会不会还出现,如果还出现,继续后面的步骤# 进入当时编译安装opencv的build文件夹,从 cmake .. 这一步开始,重新再来一遍后面的编译安装流程注意:在执行 $ cmake -D CMAKE_BUILD_T.... 这句命令时,保证使用了 WITH_GTK=ON
# 纪念2019年9月11日,今天一定是我的幸运日!完成了opencv 3.4.2的成功编译以及在gpu上的测试 : )