python - OpenCV imwrite 函数导致 'undefined symbol'

标签 python c++ opencv

我正在开发一款软件,它由一些带有 python 绑定(bind)的核心 C++ 代码组成。 C++ 代码已经使用了很多 OpenCV,但现在我正试图在两者之间保存图像,但我似乎无法使用 imwrite 函数。将它添加到 main.cpp 中并使用“默认”构建在 eclipse 中进行编译,但为了将它与现有的 Python 代码一起使用,我需要使用 CMake 进行构建。这再次编译正常,但是当我从我的 Python 类调用代码时,我得到这个错误:

ImportError: /.../pythonCPP.so: undefined symbol: _ZN2cv7imwriteERKNS_6StringERKNS_11_InputArrayERKSt6vectorIiSaIiEE

我搜索了这个,从我能收集到的信息来看,这似乎通常源于某种链接问题。不过,我不知道从哪里开始查看或在 CMake 文件中添加任何标志。我在 Ubuntu 16.04 64 位上使用 OpenCV 3.2.0。

这是对应的CMakeLists.txt:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project("blah")

#----------------------------CMAKE & GLOBAL PROPERTIES-------------------------#
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

###============= C++11 support====================================
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -g0 -s -std=c++11")
elseif (COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -g0 -s -std=c++0x")
else ()
    message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif ()
#=================================================================
# PYTHON option

set(PYTHON_OPTIONS "2.X" "3.X")
set(PYTHON_DESIRED_VERSION "3.X" CACHE STRING "Choose which python version to use, options are: ${PYTHON_OPTIONS}.")
set_property(CACHE PYTHON_DESIRED_VERSION PROPERTY STRINGS ${PYTHON_OPTIONS})


#=============== Find Packages
find_package(OpenCV 3 COMPONENTS core highgui imgproc REQUIRED)
message("Open CV version is ${OpenCV_VERSION}")
include("DetectPython")
if (${PYTHON_DESIRED_VERSION} STREQUAL "2.X")
    set(Python_ADDITIONAL_VERSIONS ${PYTHON2_VERSION_MAJOR}.${PYTHON2_VERSION_MINOR})
    find_package(Boost COMPONENTS python-py${PYTHON2_VERSION_MAJOR}${PYTHON2_VERSION_MINOR} REQUIRED)
else ()
    set(Python_ADDITIONAL_VERSIONS ${PYTHON3_VERSION_MAJOR}.${PYTHON3_VERSION_MINOR})
    find_package(Boost COMPONENTS python-py${PYTHON3_VERSION_MAJOR}${PYTHON3_VERSION_MINOR} REQUIRED)
endif ()

#========pick python stuff========================================
if (${PYTHON_DESIRED_VERSION} STREQUAL "2.X")
    SET(PYTHON_INCLUDE_DIRS ${PYTHON2_INCLUDE_DIR} ${PYTHON2_INCLUDE_DIR2} ${PYTHON2_NUMPY_INCLUDE_DIRS})
    SET(PYTHON_LIBRARIES ${PYTHON2_LIBRARY})
    SET(PYTHON_EXECUTABLE ${PYTHON2_EXECUTABLE})
    SET(PYTHON_PACKAGES_PATH ${PYTHON2_PACKAGES_PATH})
    SET(ARCHIVE_OUTPUT_NAME py2)
else ()
    SET(PYTHON_INCLUDE_DIRS ${PYTHON3_INCLUDE_DIR} ${PYTHON3_INCLUDE_DIR2} ${PYTHON3_NUMPY_INCLUDE_DIRS})
    SET(PYTHON_LIBRARIES ${PYTHON3_LIBRARY})
    SET(PYTHON_EXECUTABLE ${PYTHON3_EXECUTABLE})
    SET(PYTHON_PACKAGES_PATH ${PYTHON3_PACKAGES_PATH})
    SET(ARCHIVE_OUTPUT_NAME py3)
endif ()

file(GLOB project_sources ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)

add_library(${PROJECT_NAME} SHARED ${project_sources} ${CMAKE_CURRENT_SOURCE_DIR}/include/pyboostcvconverter/pyboostcvconverter.hpp)
target_include_directories(${PROJECT_NAME} PUBLIC
        "${CMAKE_CURRENT_SOURCE_DIR}/include"
        ${Boost_INCLUDE_DIRS}
        ${OpenCV_INCLUDE_DIRS}
        ${PYTHON_INCLUDE_DIRS}
        )

target_link_libraries(${PROJECT_NAME}
        ${Boost_LIBRARIES}
        ${OpenCV_LIBRARIES}
        ${PYTHON_LIBRARIES}
        )

#---------------------------   INSTALLATION    -----------------------------------------------------
#-get proper extension for python binary shared object on this platform
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('SO'))"
        RESULT_VARIABLE PYTHON_${PROJECT_NAME}_PY_PROCESS
        OUTPUT_VARIABLE ${PROJECT_NAME}_PY_SUFFIX
        OUTPUT_STRIP_TRAILING_WHITESPACE)

