I am trying to make a simple project that uses ROS (indigo, installed on Ubuntu 14.04) and OpenCV 3.0.0 to read images from a video (webcam or file) and publish them using ROS´s image_transport.
Reading the image and displaying it works fine, but as soon as I try to include and use cv_bridge to convert and publish the image, it still compiles fine but when running the executable it fails with
Segmentation fault (core dumped)
My code:
#include <ctime>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "image_transport/image_transport.h"
#include "cv_bridge/cv_bridge.h"
#include <fstream>
int main(int argc, char **argv)
{
cv::Mat image;
ros::init(argc, argv, "webcam_streamer");
ros::NodeHandle nh;
ros::Rate loop_rate(500);
image_transport::ImageTransport it(nh);
image_transport::Publisher pub = it.advertise("cam_img", 10);
cv::VideoCapture cap("//home//milan//drop.avi");
if(!cap.isOpened())
{
ROS_ERROR("COULD NOT OPEN FILE!\r\n");
return 0;
}else
ROS_INFO("Read file successfully!\r\n");
while(nh.ok())
{
ROS_INFO("Reading image");
cap.read(image);
ROS_INFO("...");
if(image.empty())
break;
ROS_INFO("Success!");
cv::imshow("IMG", image);
cv::waitKey(20);
sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
ROS_INFO("STOPPING CAM");
cap.release();
}
In my CMakeLists.txt I do
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
cv_bridge
image_transport
)
find_package(OpenCV REQUIRED)
add_executable(stream_webcam_image src/stream_webcam_image.cpp)
target_link_libraries(stream_webcam_image ${catkin_LIBRARIES})
target_link_libraries(stream_webcam_image ${OpenCV_LIBS})
add_dependencies(stream_webcam_image stream_webcam_image_gencpp)
When I remove cv_bridge from my CMakeLists.txt and my includes and don´t try to publish the image, the program runs fine, else it fails with the following output:
So it seems that it does not even manage to read the image.
The problem seems to be that ROS (cv_bridge in particular) uses an older version of OpenCV which is conflicting with the version 3 I have installed.
I tried to follow this:
Latest OpenCV in ROS
but the
ls /opt/ros/rosversion -d/lib/libopencv* -hal
did not find a current OpenCV in the ROS folder, and I could not find the specified OpenCV folder manually.
I still followed the steps, but still the same error.
Then I found this question on ROS Answers which seems to be the same problem, but I tried to compile ROS after having installed OpenCV 3, which also should have built opencv_vision from source, as the last comment in the above thread suggests?
Did I miss something, or is there a better solution to this Problem?
My goal is to get my Raspberry Pi 2 to send images from it´s camera to my Laptop using ROS, and as Raspbian Jessie only seems to support OpenCV 3, I am limited to that. Also I am using QT Creator on Ubuntu to write my programs for the Pi, so using OpenCV 2 in Ubuntu and OpenCV 3 on the Pi would be really cumbersome.
Allright, I solved the Problem (by repeating what I thought I had done already)
What I did:
1. Delete both ROS and OpenCV completely (I reset my Virtual Machine)
2. Download, build and install OpenCV 3
3. [Build ROS Jade from source][1] (not sure if the version makes a difference)
This now makes my code run without a problem on Ubuntu.
But guess what, when trying the same on the Pi 2, I get same error.
So, same procedure:
1. Start from scratch (or make sure both OpenCV and ROS are removed completely)
2. Build and install OpenCV 3
3. Build and install ROS (only Indigo is available for the Pi afaik)
For the last step I only managed to install the ROS_comm version (without GUI-tools and robot-generic libs), but the procedure should be the same.
To conclude, it seems necessary to compile ROS from source with OpenCV already installed.
After this, I am able to stream a videofile between the Pi 2 and my Virtual Machine using ROS´s image_transport and cv_bridge.
Hope this helps someone with the same problem.