00001 #include <ros/ros.h>
00002 #include <nodelet/nodelet.h>
00003 #include <image_transport/image_transport.h>
00004 #include <image_geometry/pinhole_camera_model.h>
00005 #include <cv_bridge/CvBridge.h>
00006
00008
00009
00010
00011
00012 namespace openni_camera {
00013
00014 class RectifyNodelet : public nodelet::Nodelet
00015 {
00016 boost::shared_ptr<image_transport::ImageTransport> it_;
00017 image_transport::CameraSubscriber sub_camera_;
00018 image_transport::Publisher pub_rect_;
00019 image_geometry::PinholeCameraModel model_;
00020 int interpolation_;
00021 int queue_size_;
00022
00023 virtual void onInit();
00024
00025 void connectCb();
00026
00027 void imageCb(const sensor_msgs::ImageConstPtr& image_msg,
00028 const sensor_msgs::CameraInfoConstPtr& info_msg);
00029 };
00030
00031 void RectifyNodelet::onInit()
00032 {
00033 ros::NodeHandle& nh = getNodeHandle();
00034 ros::NodeHandle& param_nh = getPrivateNodeHandle();
00035 it_.reset(new image_transport::ImageTransport(nh));
00036
00037
00038 param_nh.param("queue_size", queue_size_, 5);
00039 param_nh.param("interpolation", interpolation_, (int)cv::INTER_LINEAR);
00041
00042
00043
00044
00045
00046
00047
00048 image_transport::SubscriberStatusCallback connect_cb = boost::bind(&RectifyNodelet::connectCb, this);
00049 pub_rect_ = it_->advertise("image_rect", 1, connect_cb, connect_cb);
00050 }
00051
00052
00053 void RectifyNodelet::connectCb()
00054 {
00055 if (pub_rect_.getNumSubscribers() == 0)
00056 sub_camera_.shutdown();
00057 else if (!sub_camera_)
00058 sub_camera_ = it_->subscribeCamera("image_mono", queue_size_, &RectifyNodelet::imageCb, this);
00059 }
00060
00061 void RectifyNodelet::imageCb(const sensor_msgs::ImageConstPtr& image_msg,
00062 const sensor_msgs::CameraInfoConstPtr& info_msg)
00063 {
00064
00065 if (info_msg->K[0] == 0.0) {
00066 NODELET_ERROR_THROTTLE(30, "Rectified topic '%s' requested but camera publishing '%s' "
00067 "is uncalibrated", pub_rect_.getTopic().c_str(),
00068 sub_camera_.getInfoTopic().c_str());
00069 return;
00070 }
00071
00072
00073 if (info_msg->D.empty() || info_msg->D[0] == 0.0)
00074 {
00075 pub_rect_.publish(image_msg);
00076 return;
00077 }
00078
00079
00080 model_.fromCameraInfo(info_msg);
00081
00082
00083 sensor_msgs::ImagePtr rect_msg = boost::make_shared<sensor_msgs::Image>();
00084 rect_msg->header = image_msg->header;
00085 rect_msg->height = image_msg->height;
00086 rect_msg->width = image_msg->width;
00087 rect_msg->encoding = image_msg->encoding;
00088 rect_msg->step = image_msg->step;
00089 rect_msg->data.resize(rect_msg->height * rect_msg->step);
00090
00091
00092 sensor_msgs::CvBridge image_bridge, rect_bridge;
00093 const cv::Mat image = image_bridge.imgMsgToCv(image_msg);
00094 cv::Mat rect = rect_bridge.imgMsgToCv(rect_msg);
00095
00096
00097 model_.rectifyImage(image, rect, interpolation_);
00098 pub_rect_.publish(rect_msg);
00099 }
00100
00101 }
00102
00103
00104 #include <pluginlib/class_list_macros.h>
00105 PLUGINLIB_DECLARE_CLASS(openni_camera, rectify, openni_camera::RectifyNodelet, nodelet::Nodelet)