I've installed OpenCV 2.4.8 (libopencv-dev) by using apt-get and receive the following message.
init done opengl support available QMetaMethod::invoke: Unable to invoke methods with return values in queued connections.
I ran the program in gdb and it actually seems to stop and freeze on calling cv::waitKey(30); however, the problem only occurs when I call cv::imshow and it seems to be only when imshow is called in a callback function (in a single threaded program that had imshow in a loop did not exhibit the same problems).
Here is the backtrace:
#0 0x00007ffff27f8d7d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
#1 0x00007ffff376d3c8 in ros::ros_wallsleep(unsigned int, unsigned int) ()
from /opt/ros/indigo/lib/librostime.so
#2 0x00007ffff4890877 in ros::waitForShutdown() () from /opt/ros/indigo/lib/libroscpp.so
#3 0x00007ffff48ac2f8 in ros::MultiThreadedSpinner::spin(ros::CallbackQueue*) ()
from /opt/ros/indigo/lib/libroscpp.so
#4 0x0000000000412267 in CM::Robot::Robot (this=0x7fffffffd210, handle=..., mod=...)
at /home/charlie/turtlebot/packages/mapping/src/robot.cc:88
#5 0x000000000041f128 in main (argc=1, argv=0x7fffffffd468)
at /home/charlie/turtlebot/packages/mapping/src/mapping.cc:32
Here is the output. I added a few cout statements to help decide exactly where the program was freezing.
Before
init done
opengl support available
Between
After
Before
QMetaMethod::invoke: Unable to invoke methods with return values in queued connections
Between
Killed
Here is a simplified version of the code that produces the problem: robot.h
# necessary include statements...
(opencv specific includes)
#include <opencv2/core/core.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <highgui.h>
Robot {
public:
Robot(ros::NodeHandle& handle, const std::string& mod): node(handle), mode(mod){
ros::MultiThreadedSpinner threads(3);
ros::Subscriber odom = node.subscribe("/odom", 1, &Robot::get_pose, this);
ros::Subscriber cloud = node.subscribe("/camera/depth/points", 1, &Robot::add_cloud, this);
threads.spin();
}
void get_pose(nav_msgs::Odometry data){
(...)
}
void add_cloud(sensor_msgs::PointCloud2 cloud){
PointCloud::Ptr cl(new(PointCloud));
pcl::fromROSMsg(cloud, *cl);
cl->width = 640;
cl->height = 480;
extract_surf_features(cl);
(...)
}
void extract_surf_features(pcl::PointCloud<pcl::PointXYZRGB>::Ptr points){
cv::Mat image(cur->height, cur->width, CV_8UC3);
(... get 2d rgb image from point cloud ...)
cv::SURF surf_extractor(500.0); // Hession threshold = 500.0
std::vector<cv::KeyPoint> keypoints;
// actually compute the surf keypoints
surf_extractor(image, cv::Mat(), keypoints);
cv::drawKeypoints(image, keypoints, image, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
cout << "Before\n";
cv::imshow("Image", image);
cout << "Between\n";
cv::waitKey(30);
cout << "After\n";
(...)
}
private:
ros::NodeHandle node;
std::string mode;
}
main.cc:
#include <ros/ros.h>
#include <iostream>
#include "robot.h"
using namespace std;
int main(int argc, char** argv){
ros::init(argc, argv, "PCL_Map");
if (!ros::master::check()){
cout << "\033[1;31mERROR: ROS Master not found. Please Start ROS.\n\033[0m";
return -1;
}
ros::NodeHandle node("/map/pcl");
node.setParam("downsample", 0.04);
CM::Robot robot(node,"SURF");
return 0;
}
I have written another very similar program that does not exhibit the freezing behaviors. This program however does not use ROS or threading.
# necessary include statments (same opencv includes)
void load_next_cloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, int n){
(... Load Point Cloud from file ...)
}
void align(pcl::PointCloud<pcl::PointXYZRGB>::Ptr map,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud,
pcl::PointCloud<pcl::PointXYZ>::Ptr map_feat,
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_feat,
vector<cv::KeyPoint>& map_key_points,
cv::Mat& map_surf_descriptors){
cv::Mat image(cur->height, cur->width, CV_8UC3);
(... get 2d rgb image from point cloud ...)
cv::SURF surf_extractor(500.0);
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
surf_extractor(image, cv::Mat(), keypoints, descriptors);
// cout << keypoints.size() << " " << descriptors.size() << endl;
cv::drawKeypoints(image, keypoints, image, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
cv::imshow("Image", image);
cv::waitKey(30)
(...)
}
int main(){
pcl::PointCloud<pcl::PointXYZRGB>::Ptr map(new(pcl::PointCloud<pcl::PointXYZRGB>));
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp(new(pcl::PointCloud<pcl::PointXYZRGB>));
pcl::PointCloud<pcl::PointXYZ>::Ptr map_features(new(pcl::PointCloud<pcl::PointXYZ>));
pcl::PointCloud<pcl::PointXYZ>::Ptr tmp_features(new(pcl::PointCloud<pcl::PointXYZ>));
cv::Mat map_descriptors;
vector<cv::KeyPoint> map_surf_points;
for(int i = 0; i < 11; ++i){
load_next_cloud(tmp, i);
align(map, tmp, map_features, tmp_features, map_surf_points, map_descriptors);
}
return 0;
}
I know I've posted a lot of code but hopefully this can give some insight as to why the program freezes
I have really no idea how or why the program freezes. Any answers as to why the program freezes or how to fix the problem would be appreciated. Of note, the callback program will show the first image and freeze before showing the second image.
If I keep the imshow but remove the cv::waitKey the program will not freeze but continues to give the QMetaMethods message each time imshow is called. (of course this does not allow the program to show the images in the imshow window).