从 main.cpp 以外的文件编译时对 `cv::imread` 的未定义引用

undefined reference to `cv::imread` when compiled from file other than main.cpp

我无法读取或写入另一个文件(例如 ImgEnt.cpp 中的图像,但当使用 CMake 和 make[=16= 构建时,同一段代码在 main.cpp 中工作]

ImgEnt.cpp

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>

ImgEnt::ImgEnt(const std::string &filename, const std::string &filepath, const std::string &dirname, const std::string &output_dir) {
    this->filepath = filepath;
    this->filename = filename;
    this->output_dir = output_dir + fs::path::preferred_separator + dirname;
}

cv::Mat ImgEnt::input_image() const {
    cv::Mat input_img, output_img; // not causing issue
    cv::Size size(640, 640); // not causing issue
    input_img = cv::imread(this->filepath, cv::IMREAD_COLOR); // THIS IS CAUSING ISSUE
//    cv::resize(input_img, output_img, size);
//
//    return output_img;
    return output_img;
}

std::string ImgEnt::output_filepath() const {
    fs::path odir(this->output_dir);
    if (!exists(odir)) {
        fs::create_directories(odir);
    }

    return this->output_dir + fs::path::preferred_separator + this->filename;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)

# project and language settings
project(Week2 VERSION 0.1.0)
enable_language(CXX CUDA)

# c++ standard and runtime directory
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)

# libtorch settings
if (DEFINED ENV{CMAKE_PREFIX_PATH})
    message(STATUS "Setting the cmake prefix path to \"$ENV{CMAKE_PREFIX_PATH}\"")
    set(CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH};${CMAKE_PREFIX_PATH};")
else ()
    message(STATUS "Setting default cmake prefix path to \"/opt/libtorch/share/cmake/Torch\"")
    set(CMAKE_PREFIX_PATH "/opt/libtorch/share/cmake/Torch;${CMAKE_PREFIX_PATH};")
endif ()

# download modal if not exists
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/model)
    file(MAKE_DIRECTORY ${PROJECT_SOURCE_DIR}/model)
endif ()
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/model/yolo5.pt)
    message(STATUS "Download the yolo v5 model into ${PROJECT_SOURCE_DIR}/model/yolo5.pt")
    file(DOWNLOAD https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5x.pt ${PROJECT_SOURCE_DIR}/model/yolo5.pt)
endif ()

# find packages
find_package(Torch REQUIRED)
find_package(LIBMAGIC REQUIRED)
find_package(OpenCV REQUIRED COMPONENTS opencv_core opencv_imgcodecs)
find_package(Boost REQUIRED)

# configure include directories, executable and link libraries
add_executable(${PROJECT_NAME} main.cpp ImgEnt.cpp ImgEnt.hpp)
include_directories(${Boost_INCLUDE_DIR} "${OpenCV_INCLUDE_DIRS}" "${LIBMAGIC_INCLUDES}" "${TORCH_INCLUDE_DIRS}")
target_link_libraries(${PROJECT_NAME} opencv_imgcodecs opencv_core "${TORCH_LIBRARIES}" "${LIBMAGIC_LIBRARIES}")

构建日志

$ cmake . && make
-- The C compiler identification is GNU 11.1.0
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- The CUDA compiler identification is NVIDIA 11.5.119
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: /opt/cuda/bin/nvcc - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- Setting default cmake prefix path to "/opt/libtorch/share/cmake/Torch"
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- 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 Torch: /opt/libtorch/lib/libtorch.so  
-- Found LIBMAGIC: /usr/lib/libmagic.so  
-- Found components for LIBMAGIC
-- LIBMAGIC_ROOT_DIR  = /usr/local
-- LIBMAGIC_INCLUDES  = /usr/include
-- LIBMAGIC_LIBRARIES = /usr/lib/libmagic.so
-- Found OpenCV: /usr (found version "4.5.4") found components: opencv_core opencv_imgcodecs 
-- Found Boost: /usr/lib64/cmake/Boost-1.76.0/BoostConfig.cmake (found version "1.76.0")  
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/Week2
[ 33%] Building CXX object CMakeFiles/Week2.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/Week2.dir/ImgEnt.cpp.o
[100%] Linking CXX executable bin/Week2
/usr/bin/ld: CMakeFiles/Week2.dir/ImgEnt.cpp.o: in function `ImgEnt::input_image() const':
ImgEnt.cpp:(.text+0x332): undefined reference to `cv::imread(std::string const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Week2.dir/build.make:120: bin/Week2] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Week2.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

我在 main.cpp 中编写了类似的代码,它执行以下操作并且工作正常

  1. 阅读图片
  2. 转换为 HSV 并将大小调整为 250 x 250
  3. 保存在 /tmp/img/processed.cpp

好吧,我有一个 CPU 版本的 OpenCV,并且我在启用 Cuda 的情况下进行编译。删除旧版本并安装 opencv-cuda 后。它奏效了,现在对我来说完全有意义。