You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu24环境下OpenCV与Libtorch混合使用链接错误求助

问题:Ubuntu 24 + CLion中OpenCV与Libtorch混合编译出现未定义引用错误

错误现象

同时使用OpenCV和Libtorch的代码编译时,出现以下链接错误:

main.cpp:34:(.text+0xa28): undefined reference to `cv::putText(cv::_InputOutputArray const&, std::string const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)' 

main.cpp:45:(.text+0xbb1): undefined reference to `cv::VideoCapture::VideoCapture(std::string const&, int)' 

main.cpp:64:(.text+0xe04): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)' 

单独使用OpenCV或单独使用Libtorch的程序均可正常编译运行,仅在混合项目中出现上述问题。

可正常运行的单独项目CMake配置

纯OpenCV项目CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(libtorch)

find_package (OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
set(CMAKE_CXX_STANDARD 17)

add_executable(libtorch main.cpp)
target_link_libraries(libtorch ${OpenCV_LIBS})

纯Libtorch项目CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(libtorch)

find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

add_executable(libtorch main.cpp)
target_link_libraries(libtorch "${TORCH_LIBRARIES}")
set_property(TARGET libtorch PROPERTY CXX_STANDARD 17)

出错的混合项目CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(libtorch)

find_package (OpenCV REQUIRED)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

add_executable(libtorch main.cpp)
target_link_libraries(libtorch ${OpenCV_LIBS})
target_link_libraries(libtorch "${TORCH_LIBRARIES}")
set_property(TARGET libtorch PROPERTY CXX_STANDARD 17)

CLion中使用的CMake参数:-DCMAKE_PREFIX_PATH=/usr/include/libtorch/share/cmake/Torch/

出错的混合代码

#include <torch/script.h>
#include <opencv2/opencv.hpp>
#include <iostream>

const int INPUT_WIDTH = 320;
const int INPUT_HEIGHT = 320;
const float SCORE_THRESHOLD = 0.5;
const float NMS_THRESHOLD = 0.5;
const int PERSON_CLASS_ID = 1;
const std::string VIDEO_PATH = "path";
const std::string MODEL_PATH = "ssdlite320_mobilenet_v3_large.pt";

torch::Tensor preprocess_image(cv::Mat& image) {
    cv::Mat resized;
    resize(image, resized, cv::Size(INPUT_WIDTH, INPUT_HEIGHT));
    cvtColor(resized, resized, cv::COLOR_BGR2RGB);

    torch::Tensor tensor_image = torch::from_blob(resized.data, {1, INPUT_HEIGHT, INPUT_WIDTH, 3}, torch::kByte);
    tensor_image = tensor_image.permute({0, 3, 1, 2});
    tensor_image = tensor_image.toType(torch::kFloat);
    tensor_image = tensor_image.div(255);
    return tensor_image;
}

void draw_predictions(cv::Mat& image, const torch::Tensor& predictions) {
    auto pred_accessor = predictions.accessor<float, 2>();
    for (int i = 0; i < predictions.size(0); ++i) {
        if (pred_accessor[i][5] == PERSON_CLASS_ID && pred_accessor[i][4] > SCORE_THRESHOLD) {
            int x1 = static_cast<int>(pred_accessor[i][0] * image.cols);
            int y1 = static_cast<int>(pred_accessor[i][1] * image.rows);
            int x2 = static_cast<int>(pred_accessor[i][2] * image.cols);
            int y2 = static_cast<int>(pred_accessor[i][3] * image.rows);
            rectangle(image, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2);
            putText(image, "Person", cv::Point(x1, y1 - 10),
                        cv::FONT_HERSHEY_SIMPLEX, 0.9, cv::Scalar(0, 255, 0), 2);
        }
    }
}

int main() {

    torch::jit::script::Module model = torch::jit::load(MODEL_PATH);
    model.eval();

    cv::VideoCapture cap(VIDEO_PATH);
    if (!cap.isOpened()) {
        std::cerr << "Error opening video file" << std::endl;
        return -1;
    }

    cv::Mat frame;
    while (cap.read(frame)) {

        torch::Tensor input_tensor = preprocess_image(frame);

        std::vector<torch::jit::IValue> inputs;
        inputs.push_back(input_tensor);
        torch::Tensor output = model.forward(inputs).toTensor();

        torch::Tensor predictions = output.squeeze().detach();

        draw_predictions(frame, predictions);

        imshow("Person Detection", frame);

        if (cv::waitKey(1) == 27) break;

    }

    cap.release();
    cv::destroyAllWindows();
    return 0;
}

可正常运行的纯OpenCV代码

#include <opencv2/opencv.hpp>
#include <iostream>

const std::string videoPath = "path";

void preprocessFrame(cv::Mat& frame) {
    cv::resize(frame, frame, cv::Size(240, 160));
}

void applyBackgroundSubtraction(cv::Mat& frame, cv::Ptr<cv::BackgroundSubtractor>& bgSubtractor, cv::Mat& fgMask) {
    bgSubtractor->apply(frame, fgMask);
}

void applyNoiseReduction(cv::Mat& fgMask) {
    cv::GaussianBlur(fgMask, fgMask, cv::Size(15, 15), 0);

    cv::erode(fgMask, fgMask, cv::Mat(), cv::Point(-1, -1), 2);
    cv::dilate(fgMask, fgMask, cv::Mat(), cv::Point(-1, -1), 2);
}

int main() {
    cv::VideoCapture cap(videoPath);
    if (!cap.isOpened()) {
        std::cerr << "Error: Could not open the video file!" << std::endl;
        return -1;
    }

    cv::Ptr<cv::BackgroundSubtractor> bgSubtractor = cv::createBackgroundSubtractorKNN(100, 2000, false);

    cv::Mat frame, fgMask;

    while (cap.read(frame)) {
        if (frame.empty()) break;

        preprocessFrame(frame);
        applyBackgroundSubtraction(frame, bgSubtractor, fgMask);
        applyNoiseReduction(fgMask);
        cv::imshow("Foreground Mask (Noise Reduced)", fgMask);
        if (cv::waitKey(30) == 27) break;
    }

    cap.release();
    cv::destroyAllWindows();

    return 0;
}

解决方案

问题根源在于链接顺序及ABI兼容性,按以下步骤修复:

  1. 调整链接顺序:将Libtorch的链接放在OpenCV之前,修改后的CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.28)
project(libtorch)

find_package(OpenCV REQUIRED)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

add_executable(libtorch main.cpp)
# 先链接Libtorch,再链接OpenCV
target_link_libraries(libtorch "${TORCH_LIBRARIES}" ${OpenCV_LIBS})
set_property(TARGET libtorch PROPERTY CXX_STANDARD 17)
  1. 确保ABI兼容:Libtorch默认使用C17编译,需保证OpenCV也使用相同C标准。若OpenCV为源码编译,需指定CMAKE_CXX_STANDARD=17;Ubuntu 24 apt安装的OpenCV默认符合要求。

  2. 清理CMake缓存:在CLion中执行File -> Reload CMake Project,或手动删除build目录后重新编译,避免旧缓存干扰。

内容的提问来源于stack exchange,提问作者Oleg Chaika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:24:53