由于未定义的引用,无法编译OpenCV?

40

这段代码很简单,基本上是从此教程中直接提取的。我正在运行Arch Linux,并且已经将OpenCV库存储在/usr/include/中。我还检查过确保/usr/include在我的PATH路径中。

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>

using namespace cv; 

int main(int argc, char** argv){
    Mat image;
    Mat grayImage; 

    if(!argv[1]){
        std::cerr << "No image data!" << std::endl;
        return -1; 
    }

    image = imread(argv[1], 1);
    cvtColor(image, grayImage, CV_BGR2GRAY);
    imwrite("Gray_Image.jpg", grayImage);

    namedWindow(argv[1], CV_WINDOW_AUTOSIZE);
    namedWindow("Gray Image", CV_WINDOW_AUTOSIZE);

    imshow(argv[1], image);
    imshow("Gray Image", grayImage);

    waitKey(0);
    return 0;
}

编译器进程成功找到并包含这些头文件,但我仍然会在编译时收到未定义的引用错误。如果您查看我所包含的头文件,它们还会在/usr/include/opencv2中包含其他文件。我已经检查过,这样的头文件确实存在。

有任何想法吗?

/tmp/ccudBcqD.o: In function `main':
test.cpp:(.text+0xc0): undefined reference to `cv::imread(std::string const&, int)'
test.cpp:(.text+0x11f): undefined reference to `cv::_OutputArray::_OutputArray(cv::Mat&)'
test.cpp:(.text+0x138): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
test.cpp:(.text+0x158): undefined reference to `cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)'
test.cpp:(.text+0x180): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
test.cpp:(.text+0x1ca): undefined reference to `cv::imwrite(std::string const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)'
test.cpp:(.text+0x241): undefined reference to `cv::namedWindow(std::string const&, int)'
test.cpp:(.text+0x291): undefined reference to `cv::namedWindow(std::string const&, int)'
test.cpp:(.text+0x2bf): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
test.cpp:(.text+0x2ff): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
test.cpp:(.text+0x32d): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
test.cpp:(.text+0x361): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
test.cpp:(.text+0x383): undefined reference to `cv::waitKey(int)'
/tmp/ccudBcqD.o: In function `cv::Mat::~Mat()':
test.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
/tmp/ccudBcqD.o: In function `cv::Mat::operator=(cv::Mat const&)':
test.cpp:(.text._ZN2cv3MataSERKS0_[_ZN2cv3MataSERKS0_]+0x111): undefined reference to `cv::Mat::copySize(cv::Mat const&)'
/tmp/ccudBcqD.o: In function `cv::Mat::release()':
test.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x47): undefined reference to `cv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
[Finished in 1.1s with exit code 1]
[shell_cmd: g++ "/home/branden/Desktop/OpenCV/test.cpp" -o "/home/branden/Desktop/OpenCV/test"]
[dir: /home/branden/Desktop/OpenCV]
[path: /usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/vendor_perl:/usr/bin/core_perl]

3
所以显然解决方案是在编译行中添加 pkg-config --cflags --libs opencv?这究竟是做什么的? - sherrellbc
你的编译器参数是什么? - Kh40tiK
2
我之前一直在使用一个IDE,但是默认的编译方式是 g++ file.cpp -o file,而正确的方式应该是 g++ pkg-config --cflags --libs opencv file.cpp -o file - sherrellbc
3
这是因为默认情况下不包括OpenCV库。这些是链接错误,与头文件无关。 - Bull
14
-lopencv_core -lopencv_imgproc -lopencv_highgui - berak
@sherrellbc 它添加了链接时库标志,如 -lopencv_dnn345 -lopencv_ml345 ... - rogerdpack
8个回答

52

这是一个链接问题。尝试:

g++ -o test_1 test_1.cpp `pkg-config opencv --cflags --libs`

这应该可以编译源代码。然而,如果你最近从源代码编译了OpenCV,你将在运行时遇到链接问题,库文件将无法被找到。 在大多数情况下,在从源代码编译库之后,你需要最后执行以下步骤:

sudo ldconfig

6
pkg-config 部分应该用反引号括起来。但是,StackOverflow将反引号用于内联代码,因此不会显示出来。另一种语法是 g++ -o test1 test_1.cpp $(pkg-config opencv --cflags --libs) - Phil Wright
这对我有用。是否有一种方法在编译(g++)之前链接,以便不需要这些g++参数?在我的情况下,“sudo ldconfig”似乎没有任何作用。 - 2one
如果你正在使用Geany,你可能想要将构建命令设置为g++ -o "%e" "%f" `pkg-config opencv --cflags --libs` - shahar_m
它应该在反引号中。我之前使用了这个“靠近回车键的符号,而不是Esc键旁边的`符号。 - harsh
假设你正在使用opencv4,你需要明确地使用opencv4而不是opencvg++ -o test_1 test_1.cpp $(pkg-config opencv4 --cflags --libs) - undefined

16

我已经尝试了所有的解决方案。在注释中加上 -lopencv_core -lopencv_imgproc -lopencv_highgui 解决了我的问题。现在我的命令行在geany里看起来像这样:

g++ -lopencv_core -lopencv_imgproc -lopencv_highgui  -o "%e" "%f"

当我进行构建时:
g++ -lopencv_core -lopencv_imgproc -lopencv_highgui  -o "opencv" "opencv.cpp" (in directory: /home/fedora/Desktop/Implementations)

头信息包括:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

1
在我的情况下,它们包含在 pkg-config --cflags --libs ../cmake_bin_dir/instDir/lib/pkgconfig/opencv.pc 命令中,但无论如何都不起作用。 - roschach

