【问题标题】:Opencv linking CMAKE not working Ubuntu 16.04 DockerOpencv链接CMAKE不起作用Ubuntu 16.04 Docker
【发布时间】:2019-12-17 08:54:57
【问题描述】:

我正在尝试在 Docker 文件中编译一个项目,但它不断抛出错误。

Dockerfile:

FROM jjanzic/docker-python3-opencv:contrib-opencv-3.4.2

RUN apt-get update -y
RUN apt-get install -y g++ cmake libboost-dev libgoogle-perftools-dev

COPY . /opt/nsg

WORKDIR /opt/nsg

RUN mkdir -p build && cd build && \
    cmake -DCMAKE_BUILD_TYPE=Release .. && \
    make -j $(nproc)

CMakeLists.txt在根目录:

cmake_minimum_required(VERSION 2.8)

project(efanna2e)
include_directories(${PROJECT_SOURCE_DIR}/include)
find_package(OpenCV REQUIRED)
#OpenMP
find_package(OpenMP)
if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else()
    message(FATAL_ERROR "no OpenMP supprot")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
add_definitions (-std=c++14 -O3 -lboost -march=native -Wall -DINFO)

add_subdirectory(src)
add_subdirectory(tests)

CMakeLists.txt/tests 目录中:

set(CMAKE_CXX_STANDARD 14)

add_executable(test_nsg_index test_nsg_index.cpp)
target_link_libraries(test_nsg_index ${PROJECT_NAME} -ltcmalloc)

add_executable(test_nsg_search test_nsg_search.cpp)
target_link_libraries(test_nsg_search ${PROJECT_NAME})

add_executable(test_nsg_optimized_search test_nsg_optimized_search.cpp)
target_link_libraries(test_nsg_optimized_search ${OpenCV_LIBS})
target_link_libraries(test_nsg_optimized_search ${PROJECT_NAME} -ltcmalloc)

我要运行的代码:

auto body = req.body.substr(file.offset, file.length);
const cv::Mat image = cv::imdecode(body, 0);

运行docker build . 后,这是输出的一部分:

-- Found OpenCV: /usr/local (found version "3.4.2") 

/opt/nsg/tests/test_nsg_optimized_search.cpp:149:4:   required from here
/opt/nsg/tests/test_nsg_optimized_search.cpp:145:39: error: no matching function for call to ‘imdecode(std::__cxx11::basic_string<char>&, int)’
     const cv::Mat image = cv::imdecode(body, 0);
                           ~~~~~~~~~~~~^~~~~~~~~
In file included from /usr/local/include/opencv2/imgcodecs/imgcodecs.hpp:48:0,
                 from /opt/nsg/tests/test_nsg_optimized_search.cpp:12:
/usr/local/include/opencv2/imgcodecs.hpp:222:18: note: candidate: cv::Mat cv::imdecode(cv::InputArray, int)
 CV_EXPORTS_W Mat imdecode( InputArray buf, int flags );
                  ^~~~~~~~

所以它一直说没有函数imdecode。我还尝试了imread 和其他多种功能。它只是一直说它不存在,在下一行它说它找到了我想要的功能并指向它。

我在我的代码中尝试了多种方法:

  1. 我加载了#include &lt;opencv2/core/core.hpp&gt;
  2. 然后我加载了#include "opencv2/core/core.hpp"(对来自opencv的所有包含的hpp文件这样做了
  3. 使用:using namespace cv;
  4. 使用没有命名空间的函数
  5. 做了:cv::imdecode()
  6. 做了:imdecode()

这些全部导致了同样的错误。

昨天我在一台 Ubuntu 18.04 机器上遇到了同样的问题,除了我在机器上安装了 opencv 而不是通过 Docker。今天,我重新安装了 Ubuntu 到 16.04 版本并开始使用 Docker。但同样的问题。我想我在这里做错了,但不知道是什么。

【问题讨论】:

  • cv::InputArray 的底层类型是什么?它是否与您为函数参数 (std::__cxx11::basic_string&lt;char&gt;&amp;) 提供的匹配?
  • 可以在此处找到文档The function imdecode reads an image from the specified buffer in the memory. If the buffer is too short or contains invalid data, the function returns an empty matrix ( Mat::data==NULL ).buf Input array or vector of bytes.docs.opencv.org/3.4/d4/da8/… 即使我提供的输入不正确,这也应该有效。
  • "即使我提供的输入不正确,这也应该有效。" - 我认为这不一定正确,您的输入 body 不是正确的类型docsInputArray 是“一个可以从 Mat, Mat_, Matx, std::vector, std::vector<:> >、std::vector、std::vector >、UMat、std::vector 或双精度。"
  • 我会在 2 小时后回来检查您是否正确,我将使用 imread 并使用 jpg 图像来确保我的输入正确。你为什么认为我收到一个错误,说函数未定义?

标签: c++ docker opencv ubuntu cmake


【解决方案1】:

错误告诉你函数调用:

const cv::Mat image = cv::imdecode(body, 0);

与头文件中定义的不匹配。编译器只知道如何使用与定义的函数签名(即函数名称、函数参数类型、返回类型等)匹配的调用,在您的情况下为imgcodecs.hpp

cv::Mat cv::imdecode(cv::InputArray, int)

编译器将此称为 candidate 匹配,因为虽然您使用的函数名称 imdecode 是正确的,但函数参数 types 不匹配。您的函数调用具有此签名(根据错误消息),显示第一个参数与编译器期望的不同:

cv::Mat imdecode(std::__cxx11::basic_string<char>&, int)

因此,您必须将变量 body 更改为 cv::InputArray 类型,或者可以构造 InputArray 的类型。可能性列表是here。考虑到cv::InputArray 可以从std::vector&lt;T&gt; 类型构造,您可以尝试将body 转换为char 的向量,如下所示:

auto body = req.body.substr(file.offset, file.length);
std::vector<char> bodyVector(body.begin(), body.end());
const cv::Mat image = cv::imdecode(bodyVector, 0);

或者您可以从body 显式创建一个cv::InputArray 变量并将其传递给imdecode 函数。

【讨论】:

  • 这确实是正确的。我感到困惑,因为我认为它指向了不同的方向。
猜你喜欢
  • 2016-11-09
  • 1970-01-01
  • 2015-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多