image_publisher_nodelet.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2014, JSK Lab.
5 * 2008, Willow Garage, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 * * Neither the name of the Willow Garage nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *********************************************************************/
35 
36 #include <ros/ros.h>
37 #include <nodelet/nodelet.h>
38 #include <cv_bridge/cv_bridge.h>
39 #include <image_publisher/ImagePublisherConfig.h>
41 #include <sensor_msgs/CameraInfo.h>
43 #include <opencv2/highgui/highgui.hpp>
44 #include <dynamic_reconfigure/server.h>
45 #include <boost/assign.hpp>
46 using namespace boost::assign;
47 
48 namespace image_publisher {
50 {
51  dynamic_reconfigure::Server<image_publisher::ImagePublisherConfig> srv;
52 
54 
57 
58  cv::VideoCapture cap_;
59  cv::Mat image_;
62 
63  std::string frame_id_;
64  std::string filename_;
67  sensor_msgs::CameraInfo camera_info_;
68 
69 
70  void reconfigureCallback(image_publisher::ImagePublisherConfig &new_config, uint32_t level)
71  {
72  frame_id_ = new_config.frame_id;
73 
74  timer_ = nh_.createTimer(ros::Duration(1.0/new_config.publish_rate), &ImagePublisherNodelet::do_work, this);
75 
77  if ( !new_config.camera_info_url.empty() ) {
78  try {
79  c.validateURL(new_config.camera_info_url);
80  c.loadCameraInfo(new_config.camera_info_url);
81  camera_info_ = c.getCameraInfo();
82  } catch(cv::Exception &e) {
83  NODELET_ERROR("camera calibration failed to load: %s %s %s %i", e.err.c_str(), e.func.c_str(), e.file.c_str(), e.line);
84  }
85  }
86 
87 
88  }
89 
90  void do_work(const ros::TimerEvent& event)
91  {
92  // Transform the image.
93  try
94  {
95  if ( cap_.isOpened() ) {
96  if ( ! cap_.read(image_) ) {
97  cap_.set(CV_CAP_PROP_POS_FRAMES, 0);
98  }
99  }
100  if (flip_image_)
101  cv::flip(image_, image_, flip_value_);
102 
103  sensor_msgs::ImagePtr out_img = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image_).toImageMsg();
104  out_img->header.frame_id = frame_id_;
105  out_img->header.stamp = ros::Time::now();
106  camera_info_.header.frame_id = out_img->header.frame_id;
107  camera_info_.header.stamp = out_img->header.stamp;
108 
109  pub_.publish(*out_img, camera_info_);
110  }
111  catch (cv::Exception &e)
112  {
113  NODELET_ERROR("Image processing error: %s %s %s %i", e.err.c_str(), e.func.c_str(), e.file.c_str(), e.line);
114  }
115  }
116 
118  {
119  subscriber_count_++;
120  }
121 
123  {
124  subscriber_count_--;
125  }
126 
127 public:
128  virtual void onInit()
129  {
130  subscriber_count_ = 0;
131  nh_ = getPrivateNodeHandle();
133  pub_ = image_transport::ImageTransport(nh_).advertiseCamera("image_raw", 1);
134 
135  nh_.param("filename", filename_, std::string(""));
136  NODELET_INFO("File name for publishing image is : %s", filename_.c_str());
137  try {
138  image_ = cv::imread(filename_, CV_LOAD_IMAGE_COLOR);
139  if ( image_.empty() ) { // if filename is motion file or device file
140  try { // if filename is number
141  int num = boost::lexical_cast<int>(filename_);//num is 1234798797
142  cap_.open(num);
143  } catch(boost::bad_lexical_cast &) { // if file name is string
144  cap_.open(filename_);
145  }
146  CV_Assert(cap_.isOpened());
147  cap_.read(image_);
148  cap_.set(CV_CAP_PROP_POS_FRAMES, 0);
149  }
150  CV_Assert(!image_.empty());
151  }
152  catch (cv::Exception &e)
153  {
154  NODELET_ERROR("Failed to load image (%s): %s %s %s %i", filename_.c_str(), e.err.c_str(), e.func.c_str(), e.file.c_str(), e.line);
155  }
156 
157  bool flip_horizontal;
158  nh_.param("flip_horizontal", flip_horizontal, false);
159  NODELET_INFO("Flip horizontal image is : %s", ((flip_horizontal)?"true":"false"));
160 
161  bool flip_vertical;
162  nh_.param("flip_vertical", flip_vertical, false);
163  NODELET_INFO("Flip flip_vertical image is : %s", ((flip_vertical)?"true":"false"));
164 
165  // From http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#void flip(InputArray src, OutputArray dst, int flipCode)
166  // FLIP_HORIZONTAL == 1, FLIP_VERTICAL == 0 or FLIP_BOTH == -1
167  flip_image_ = true;
168  if (flip_horizontal && flip_vertical)
169  flip_value_ = 0; // flip both, horizontal and vertical
170  else if (flip_horizontal)
171  flip_value_ = 1;
172  else if (flip_vertical)
173  flip_value_ = -1;
174  else
175  flip_image_ = false;
176 
177  camera_info_.width = image_.cols;
178  camera_info_.height = image_.rows;
179  camera_info_.distortion_model = "plumb_bob";
180  camera_info_.D = list_of(0)(0)(0)(0)(0).convert_to_container<std::vector<double> >();
181  camera_info_.K = list_of(1)(0)(camera_info_.width/2)(0)(1)(camera_info_.height/2)(0)(0)(1);
182  camera_info_.R = list_of(1)(0)(0)(0)(1)(0)(0)(0)(1);
183  camera_info_.P = list_of(1)(0)(camera_info_.width/2)(0)(0)(1)(camera_info_.height/2)(0)(0)(0)(1)(0);
184 
185  timer_ = nh_.createTimer(ros::Duration(1), &ImagePublisherNodelet::do_work, this);
186 
187  dynamic_reconfigure::Server<image_publisher::ImagePublisherConfig>::CallbackType f =
188  boost::bind(&ImagePublisherNodelet::reconfigureCallback, this, _1, _2);
189  srv.setCallback(f);
190  }
191 };
192 }
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
#define NODELET_ERROR(...)
sensor_msgs::CameraInfo getCameraInfo(void)
PLUGINLIB_EXPORT_CLASS(image_publisher::ImagePublisherNodelet, nodelet::Nodelet)
f
bool loadCameraInfo(const std::string &url)
void disconnectCb(const image_transport::SingleSubscriberPublisher &)
void reconfigureCallback(image_publisher::ImagePublisherConfig &new_config, uint32_t level)
bool validateURL(const std::string &url)
CameraPublisher advertiseCamera(const std::string &base_topic, uint32_t queue_size, bool latch=false)
void do_work(const ros::TimerEvent &event)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
dynamic_reconfigure::Server< image_publisher::ImagePublisherConfig > srv
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
#define NODELET_INFO(...)
static Time now()
boost::shared_ptr< image_transport::ImageTransport > it_
sensor_msgs::ImagePtr toImageMsg() const
void connectCb(const image_transport::SingleSubscriberPublisher &ssp)


image_publisher
Author(s): Kei Okada
autogenerated on Thu Nov 7 2019 03:45:01