gazebo_geotagged_images_plugin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
19 
20 #include <math.h>
21 #include <string>
22 #include <iostream>
23 
24 #include <boost/filesystem.hpp>
25 #include <opencv2/opencv.hpp>
26 
28 
29 using namespace std;
30 using namespace gazebo;
31 using namespace cv;
32 
34 
35 
37  SensorPlugin(), width_(0), height_(0), depth_(0), imageCounter_(0) {}
38 
39 GeotaggedImagesPlugin::~GeotaggedImagesPlugin()
40 {
41  this->parentSensor_.reset();
42  this->camera_.reset();
43 }
44 
45 void GeotaggedImagesPlugin::Load(sensors::SensorPtr sensor, sdf::ElementPtr sdf)
46 {
47  if(kPrintOnPluginLoad) {
48  gzdbg << __FUNCTION__ << "() called." << std::endl;
49  }
50 
51  if (!sensor)
52  gzerr << "Invalid sensor pointer.\n";
53 
54  this->parentSensor_ =
55  std::dynamic_pointer_cast<sensors::CameraSensor>(sensor);
56 
57  if (!this->parentSensor_)
58  {
59  gzerr << "GeotaggedImagesPlugin requires a CameraSensor.\n";
60  }
61 
62  this->camera_ = this->parentSensor_->Camera();
63 
64  if (!this->parentSensor_)
65  {
66  gzerr << "GeotaggedImagesPlugin not attached to a camera sensor\n";
67  return;
68  }
69  scene_ = camera_->GetScene();
70  lastImageTime_ = scene_->SimTime();
71 
72  this->width_ = this->camera_->ImageWidth();
73  this->height_ = this->camera_->ImageHeight();
74  this->depth_ = this->camera_->ImageDepth();
75  this->format_ = this->camera_->ImageFormat();
76 
77  if (sdf->HasElement("robotNamespace")) {
78  namespace_ = sdf->GetElement("robotNamespace")->Get<std::string>();
79  } else {
80  gzwarn << "[gazebo_geotagging_images_camera_plugin] Please specify a robotNamespace.\n";
81  }
82 
83  this->storeIntervalSec_ = 1;
84  if (sdf->HasElement("interval")) {
85  this->storeIntervalSec_ = sdf->GetElement("interval")->Get<float>();
86  }
87 
88  destWidth_ = width_;
89  if (sdf->HasElement("width")) {
90  destWidth_ = sdf->GetElement("width")->Get<int>();
91  }
92  destHeight_ = height_;
93  if (sdf->HasElement("height")) {
94  destHeight_ = sdf->GetElement("height")->Get<int>();
95  }
96 
97 
98  //check if exiftool exists
99  if (system("exiftool -ver &>/dev/null") != 0) {
100  gzerr << "exiftool not found. geotagging_images plugin will be disabled" << endl;
101  gzerr << "On Ubuntu, use 'sudo apt-get install libimage-exiftool-perl' to install" << endl;
102  return;
103  }
104 
105  node_handle_ = transport::NodePtr(new transport::Node());
106  node_handle_->Init(namespace_);
107 
108  this->parentSensor_->SetActive(true);
109 
110  this->newFrameConnection_ = this->camera_->ConnectNewImageFrame(
111  boost::bind(&GeotaggedImagesPlugin::OnNewFrame, this, _1));
112 
113  // This topic is published to by gazebo_mavlink_interface.cpp
115  gpsSub_ = node_handle_->Subscribe("~/gps_position", &GeotaggedImagesPlugin::OnNewGpsPosition, this);
116 
117  storageDir_ = "frames";
118  boost::filesystem::remove_all(storageDir_); //clear existing images
120 }
121 
122 void GeotaggedImagesPlugin::OnNewGpsPosition(ConstVector3dPtr& v)
123 {
124  lastGpsPosition_ = *v;
125  //gzdbg << "got gps pos: "<<lastGpsPosition_.x()<<", "<<lastGpsPosition.y()<<endl;
126 }
127 
128 void GeotaggedImagesPlugin::OnNewFrame(const unsigned char * image)
129 {
130 
131  image = this->camera_->ImageData(0);
132 
133  common::Time currentTime = scene_->SimTime();
134  if (currentTime.Double() - lastImageTime_.Double() < storeIntervalSec_) {
135  return;
136  }
137 
138  Mat frame = Mat(height_, width_, CV_8UC3);
139  Mat frameBGR = Mat(height_, width_, CV_8UC3);
140  frame.data = (uchar*)image; //frame has not the right color format yet -> convert
141  cvtColor(frame, frameBGR, cv::COLOR_RGB2BGR);
142 
143  char file_name[256];
144  snprintf(file_name, sizeof(file_name), "%s/DSC%05i.jpg", storageDir_.c_str(), imageCounter_);
145 
146  if (destWidth_ != width_ || destHeight_ != height_) {
147  Mat frameResized;
148  cv::Size size(destWidth_, destHeight_);
149  cv::resize(frameBGR, frameResized, size);
150  imwrite(file_name, frameResized);
151  } else {
152  imwrite(file_name, frameBGR);
153  }
154 
155  char gps_tag_command[1024];
156  double lat = lastGpsPosition_.x();
157  char north_south = 'N', east_west = 'E';
158  double lon = lastGpsPosition_.y();
159  if (lat < 0.) {
160  lat = -lat;
161  north_south = 'S';
162  }
163  if (lon < 0.) {
164  lon = -lon;
165  east_west = 'W';
166  }
167  snprintf(gps_tag_command, sizeof(gps_tag_command),
168  "exiftool -gpslatituderef=%c -gpslongituderef=%c -gpsaltituderef=above -gpslatitude=%.9lf -gpslongitude=%.9lf"
169 // " -gpsdatetime=now -gpsmapdatum=WGS-84"
170  " -datetimeoriginal=now -gpsdop=0.8"
171  " -gpsmeasuremode=3-d -gpssatellites=13 -gpsaltitude=%.3lf -overwrite_original %s &>/dev/null",
172  north_south, east_west, lat, lon, lastGpsPosition_.z(), file_name);
173 
174  system(gps_tag_command);
175 
176  ++imageCounter_;
177  lastImageTime_ = currentTime;
178 
179 }
GZ_REGISTER_SENSOR_PLUGIN(GazeboGpsPlugin)
Gazebo plugin that saves geotagged camera images to disk.
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
static const bool kPrintOnPluginLoad
Definition: common.h:41
uint8_t size
void create_directory(std::string &path)


rotors_gazebo_plugins
Author(s): Fadri Furrer, Michael Burri, Mina Kamel, Janosch Nikolic, Markus Achtelik
autogenerated on Mon Feb 28 2022 23:39:03