C++ 编译并运行一个最简单的openCV 程序(纯命令行)
前言
- 在进入这篇文章之前应该学会:C++ hello world编译过程
- 本文代码来自:Lab 1 - OpenCV 的安装和使用
代码
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char* argv[]) {
Mat image = imread("opencv-logo.png"); // 载入名为 "opencv-logo.png" 的图片
namedWindow("hello"); // 创建一个标题为 "hello" 的窗口
imshow("hello", image); // 在窗口 "hello" 中显示图片
waitKey(0); // 等待用户按下键盘
destroyWindow("hello"); // 销毁窗口 "hello"
return 0;
}
macOS安装 openCV
brew install opencv
, 安装在/usr/local/Cellar/opencv
目录下- 同时建议安装
brew install pkg-config
- 参考 https://www.geeksforgeeks.org/how-to-install-opencv-for-c-on-macos/
错误与解决方法
g++ main.cpp -o main.out -I /usr/local/Cellar/opencv/4.5.4_4/include/opencv4
出现错误error: no template named 'initializer_list' in namespace 'std'
error: "OpenCV 4.x+ requires enabled C++11 support"
解决方法:g++ -std=c++11 main.cpp -o main.out -I /usr/local/Cellar/opencv/4.5.4_4/include/opencv4
- 以上命令出现错误:
解决方法:Undefined symbols for architecture x86_64: "cv::namedWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from: _main in main-1d11bd.o "cv::destroyWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from: _main in main-1d11bd.o "cv::Mat::~Mat()", referenced from: _main in main-1d11bd.o "cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from: _main in main-1d11bd.o "cv::imshow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&)", referenced from: _main in main-1d11bd.o "cv::waitKey(int)", referenced from: _main in main-1d11bd.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
g++ -std=c++11 main.cpp -o main.out -I /usr/local/Cellar/opencv/4.5.4_4/include/opencv4 -L /usr/local/Cellar/opencv/4.5.4_4/lib -lopencv_highgui -lopencv_imgcodecs -lopencv_core
分析:- 出错是因为只用
-I
给出了头文件的包括路径,但没有告诉链接器应该链接的库文件的位置(-L
)和名称(-l
,-labc
指的是链接libabc.a
)。 - 如果只用
-I
给出包括路径,可以正确生成机器代码(即完成编译四步的前三步)(使用-c
选项):g++ -std=c++11 -c main.cpp -I /usr/local/Cellar/opencv/4.5.4_4/include/opencv4 -L /usr/local/Cellar/opencv/4.5.4_4/lib
- 直接找到链接器缺失的库,比如此处,库
opencv_highgui
包含了cv::namedWindow
,cv::destroyWindow
,cv::imshow
,cv::waitKey
, 库opencv_imgcodecs
包含了cv::imread
, 库opencv_core
包含了cv::Mat::~Mat
。
- 出错是因为只用
pkg-config
一个个找对应的库很麻烦,一般直接告诉编译器 openCV 的所有库的名称和位置,这可以用pkg-config
实现。
g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test
pkg-config --cflags --libs opencv4
的输出:
-I/usr/local/opt/opencv/include/opencv4 -L/usr/local/opt/opencv/lib -lopencv_gapi -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_sfm -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_highgui -lopencv_datasets -lopencv_text -lopencv_plot -lopencv_videostab -lopencv_videoio -lopencv_viz -lopencv_wechat_qrcode -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core