Robotics StackExchange | Archived questions

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

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++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff3423ca000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff3420c1000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff341eaa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff341ae0000)
/lib64/ld-linux-x86-64.so.2 (0x000055f87df4e000)

I've already searched and tried a lot but any help is very much appreciated!

Asked by rosusr142573 on 2018-06-18 06:30:44 UTC

Comments

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

Asked by gvdhoorn on 2018-06-18 06:36:48 UTC

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.

..

Asked by gvdhoorn on 2018-06-18 06:39:18 UTC

..

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 ..

Asked by gvdhoorn on 2018-06-18 06:40:01 UTC

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

Asked by gvdhoorn on 2018-06-18 06:41:52 UTC

  • 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

Asked by rosusr142573 on 2018-06-18 06:51:14 UTC

"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

Asked by rosusr142573 on 2018-06-18 06:53:51 UTC

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 ..

Asked by gvdhoorn on 2018-06-18 06:53:54 UTC

.. 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.

Asked by gvdhoorn on 2018-06-18 06:54:42 UTC

Only files that the API includes are PicoZense_api.h and libpicozense_api.so

Asked by rosusr142573 on 2018-06-18 07:14:59 UTC

And the output of ldd of your node (ie: publisher)?

It might be good to verify with Pico whether they are targetting any specific OpenCV version. I don't see anything in the ldd output you post, but seeing as they give you a 2.4.9 app, would be good to know for certain.

Asked by gvdhoorn on 2018-06-18 07:19:44 UTC

Can you try:

find_package(OpenCV 3.3.1 EXACT REQUIRED ..)

clean your devel and build folders (ie: rm -rf them) and rerun catkin_make?

It could well be that this isn't an ABI problem, but it would be good to try and rule it out.

Asked by gvdhoorn on 2018-06-18 07:20:57 UTC

Something else to verify (from here):

I am almost pretty sure the image sizes you are declaring (or Mats you are initiating) and the images you are receiving from cv_bridge don't have the same size.

Asked by gvdhoorn on 2018-06-18 07:25:43 UTC

3.3.1 EXACT REQUIRED -> already tried, doesn't work

clean devel and build ->already tried doesn't work

No mats are initialized, the program crashes on the camera init function

Asked by rosusr142573 on 2018-06-18 07:32:37 UTC

3.3.1 EXACT REQUIRED -> already tried, doesn't work

that's very nice. But please include the output of a fresh catkin_make run with that in your CMakeLists.txt.

the program crashes on the camera init function

well then I guess you should ask Pico about this.

Asked by gvdhoorn on 2018-06-18 07:33:59 UTC

Gonna check in with Pico and if there's not better solution install and use OpenCV2

Asked by rosusr142573 on 2018-06-18 07:34:37 UTC

To help future users, please also update this question with whatever information Pico provided you.

Asked by gvdhoorn on 2018-06-18 07:38:03 UTC

Will do when they answer

Asked by rosusr142573 on 2018-06-18 07:39:06 UTC

Hi! I am facing the same error. My code (very similar to the one in the question) runs most of the time but sometimes I get the CV Exception or a segmentation fault. @rosusr142573 Did you get any reply from Pico? Please do update if they answer. Thanks

Asked by saks on 2018-06-29 09:00:33 UTC

I ended up building a workaround by not using OpenCV in my publisher node at all. I'm now using an UInt16MultiArray to publish my depth image i get from the camera. Only using OpenCV in the subscriber now. Works like a charm

Asked by rosusr142573 on 2018-07-04 05:27:46 UTC

That is really ugly :)

Did Pico not have any useful information?

Asked by gvdhoorn on 2018-07-05 02:28:21 UTC

Not ugly at all imo. Works as intended. The nodes are more modular.

Pico did not answer

Asked by rosusr142573 on 2018-07-05 10:01:22 UTC

It is not very nice because a multi array has no semantics, other than being a nD array.

DepthImage would seem to be the appropriate msg type to use.

Asked by gvdhoorn on 2018-07-05 10:02:50 UTC

Answers