virtual_camera_mono.cpp
Go to the documentation of this file.
2 
3 #include <jsk_topic_tools/rosparam_utils.h>
4 #include <cv_bridge/cv_bridge.h>
5 #include <string>
6 #include <vector>
7 
8 namespace jsk_perception
9 {
11  {
12  DiagnosticNodelet::onInit();
13  pub_ = advertiseCamera(*pnh_, "image", 1);
14 
15  dynamic_reconfigure::Server<jsk_perception::VirtualCameraMonoConfig>::CallbackType f =
16  boost::bind(&VirtualCameraMono::configCb, this, _1, _2);
17  srv_ = boost::make_shared<dynamic_reconfigure::Server<jsk_perception::VirtualCameraMonoConfig> >(*pnh_);
18  srv_->setCallback(f);
19 
20  pnh_->param("frame_id", trans_.frame_id_, std::string("/elevator_inside_panel"));
21  pnh_->param("child_frame_id", trans_.child_frame_id_, std::string("/virtual_camera_frame"));
22  ROS_INFO("VirutalCmaeraMono(%s) frame_id: %s, chid_frame_id: %s", ros::this_node::getName().c_str(), trans_.frame_id_.c_str(), trans_.child_frame_id_.c_str());
23  pnh_->param("queue_size", queue_size_, 1);
24  std::vector<double> initial_pos, initial_rot;
25  if (jsk_topic_tools::readVectorParameter(*pnh_, "initial_pos", initial_pos)) {
26  trans_.setOrigin(tf::Vector3(initial_pos[0], initial_pos[1], initial_pos[2]));
27  }
28  else {
29  trans_.setOrigin(tf::Vector3(0.7, 0, 0));
30  }
31  if (jsk_topic_tools::readVectorParameter(*pnh_, "initial_rot", initial_rot)) {
32  trans_.setRotation(tf::Quaternion(initial_rot[0], initial_rot[1], initial_rot[2], initial_rot[3]));
33  }
34  else {
35  trans_.setRotation(tf::Quaternion(0.707, 0, 0, -0.707) * tf::Quaternion(0, 0.707, 0, -0.707));
36  }
37  ROS_INFO(" initia_pos : %f %f %f", trans_.getOrigin().getX(), trans_.getOrigin().getY(), trans_.getOrigin().getZ());
38  ROS_INFO(" initia_rot : %f %f %f %f", trans_.getRotation().getX(), trans_.getRotation().getY(), trans_.getRotation().getZ(), trans_.getRotation().getW());
39 
40  poly_.header.frame_id = trans_.frame_id_;
41  geometry_msgs::Point32 pt;
42  pt.x=0, pt.y=1, pt.z=0; poly_.polygon.points.push_back(pt);
43  pt.x=0, pt.y=-1, pt.z=0; poly_.polygon.points.push_back(pt);
44  pt.x=0, pt.y=-1, pt.z=-1; poly_.polygon.points.push_back(pt);
45  pt.x=0, pt.y=1, pt.z=-1; poly_.polygon.points.push_back(pt);
46 
47  // parameter subscriber
48  sub_trans_ = nh_->subscribe<geometry_msgs::TransformStamped>("view_point", 1, &VirtualCameraMono::transCb, this);
49  sub_poly_ = nh_->subscribe<geometry_msgs::PolygonStamped>("target_polygon", 1, &VirtualCameraMono::polyCb, this);
50 
51  onInitPostProcess();
52  }
53 
54  void VirtualCameraMono::configCb(Config &config, uint32_t level)
55  {
56  boost::mutex::scoped_lock(mutex_);
57  switch (config.interpolation_method) {
58  case 0:
59  interpolation_method_ = cv::INTER_NEAREST;
60  break;
61  case 1:
62  interpolation_method_ = cv::INTER_LINEAR;
63  break;
64  case 2:
65  interpolation_method_ = cv::INTER_AREA;
66  break;
67  case 3:
68  interpolation_method_ = cv::INTER_CUBIC;
69  break;
70  case 4:
71  interpolation_method_ = cv::INTER_LANCZOS4;
72  break;
73  default:
74  ROS_ERROR("Invalid interpolation method: %d", config.interpolation_method);
75  break;
76  }
77  }
78 
80  {
81  ROS_INFO("Subscribing to image topic");
82  it_.reset(new image_transport::ImageTransport(*nh_));
83  sub_ = it_->subscribeCamera("image", queue_size_, &VirtualCameraMono::imageCb, this);
84  ros::V_string names = boost::assign::list_of("image");
85  jsk_topic_tools::warnNoRemap(names);
86  }
87 
89  {
90  ROS_INFO("Unsubscibing from image topic");
91  sub_.shutdown();
92  }
93 
94  void VirtualCameraMono::imageCb(const sensor_msgs::ImageConstPtr& image_msg,
95  const sensor_msgs::CameraInfoConstPtr& info_msg)
96  {
97  vital_checker_->poke();
98  cv_bridge::CvImagePtr cv_ptr;
99  cv::Mat image;
100  try {
101  cv_ptr = cv_bridge::toCvCopy(image_msg, "bgr8");
102  image = cv_ptr->image;
103  }
104  catch (cv_bridge::Exception& ex) {
105  ROS_ERROR("[virtual_camera_mono] Failed to convert image");
106  return;
107  }
108 
110 
113 
114  //
115  ROS_DEBUG("transform image.");
116  cv::Mat outimage = image.clone();
117  if (TransformImage(image, outimage, trans_, poly_, cam_model_)) {
118  ROS_DEBUG("publish image and transform.");
119  sensor_msgs::CameraInfo virtual_info = *info_msg;
120  cv_ptr->image = outimage;
121  sensor_msgs::Image::Ptr img_msg = cv_ptr->toImageMsg();
122  img_msg->header.stamp = trans_.stamp_;
123  virtual_info.header.stamp = trans_.stamp_;
124  img_msg->header.frame_id = trans_.child_frame_id_;
125  virtual_info.header.frame_id = trans_.child_frame_id_;
126  pub_.publish(*img_msg, virtual_info);
127  }
128  }
129 
130  // subscribe target polygon
131  void VirtualCameraMono::polyCb(const geometry_msgs::PolygonStampedConstPtr& poly) { poly_ = *poly; }
132 
133  // subscribe virtual camera pose
134  void VirtualCameraMono::transCb(const geometry_msgs::TransformStampedConstPtr& tf)
135  {
136  trans_.frame_id_ = tf->header.frame_id;
137  trans_.child_frame_id_ = tf->child_frame_id;
138  trans_.setOrigin(tf::Vector3(tf->transform.translation.x,
139  tf->transform.translation.y,
140  tf->transform.translation.z));
141  trans_.setRotation(tf::Quaternion(tf->transform.rotation.x, tf->transform.rotation.y,
142  tf->transform.rotation.z, tf->transform.rotation.w));
143  }
144 
145  // poly is plane only
146  bool VirtualCameraMono::TransformImage(cv::Mat src, cv::Mat dest,
147  tf::StampedTransform& trans, geometry_msgs::PolygonStamped& poly,
149  {
150  try {
151  // transform polygon to camera coordinate and virtual camera coordinate
152  std::vector<tf::Point> target_poly, target_poly_translated;
153  for(std::vector<geometry_msgs::Point32>::iterator pit=poly.polygon.points.begin(); pit != poly.polygon.points.end(); pit++) {
154  geometry_msgs::PointStamped point, cpoint, vpoint;
155  point.point.x = pit->x, point.point.y = pit->y, point.point.z = pit->z;
156  point.header = poly.header;
158  tf_listener_.transformPoint(trans.frame_id_, point, vpoint);
159 
160  tf::Vector3 vpt_vec = trans.inverse() * tf::Vector3(vpoint.point.x, vpoint.point.y, vpoint.point.z);
161 
162  // push
163  target_poly.push_back(tf::Point(cpoint.point.x, cpoint.point.y, cpoint.point.z));
164  target_poly_translated.push_back(tf::Point(vpt_vec.x(),vpt_vec.y(),vpt_vec.z()));
165  }
166 
167  // warp from (cpoint in camera) to (vpoint in virtual camera)
168  cv::Point2f src_pnt[4], dst_pnt[4];
169  for(int i = 0; i < 4; i++) {
170  cv::Point3d xyz(target_poly[i].x(),target_poly[i].y(),target_poly[i].z());
171  cv::Point3d xyz_trans(target_poly_translated[i].x(),
172  target_poly_translated[i].y(),
173  target_poly_translated[i].z());
174  cv::Point2d uv,uv_trans;
175  uv = cam_model_.project3dToPixel(xyz);
176  src_pnt[i] = cv::Point (uv.x, uv.y);
177  uv_trans = cam_model_.project3dToPixel(xyz_trans);
178  dst_pnt[i] = cv::Point (uv_trans.x, uv_trans.y);
179  }
180 
181  cv::Mat map_matrix = cv::getPerspectiveTransform (src_pnt, dst_pnt);
182  cv::warpPerspective (src, dest, map_matrix, dest.size(), interpolation_method_);
183  }
184  catch (tf::TransformException e) {
185  ROS_WARN_THROTTLE(10, "[virtual_camera_mono] failed to transform image: %s", e.what());
186  return false;
187  }
188  return true;
189  }
190 }
191 
tf::Transform::getRotation
Quaternion getRotation() const
jsk_perception::VirtualCameraMono::tf_broadcaster_
tf::TransformBroadcaster tf_broadcaster_
Definition: virtual_camera_mono.h:51
x
x
tf::StampedTransform::stamp_
ros::Time stamp_
jsk_perception::VirtualCameraMono
Definition: virtual_camera_mono.h:23
tf::TransformBroadcaster::sendTransform
void sendTransform(const geometry_msgs::TransformStamped &transform)
image_transport::ImageTransport
jsk_perception::VirtualCameraMono::sub_poly_
ros::Subscriber sub_poly_
Definition: virtual_camera_mono.h:45
jsk_perception::VirtualCameraMono::sub_trans_
ros::Subscriber sub_trans_
Definition: virtual_camera_mono.h:45
jsk_perception::VirtualCameraMono::unsubscribe
virtual void unsubscribe()
Definition: virtual_camera_mono.cpp:88
boost::shared_ptr< CvImage >
i
int i
tf::StampedTransform::child_frame_id_
std::string child_frame_id_
ROS_WARN_THROTTLE
#define ROS_WARN_THROTTLE(period,...)
_1
boost::arg< 1 > _1
jsk_perception::VirtualCameraMono::srv_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
Definition: virtual_camera_mono.h:47
jsk_perception::VirtualCameraMono::interpolation_method_
int interpolation_method_
Definition: virtual_camera_mono.h:55
tf::TransformListener::transformPoint
void transformPoint(const std::string &target_frame, const geometry_msgs::PointStamped &stamped_in, geometry_msgs::PointStamped &stamped_out) const
image_transport::CameraPublisher::publish
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
jsk_perception::VirtualCameraMono::it_
boost::shared_ptr< image_transport::ImageTransport > it_
Definition: virtual_camera_mono.h:48
image_geometry::PinholeCameraModel::project3dToPixel
cv::Point2d project3dToPixel(const cv::Point3d &xyz) const
jsk_perception::VirtualCameraMono::tf_listener_
tf::TransformListener tf_listener_
Definition: virtual_camera_mono.h:49
cv_bridge::Exception
tf::StampedTransform
tf::StampedTransform::frame_id_
std::string frame_id_
image_geometry::PinholeCameraModel::tfFrame
std::string tfFrame() const
class_list_macros.h
jsk_perception::VirtualCameraMono::poly_
geometry_msgs::PolygonStamped poly_
Definition: virtual_camera_mono.h:54
jsk_perception
Definition: add_mask_image.h:48
image_geometry::PinholeCameraModel::fromCameraInfo
bool fromCameraInfo(const sensor_msgs::CameraInfo &msg)
tf::Point
tf::Vector3 Point
tf::Transform::inverse
Transform inverse() const
jsk_perception::VirtualCameraMono::sub_
image_transport::CameraSubscriber sub_
Definition: virtual_camera_mono.h:43
jsk_perception::VirtualCameraMono::TransformImage
virtual bool TransformImage(cv::Mat src, cv::Mat dest, tf::StampedTransform &trans, geometry_msgs::PolygonStamped &poly, image_geometry::PinholeCameraModel &cam_model_)
Definition: virtual_camera_mono.cpp:146
tf::Transform::setRotation
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
jsk_perception::VirtualCameraMono::queue_size_
int queue_size_
Definition: virtual_camera_mono.h:56
jsk_perception::VirtualCameraMono::pub_
image_transport::CameraPublisher pub_
Definition: virtual_camera_mono.h:44
cv_bridge::toCvCopy
CvImagePtr toCvCopy(const sensor_msgs::CompressedImage &source, const std::string &encoding=std::string())
ROS_DEBUG
#define ROS_DEBUG(...)
random_forest_client_sample.img_msg
img_msg
Definition: random_forest_client_sample.py:111
image_transport::CameraSubscriber::shutdown
void shutdown()
_2
boost::arg< 2 > _2
jsk_perception::VirtualCameraMono::transCb
virtual void transCb(const geometry_msgs::TransformStampedConstPtr &tf)
Definition: virtual_camera_mono.cpp:134
jsk_perception::VirtualCameraMono::cam_model_
image_geometry::PinholeCameraModel cam_model_
Definition: virtual_camera_mono.h:50
jsk_perception::VirtualCameraMono::imageCb
virtual void imageCb(const sensor_msgs::ImageConstPtr &image_msg, const sensor_msgs::CameraInfoConstPtr &info_msg)
Definition: virtual_camera_mono.cpp:94
tf::Quaternion::getW
const TFSIMD_FORCE_INLINE tfScalar & getW() const
tf::Transform::setOrigin
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
random_forest_client_sample.point
point
Definition: random_forest_client_sample.py:52
jsk_perception::VirtualCameraMono::onInit
virtual void onInit()
Definition: virtual_camera_mono.cpp:10
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
jsk_perception::VirtualCameraMono::configCb
virtual void configCb(Config &config, uint32_t level)
Definition: virtual_camera_mono.cpp:54
f
f
nodelet::Nodelet
image_geometry::PinholeCameraModel
jsk_perception::VirtualCameraMono::Config
VirtualCameraMonoConfig Config
Definition: virtual_camera_mono.h:26
cv_bridge.h
ROS_ERROR
#define ROS_ERROR(...)
jsk_perception::VirtualCameraMono::subscribe
virtual void subscribe()
Definition: virtual_camera_mono.cpp:79
virtual_camera_mono.h
jsk_perception::VirtualCameraMono::trans_
tf::StampedTransform trans_
Definition: virtual_camera_mono.h:53
tf
ros::V_string
std::vector< std::string > V_string
jsk_perception::VirtualCameraMono::polyCb
virtual void polyCb(const geometry_msgs::PolygonStampedConstPtr &poly)
Definition: virtual_camera_mono.cpp:131
tf2::TransformException
ROS_INFO
#define ROS_INFO(...)
config
config
tf::Quaternion
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_perception::VirtualCameraMono, nodelet::Nodelet)
tf::Transform::getOrigin
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
info_msg
info_msg
ros::Time::now
static Time now()


jsk_perception
Author(s): Manabu Saito, Ryohei Ueda
autogenerated on Fri May 16 2025 03:11:17