OpenCV 3 runtime error "Invalid pointer to file storage" cv_bridge + third party library

asked 2018-06-18 06:30:44 -0500

rosusr142573 gravatar image

updated 2018-06-18 07:12:54 -0500

I'm trying to publish the image of a picozense camera in a ROS node in ROS kinetic, Ubuntu 16.04. I build a catkin package and included the camera's API (.h and .so files) which is OpenCV3 compatible. This works fine, i can call the API functions in the c++ source code. However, OpenCV crashes at runtime with an error that after some research most posts argue is a conflict between OpenCV2 and OpenCV3. But my installed OpenCV version is 3.3.1 and i don't have any OpenCV 2.x installed. (Also i'm using cv_bridge which depends on OpenCV3 components)

The only OpenCV package i added to my dependencies and in my code is the highgui package. If i leave it out, the node does not crash at all. But even with the highgui package the node runs successfully sometimes.

How can i fix the error?

OpenCV Runtime Error

rosusr@ubuntu:~/catkin_ws$ rosrun picozense publisher 
1
OpenCV Error: Bad argument (Invalid pointer to file storage) in cvGetFileNodeByName, file /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/core/src/persistence.cpp, line 861
terminate called after throwing an instance of 'cv::Exception'
  what():  /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/core/src/persistence.cpp:861: error: (-5) Invalid pointer to file storage in function cvGetFileNodeByName

Aborted (core dumped)

Running the node works sometimes (the initialization just fails because the camera is not connected)

rosusr@ubuntu:~/catkin_ws$ rosrun picozense publisher 
1
2
PsInitialize status: -1
Initialize failed!
Shutdown status: 0

publisher.cpp

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/highgui.hpp>
#include "PicoZense_api.h"

int main(int argc, char** argv){
  ros::init(argc, argv, "publisher");
  ros::NodeHandle nh;
  PsReturnStatus status;
  std::cout << "1" << std::endl;
  status = PsInitialize();
  std::cout << "2" << std::endl;
  std::cout << "PsInitialize status: " << status << std::endl;
  if (status != PsReturnStatus::PsRetOK){
      std::cout << "Initialize failed!" << std::endl;
      status = PsShutdown();
      std::cout << "Shutdown status: " << status << std::endl;
      return -1;
  }
  // ...
  // using opencv highgui etc. here
  //
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(picozense)
add_compile_options(-std=c++11)
find_package(catkin REQUIRED COMPONENTS
  cv_bridge
  image_transport
  sensor_msgs
  message_generation
)
find_package(OpenCV 3 REQUIRED COMPONENTS highgui)
generate_messages( DEPENDENCIES
  sensor_msgs
)
catkin_package( CATKIN_DEPENDS
   cv_bridge
   image_transport
   sensor_msgs
   message_runtime
)
include_directories( include
  ${catkin_INCLUDE_DIRS} #picoZense API header file is here (/picozense/include/)
  ${OpenCV_INCLUDE_DIRS}
)
message(STATUS "catkin_include_dirs: " ${catkin_INCLUDE_DIRS})
message(STATUS "opencv_include_dirs: " ${OpenCV_INCLUDE_DIRS})
add_executable(publisher src/publisher.cpp)
add_dependencies(publisher ${catkin_EXPORTED_TARGETS} ${${PROJECT_NAME}_EXPORTED_TARGETS})
target_link_libraries(publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${PROJECT_SOURCE_DIR}/lib/x64/libpicozense_api.so)
message(STATUS "opencv_libraries: " ${OpenCV_LIBRARIES})

package.xml

<?xml version="1.0"?>
<package format="2">
  <name>picozense</name>
  <version>0.0.0</version>
  <description>The picozense package</description>
  <maintainer email="rosusr@todo.todo">rosusr</maintainer>
  <license>TODO</license>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>cv_bridge</build_depend>
  <build_depend>image_transport</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>message_generation</build_depend>
  <build_export_depend>cv_bridge</build_export_depend>
  <build_export_depend>image_transport</build_export_depend>
  <build_export_depend>sensor_msgs</build_export_depend>
  <build_export_depend>message_generation</build_export_depend>
  <exec_depend>cv_bridge</exec_depend>
  <exec_depend>image_transport</exec_depend>
  <exec_depend>sensor_msgs</exec_depend>
  <exec_depend>message_runtime</exec_depend>
  <export>
  </export>
</package>

ldd libpicozense_api.so

linux-vdso.so.1 =>  (0x00007ffc19ea8000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff34274c000)
libstdc ...
(more)
edit retag flag offensive close merge delete

Comments

Does libpicozense_api.so link to anything suspicuous? What is the output of ldd libpicozense_api.so?

gvdhoorn gravatar image gvdhoorn  ( 2018-06-18 06:36:48 -0500 )edit

If i leave [highgui] out, the node does not crash at all.

That is interesting. What is the contents of the various OpenCV CMake variables? Particularly OpenCV_LIBRARIES?

Random SEGFAULTs (ie: sometimes they occur, sometimes they don't) are a strong pointer to ABI incompatibility.

..

gvdhoorn gravatar image gvdhoorn  ( 2018-06-18 06:39:18 -0500 )edit

..

and included the camera's API (.h and .so files) which is OpenCV3 compatible.

if the camera sdk is linking against a different version of OpenCV (or expecting to link against a different version), that could be the problem.


Edit: I tried looking for the lib, but it appears the ..

gvdhoorn gravatar image gvdhoorn  ( 2018-06-18 06:40:01 -0500 )edit

.. camera is only in pre-order now. I'm guessing you have a preproduction unit for evaluation purposes?

gvdhoorn gravatar image gvdhoorn  ( 2018-06-18 06:41:52 -0500 )edit
  • OpenCV_LIBRARIES outputs just "opencv_highgui" as defined in my CMakeLists
  • ABI incompatibility can't be the case because the SDK includes a working c++/opencv example application for the camera which displays the image correctly. It's opencv2.4.9 and all libs are included, but 3 works here too
rosusr142573 gravatar image rosusr142573  ( 2018-06-18 06:51:14 -0500 )edit

"if the camera sdk is linking against a different version of OpenCV (or expecting to link against a different version), that could be the problem."

Exactly my thought. Problem is i only have a .h and a .so file and in the header it does not state any opencv version whatsoever

rosusr142573 gravatar image rosusr142573  ( 2018-06-18 06:53:51 -0500 )edit

OpenCV_LIBRARIES outputs just "opencv_highgui" as defined in my CMakeLists.txt

which is rather unfortunate, as find scripts should populate those variables with absolute paths. Not with library names.

ABI incompatibility can't be the case [..] However, it's opencv2.4.9

I'm not sure how ..

gvdhoorn gravatar image gvdhoorn  ( 2018-06-18 06:53:54 -0500 )edit

.. your last sentence supports your conclusion.

Exactly my thought. Problem is i only have a .h and a .so file and in the header it does not state any opencv version whatsoever

That's why you need to look at the output of ldd.

gvdhoorn gravatar image gvdhoorn  ( 2018-06-18 06:54:42 -0500 )edit