6
跟着这个教程进行操作:教程。在bash中运行install-opencv.sh文件,该文件在教程中有提及。
阅读openCV的示例。
CMakeLists.txt
cmake_minimum_required(VERSION 3.7)
project(openCVTest)
# cmake needs this line
cmake_minimum_required(VERSION 2.8)

# Define project name
project(opencv_example_project)

# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)

# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

if(CMAKE_VERSION VERSION_LESS "2.8.11")
    # Add OpenCV headers location to your include paths
    include_directories(${OpenCV_INCLUDE_DIRS})
endif()

# Declare the executable target built from your sources
add_executable(main main.cpp)

# Link your application with OpenCV libraries
target_link_libraries(main ${OpenCV_LIBS})

main.cpp

/**
 * @file LinearBlend.cpp
 * @brief Simple linear blender ( dst = alpha*src1 + beta*src2 )
 * @author OpenCV team
 */

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>

using namespace cv;

/** Global Variables */
const int alpha_slider_max = 100;
int alpha_slider;
double alpha;
double beta;

/** Matrices to store images */
Mat src1;
Mat src2;
Mat dst;

//![on_trackbar]
/**
 * @function on_trackbar
 * @brief Callback for trackbar
 */
static void on_trackbar( int, void* )
{
    alpha = (double) alpha_slider/alpha_slider_max ;

    beta = ( 1.0 - alpha );

    addWeighted( src1, alpha, src2, beta, 0.0, dst);

    imshow( "Linear Blend", dst );
}
//![on_trackbar]

/**
 * @function main
 * @brief Main function
 */
int main( void )
{
    //![load]
    /// Read images ( both have to be of the same size and type )
    src1 = imread("../data/LinuxLogo.jpg");
    src2 = imread("../data/WindowsLogo.jpg");
    //![load]

    if( src1.empty() ) { printf("Error loading src1 \n"); return -1; }
    if( src2.empty() ) { printf("Error loading src2 \n"); return -1; }

    /// Initialize values
    alpha_slider = 0;

    //![window]
    namedWindow("Linear Blend", WINDOW_AUTOSIZE); // Create Window
    //![window]

    //![create_trackbar]
    char TrackbarName[50];
    sprintf( TrackbarName, "Alpha x %d", alpha_slider_max );
    createTrackbar( TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar );
    //![create_trackbar]

    /// Show some stuff
    on_trackbar( alpha_slider, 0 );

    /// Wait until user press some key
    waitKey(0);
    return 0;
}

测试过适用于linux mint 17


4

在Linux编译OpenCV4后,我遇到了相同的错误。

我必须在我的.cpp文件后连接库,而不是在之前。

g++ $(pkg-config opencv4 --cflags) -std=c++17 foo.cpp $(pkg-config opencv4 --libs) -o foo.o

注意:我还向 cmake 命令传递了 -D OPENCV_GENERATE_PKGCONFIG=ON 参数以生成 pkgconfig/opencv4.pc 文件,因为 pkg-config 命令需要它。
有关顺序的原因,请阅读此处获取更多信息:为什么库链接顺序有时会导致 GCC 出错?

4

如果有人仍然遇到这个问题,一个解决方案是使用MinGW重新构建源OpenCV库,而不是使用OpenCV提供的二进制文件。我这样做了,它就像魔法般地工作了。


这实际上是一个完全有效的答案,因为我必须在Ubuntu 16.04上执行此操作,并使用此版本的OpenCV。如果不进行重建,则无法在我的系统上构建一个简单的示例,否则我会得到类似于Ubuntu提供的deb的链接器错误。请重新考虑那些对此进行了负评价的人。 - eacousineau
在Ubuntu上似乎无法做到这一点,对吗? - Vandrey

0
如果您按照以下步骤操作,就可以使用从OpenCV_INSTALL_PATH构建的opencv。
cmake_minimum_required(VERSION 2.8)

SET(OpenCV_INSTALL_PATH /home/user/opencv/opencv-2.4.13/release/)

SET(OpenCV_INCLUDE_DIRS "${OpenCV_INSTALL_PATH}/include/opencv;${OpenCV_INSTALL_PATH}/include")

SET(OpenCV_LIB_DIR "${OpenCV_INSTALL_PATH}/lib")

LINK_DIRECTORIES(${OpenCV_LIB_DIR})

set(OpenCV_LIBS opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu)

# find_package( OpenCV )

project(edge.cpp)

add_executable(edge edge.cpp)

0

我只是改变了参数位置: g++ -o test2.out test2.cpp pkg-config opencv4 --cflags --libs

在我改变位置之前,我使用的是 g++ pkg-config opencv4 --cflags --libs test2.cpp -o test2.out。

你可以尝试在终端中运行 pkg-config opencv --cflags --libs 或者 运行 pkg-config opencv4 --cflags --libs 看看是否能够获取任何信息。


0

对我来说,这种类型的错误:

mingw-w64-x86_64/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: mingw-w64-x86_64/x86_64-w64-mingw32/lib/libTransform360.a(VideoFrameTransform.cpp.obj):VideoFrameTransform.cpp:(.text+0xc7c):
undefined reference to `cv::Mat::Mat(cv::Mat const&, cv::Rect_<int> const&)'

指的是加载顺序,我必须像这样执行-lTransform360 -lopencv_dnn345 -lopencv...,就是那个顺序。 把它们紧挨着放也有帮助,不要把-lTransform360放在开头...不然你会因为某种诡异的原因得到:

undefined reference to `VideoFrameTransform_new'
undefined reference to `VideoFrameTransform_generateMapForPlane'

...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接