ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org
Ask Your Question
0

[ROS2] Opencv 4 conflicted with cv_bridge causing an error.

asked 2020-09-29 08:26:18 -0500

Majed gravatar image

updated 2020-09-30 07:18:43 -0500

Hi fellow developers,

I am having an issue with ROS2 cv_bridge and opencv 4. The warning below shows that I have a conflict between opencv3 and opencv4. I can not downgrade the opencv in the device because other programs require it.

 /usr/bin/ld: warning: libopencv_core.so.3.2, needed by //opt/ros/dashing/lib/libcv_bridge.so, may conflict with libopencv_core.so.4.1
/usr/bin/ld: warning: libopencv_core.so.3.2, needed by //opt/ros/dashing/lib/libcv_bridge.so, may conflict with libopencv_core.so.4.1

This is the Error it causes when I run the software.

/home/jetson/ros2_ws/install/camera_pkg/lib/camera_pkg/camera_display_node: symbol lookup error: /usr/local/lib/libopencv_imgproc.so.4.1: undefined symbol: _ZN2cv3ocl17isOpenCLActivatedEv

I believe the error occurs when the line below is executed:

cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);

What is the best way to deal with this error?

Edit: due to the comments where they seem to be working I am adding the CMakelist, hpp and cpp

cmake_minimum_required(VERSION 3.5) project(library_pkg)

# Default to C++17
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(image_transport REQUIRED)
find_package(std_msgs REQUIRED)
find_package(OpenCV 4 QUIET)
if (NOT OpenCV_FOUND)
  find_package(OpenCV REQUIRED)
endif ()
message(STATUS "Found OpenCV version ${OpenCV_VERSION}")

include_directories(
  include
  ${OpenCV_INCLUDE_DIRS}
)

add_library(
    ${PROJECT_NAME} SHARED
    src/MJPEGWriter.cpp
    src/CameraMainNode.cpp
    src/CameraDisplayNode.cpp
    src/CameraSaveNode.cpp
    src/CameraStreamNode.cpp
)

target_include_directories(${PROJECT_NAME} PUBLIC
  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
  "$<INSTALL_INTERFACE:include>")

ament_target_dependencies(
  ${PROJECT_NAME}
  image_transport
  OpenCV
  rclcpp
  sensor_msgs
  std_msgs
  cv_bridge
)

ament_export_include_directories(include)
ament_export_libraries(${PROJECT_NAME})
ament_export_interfaces(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)

#=============
# Install
#=============

install(
  DIRECTORY include/
  DESTINATION include
)

install(
  TARGETS ${PROJECT_NAME}
  EXPORT export_${PROJECT_NAME}
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)


ament_package()

hpp code:

#ifndef _CAMERADISPLAYNODE_H_
#define _CAMERADISPLAYNODE_H_
#endif

#include <iostream>
#include "rclcpp/rclcpp.hpp"
#include <image_transport/image_transport.h>
#include <sensor_msgs/image_encodings.hpp>
#include <opencv2/opencv.hpp>
#include "cv_bridge/cv_bridge.h"
#include <sensor_msgs/image_encodings.hpp>


class CameraDisplayNode : public rclcpp::Node{
public:
    //--------------------------
    CameraDisplayNode() : Node("camera_display"){
        //--------------------------
        RCLCPP_INFO(this->get_logger(), "Hit ESC to exit");
        //--------------------------
        //cv::namedWindow("view", cv::WINDOW_AUTOSIZE);
        //cv::startWindowThread();
        //--------------------------
        subscriber_ = this->create_subscription<sensor_msgs::msg::Image>(
            "camera_image", 1,
            std::bind(&CameraDisplayNode::display_image_callback, this, std::placeholders::_1));

    } // end CameraDisplayNode() : Node("camera_display")

private:
    void display_image_callback(const sensor_msgs::msg::Image::SharedPtr msg);
    //--------------------------
    rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr subscriber_;
    //--------------------------
};

cpp code:

#include "library_pkg/CameraDisplayNode.hpp"

//--------------------------------------------------------------
void CameraDisplayNode::display_image_callback(const sensor_msgs::msg::Image::SharedPtr msg){
    try{
        cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
        int keycode = cv::waitKey(30) & 0xff;
        if(keycode == 27){
            RCLCPP_INFO(this->get_logger(),"Exit Display");
        }// end if(keycode == 27)
    }// end try
    catch (cv_bridge::Exception& e){
        RCLCPP_ERROR(this->get_logger(),"Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }// end catch
}// end display_image_callback
//--------------------------------------------------------------

Only the display code doesn't work with me and it does give me the error mentioned before. Any help is highly appricated.

edit retag flag offensive close merge delete

Comments

1

I cannot confirm the issue. I also use opencv 4.1 and cv_bridge from eloquent binaries in my node. Of course I get compile time warning /usr/bin/ld: warning: libopencv_core.so.3.2, needed by /opt/ros/eloquent/lib/libcv_bridge.so, may conflict with libopencv_core.so.4.1. I have tested your imshow line and it works. The problem is not in this line.

rrrand gravatar image rrrand  ( 2020-09-30 04:55:18 -0500 )edit

@rrrand Amazing, thank you for doing the test. I have added the post to include my Cmakelist, hpp and cpp. If you have any insight please let me know.

Majed gravatar image Majed  ( 2020-09-30 07:20:06 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2020-09-30 12:10:47 -0500

Majed gravatar image

The answer seems to add the following in the callback. Although, this seems wrong to me, but it does work

    cv::namedWindow("view", cv::WINDOW_AUTOSIZE);
    cv::startWindowThread();

The full function:

void CameraDisplayNode::display_image_callback(const sensor_msgs::msg::Image::SharedPtr msg){
    //--------------------------
    cv::namedWindow("view", cv::WINDOW_AUTOSIZE);
    cv::startWindowThread();
    //--------------------------
    try{
        cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
        int keycode = cv::waitKey(30) & 0xff;
        if(keycode == 27){
            RCLCPP_INFO(this->get_logger(),"Exit Display");
        }// end if(keycode == 27)
    }// end try
    catch (cv_bridge::Exception& e){
        RCLCPP_ERROR(this->get_logger(),"Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }// end catch
}// end display_image_callback
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2020-09-29 08:26:18 -0500

Seen: 982 times

Last updated: Sep 30 '20