Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

VideoCapture returns empty Mat and imshow() crashes.

I have following code (in ROS), where I read an Image stream from a webcam, convert it and send it to another ROS program, and display it:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cv_bridge/cv_bridge.h>
#include <thread>
#include <chrono>

using namespace std;

int main(int argc, char** argv) {

    ros::init(argc, argv, "image_publisher");
    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    image_transport::Publisher pub = it.advertise("camera/image", 1);

    cv::VideoCapture cap;
    cap.open(0);
    // give webcam some time
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    // Check if video device can be opened with the given index
    if (!cap.isOpened())
        return 1;
    sensor_msgs::ImagePtr msg;
    ROS_INFO("Webcam publisher running");

    ros::Rate loop_rate(10); 
    while (nh.ok()) {
        cv::Mat frame;
        cap >> frame;
        cout<<"frame type: "<<frame.type()<<"\n";
            cout<<"frame empty: "<<frame.empty()<<"\n";
        // Check if grabbed frame is actually full with some content
        if (!frame.empty()) {
            msg = cv_bridge::CvImage(std_msgs::Header(), "rgb8", frame).toImageMsg();
            pub.publish(msg);
            cv::imshow("Webcam",frame);
            cv::waitKey(0);
        }
        ros::spinOnce();
        loop_rate.sleep();
    }
}

My problem is that the code always outputs "frame empty: 0". The if condition if(!frame.empty()) is nevertheless entered and the ROS msg (created from the frame) which is sent, is just fine. The subscriber to this ROS msg has no problem to read the frame and show it with imshow(). (For those who aren't familiar with ROS: I send the frame to another program where I can read and display it without any problems).

I need to display the frame already in the code above, but it always crashes at cv::imshow("Webcam",frame);, giving the following debugging (with gdb) output:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff760cd20 in cv::_InputArray::size(int) const ()
   from /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4
(gdb) bt
#0  0x00007ffff760cd20 in cv::_InputArray::size(int) const ()
   from /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4
#1  0x00007ffff66e4887 in cv::imshow(cv::String const&, cv::_InputArray const&) () from /usr/local/lib/libopencv_highgui.so.3.0
#2  0x00000000004023c8 in main (argc=1, argv=<optimized out>)
    at /ibox/ros/catkin_ws/src/ros/webcam_publisher/src/webcam_publisher.cpp:41
(gdb)

If I comment the lines cv::imshow("Webcam",frame); (and cv::waitKey(0);), everything works just fine. I am using opencv 3.

Does anybody have a clue what could be going on here?