set_target_properties(${PROJECT_NAME} PROPERTIES
        ARCHIVE_OUTPUT_NAME ${ARCHIVE_OUTPUT_NAME}  # prevent name conflict for python2/3 outputs
        PREFIX ""
        OUTPUT_NAME py
        SUFFIX ${${PROJECT_NAME}_PY_SUFFIX})

if (MSVC AND NOT PYTHON_DEBUG_LIBRARIES)
    set(PYTHON_INSTALL_CONFIGURATIONS CONFIGURATIONS Release)
else ()
    set(PYTHON_INSTALL_CONFIGURATIONS "")
endif ()

if (WIN32)
    set(PYTHON_INSTALL_ARCHIVE "")
else ()
    set(PYTHON_INSTALL_ARCHIVE ARCHIVE DESTINATION ${PYTHON_PACKAGES_PATH} COMPONENT python)
endif ()

install(TARGETS ${PROJECT_NAME}
        ${PYTHON_INSTALL_CONFIGURATIONS}
        RUNTIME DESTINATION ${PYTHON_PACKAGES_PATH} COMPONENT python
        LIBRARY DESTINATION ${PYTHON_PACKAGES_PATH} COMPONENT python
        ${PYTHON_INSTALL_ARCHIVE}
        )

最佳答案

我不是最擅长 cmake 的,但您似乎未能链接 imwrite() 函数。

我在 Mac 上,所以如果你在其他地方,这会有所不同,但如果你查看 OpenCV 库目录,特别是在 libopencv_imgcodecs.dylib 中,如下所示:

nm -gUP  libopencv_imgcodecs.dylib | grep -i write

你会看到这样的东西:

__ZN2cv7imwriteERKNS_6StringERKNS_11_InputArrayERKNSt3__16vector...

这意味着 imgcodecs 提供了您需要的功能。

我是,我希望(感谢@Ptaq666)可靠地告知添加这个库的最好方法是使用:

find_package(OpenCV 3 REQUIRED)

其次是:

target_link_libraries(<as you already have> ${OpenCV_LIBRARIES})

原创建议

这意味着 imgcodecs 提供了您需要的功能,因此我认为您需要将其添加到 CMakeLists.txt 的这一行中:

find_package(OpenCV 3 COMPONENTS core highgui imgproc REQUIRED)

我想这会是这样的:

find_package(OpenCV 3 COMPONENTS core highgui imgproc imgcodecs REQUIRED)

关于python - OpenCV imwrite 函数导致 'undefined symbol',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52273971/

相关文章:

android - 从库中删除armeabi-v7a文件夹后,静态初始化失败

python - 在python中生成索引列表的方式之间的区别

c++ - 为什么 unique_ptr 会重载 reset(pointer p = pointer()) 和 reset(nullptr_t)?

c++ - 使用带有 ATL_BASE64_FLAG_NOPAD 标志的 ATL Base64 编码解码 base64 编码的字符串

c++ - 如何设置 QFormLayout 第一列的最小宽度?

c++ - 为什么当我尝试将 opencv 图像数据指针转换为 char* 时出现错误

python - OpenCV 从 url 加载视频

python - 如何使用 Python 去除焦点或最小化窗口?

python - 什么相当于 pytorch 在 tensorflow 中的 torch.nn.CosineEmbeddingLoss?

python - 将 datetime.max 插入 pandas 系列会更改系列类型