0
$\begingroup$

Rosanswers logo

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.


Originally posted by Majed on ROS Answers with karma: 55 on 2020-09-29

Post score: 0


Original comments

Comment by rrrand on 2020-09-30:
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.

Comment by Majed on 2020-09-30:
@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.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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

Originally posted by Majed with karma: 55 on 2020-09-30

This answer was ACCEPTED on the original site

Post score: 0

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.