提问人:Iascaire 提问时间:6/30/2022 最后编辑:Iascaire 更新时间:7/2/2022 访问量:2060
在 C++ 中编译 OpenCV 时对 cv::Mat::Mat 的未定义引用
Undefined Reference to cv::Mat::Mat when Compiling OpenCV in C++
问:
我正在尝试使用 C++ 中的 OpenCV 4.6.0 编译一个简单的程序(我在 Ubuntu 20.04 上,这是默认安装),该程序读取图像,运行 BRISK 特征检测,并使用 imshow 在图像上显示关键点的位置。我可以毫无问题地将预处理、编译和汇编成一个 .o 文件,但到目前为止,g++ 断然拒绝执行链接步骤。
我最初每次 OpenCV 函数调用都会收到一个未定义的引用错误,但经过许多痛苦和反复试验,包括多次卸载和重新安装 OpenCV(按照 https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html#tutorial_linux_install_detailed_basic_verify 中的说明),我意识到出于某种原因,g++ 只有在明确告知使用 -l 时才会链接到 OpenCV 库。我现在已经编写了一个 bash 脚本来手动链接我可以在 /usr/local/lib 中找到的每个 OpenCV 库。该脚本称为 opencv_linker,它包含以下内容:
#!/bin/bash
g++ $@ -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_calib3d -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_gapi -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_videoio -lopencv_video
我从命令行运行它
./opencv_linker brisk_test.cpp -I/usr/local/include/opencv4
(我最终会把它变成一个makefile,但现在我只是想让OpenCV工作。此外,我确信我并不需要所有这些库来执行我正在做的事情,但我没有一个很好的参考来说明哪些库包含哪些函数,所以我采取了蛮力路线。
在命令行中运行上述命令会给出以下错误:
usr/bin/ld: /tmp/ccdVMcvM.o: in function `main':
<path_to_directory>/brisk_test.cpp:19: undefined reference to `cv::Mat::Mat()'
collect2: error: ld returned 1 exit status
我也试过跑步,我认为这是等效的。相同的结果。交换 -I 参数和 pkg-config 参数的顺序不会改变任何内容。g++ brisk_test.cpp -I/usr/local/include/opencv4 `pkg-config --libs opencv4`
关于如何消除最后一个未定义的引用,我已经没有想法了。我不明白为什么 g++ 无法在任何 OpenCV 库中找到 cv::Mat::Mat()(除非在某个地方有另一个我不知道的库)。我在网上搜索了答案,但我没有找到任何解决问题的方法——这篇文章的答案和这篇文章没有解决问题,这篇文章也没有答案。如果有人对可能发生的事情有任何想法,我将永远感激不尽。
编辑:我不认为我链接库的顺序是一个问题(但我可能是错的)。网上关于链接库的顺序的所有内容都只是说使用(有时没有 --cflags),显然应该负责排序?我尝试了以下六个命令:`pkg-config --cflags --libs opencv4`
g++ -g brisk_test.cpp -I/usr/local/include/opencv4 `pkg-config --libs opencv4`
g++ -g brisk_test.cpp `pkg-config --libs opencv4` -I/usr/local/include/opencv4
g++ -g brisk_test.cpp -I/usr/local/include/opencv4 `pkg-config --cflags --libs opencv4`
g++ -g brisk_test.cpp `pkg-config --cflags --libs opencv4` -I/usr/local/include/opencv4
g++ -g `pkg-config --cflags opencv4` brisk_test.cpp `pkg-config --libs opencv4` -I/usr/local/include/opencv4
g++ -g `pkg-config --cflags opencv4` brisk_test.cpp -I/usr/local/include/opencv4 `pkg-config --libs opencv4`
他们都给了我与上面相同的错误消息。
编辑2:这是以下输出:nm -CD /usr/local/lib/libopencv_core.so | grep Mat::Mat
$ nm -CD /usr/local/lib/libopencv_core.so | grep Mat::Mat
00000000001c2580 T cv::Mat::Mat(int, int, int)
00000000001c12e0 T cv::Mat::Mat(int, int, int, void*, unsigned long)
00000000001c25d0 T cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&)
00000000001c2440 T cv::Mat::Mat(int, int const*, int)
00000000001c2ab0 T cv::Mat::Mat(int, int const*, int, void*, unsigned long const*)
00000000001c2490 T cv::Mat::Mat(int, int const*, int, cv::Scalar_<double> const&)
00000000001c2640 T cv::Mat::Mat(cv::Size_<int>, int)
00000000001c14e0 T cv::Mat::Mat(cv::Size_<int>, int, void*, unsigned long)
00000000001c2690 T cv::Mat::Mat(cv::Size_<int>, int, cv::Scalar_<double> const&)
00000000001c1790 T cv::Mat::Mat(cv::Mat&&)
00000000001c19e0 T cv::Mat::Mat(cv::Mat const&)
00000000001c3630 T cv::Mat::Mat(cv::Mat const&, cv::Range const*)
00000000001c38a0 T cv::Mat::Mat(cv::Mat const&, cv::Range const&, cv::Range const&)
00000000001c2800 T cv::Mat::Mat(cv::Mat const&, cv::Rect_<int> const&)
00000000001c3cb0 T cv::Mat::Mat(cv::Mat const&, std::vector<cv::Range, std::allocator<cv::Range> > const&)
00000000001c2740 T cv::Mat::Mat(std::vector<int, std::allocator<int> > const&, int)
00000000001c34e0 T cv::Mat::Mat(std::vector<int, std::allocator<int> > const&, int, void*, unsigned long const*)
00000000001c2790 T cv::Mat::Mat(std::vector<int, std::allocator<int> > const&, int, cv::Scalar_<double> const&)
00000000001c11c0 T cv::Mat::Mat()
00000000001c2580 T cv::Mat::Mat(int, int, int)
00000000001c12e0 T cv::Mat::Mat(int, int, int, void*, unsigned long)
00000000001c25d0 T cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&)
00000000001c2440 T cv::Mat::Mat(int, int const*, int)
00000000001c2ab0 T cv::Mat::Mat(int, int const*, int, void*, unsigned long const*)
00000000001c2490 T cv::Mat::Mat(int, int const*, int, cv::Scalar_<double> const&)
00000000001c2640 T cv::Mat::Mat(cv::Size_<int>, int)
00000000001c14e0 T cv::Mat::Mat(cv::Size_<int>, int, void*, unsigned long)
00000000001c2690 T cv::Mat::Mat(cv::Size_<int>, int, cv::Scalar_<double> const&)
00000000001c1790 T cv::Mat::Mat(cv::Mat&&)
00000000001c19e0 T cv::Mat::Mat(cv::Mat const&)
00000000001c3630 T cv::Mat::Mat(cv::Mat const&, cv::Range const*)
00000000001c38a0 T cv::Mat::Mat(cv::Mat const&, cv::Range const&, cv::Range const&)
00000000001c2800 T cv::Mat::Mat(cv::Mat const&, cv::Rect_<int> const&)
00000000001c3cb0 T cv::Mat::Mat(cv::Mat const&, std::vector<cv::Range, std::allocator<cv::Range> > const&)
00000000001c2740 T cv::Mat::Mat(std::vector<int, std::allocator<int> > const&, int)
00000000001c34e0 T cv::Mat::Mat(std::vector<int, std::allocator<int> > const&, int, void*, unsigned long const*)
00000000001c2790 T cv::Mat::Mat(std::vector<int, std::allocator<int> > const&, int, cv::Scalar_<double> const&)
00000000001c11c0 T cv::Mat::Mat()
编辑 3:我知道哪一行代码导致了问题,这要归功于我有一个聪明的想法,即尝试一些我真的应该已经尝试过的东西(我的错,对不起——我真的不是这方面的专家):即注释掉代码行,直到程序成功编译和链接。当我将程序简化为以下代码行时,它会成功编译并链接以生成可执行文件:
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
Mat img = imread("test_image.jpg", IMREAD_GRAYSCALE);
Ptr<BRISK> detector = BRISK::create();
std::vector<KeyPoint> keypoints;
detector->detect(img, keypoints);
return EXIT_SUCCESS;
}
破坏代码的是添加绘制关键点所需的下一行:即当我在返回之前添加该行时,g++ 无法进行链接。我不明白为什么那行会引起问题,特别是因为我显然能够在第一行创建一个 Mat 对象。不过,我确实知道错误发生在链接步骤中,因为我能够将我的程序编译并组装成 .o 文件,即使包含有问题的代码行也是如此。Mat img_keypoints;
编辑 4:更改上面的代码(有效)以将第一行拆分为两行也会破坏事情:即,
int main(int argc, char* argv[])
{
Mat img;
img = imread("test_image.jpg", IMREAD_GRAYSCALE);
Ptr<BRISK> detector = BRISK::create();
std::vector<KeyPoint> keypoints;
detector->detect(img, keypoints);
return EXIT_SUCCESS;
}
也给了我同样的链接器错误。
答: 暂无答案
评论
nm -CD /usr/local/lib/libopencv_code.so | grep Mat::Mat
file /usr/local/lib/libopencv_core.so
file /usr/local/lib/libopencv_core.so.4.6.0
/usr/local/lib/libopencv_core.so.4.6.0: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=093c7b7f36398ea824fe64041efd0c836d9df2c7, not stripped
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libopencv_core.so succeeded