public_api.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package visionx::imrec
17  * @author Christian R. G. Dreher <christian.dreher@student.kit.edu>
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 
25 
26 
27 // STD/STL
28 #include <exception>
29 #include <thread>
30 
31 // OpenCV
32 #include <opencv2/core/core.hpp>
33 
34 // Simox
35 #include <SimoxUtility/algorithm.h>
36 
37 // IVT
38 #include <Image/ByteImage.h>
39 
40 // ArmarX
50 
51 
52 namespace
53 {
54  static const std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry> registry =
55  {
56  {
58  {
59  "bmp_img_seq",
60  ".bmp (Bitmap image sequence)",
63  }
64  },
65  {
67  {
68  "png_img_seq",
69  ".png (PNG image sequence, high compression, single-threaded)",
72  }
73  },
74  {
76  {
77  "png_fast_img_seq",
78  ".png (PNG image sequence, fast, single-threaded)",
81  }
82  },
83  {
85  {
86  "png_img_seq",
87  ".png (PNG image sequence, high compression, multi-threaded)",
90  }
91  },
92  {
94  {
95  "png_fast_img_seq",
96  ".png (PNG image sequence, fast, multi-threaded)",
99  }
100  },
101  {
103  {
104  "jpg_img_seq",
105  ".jpg (JPG image sequence)",
108  }
109  },
110  {
112  {
113  "avi_default",
114  ".avi (AVI video)",
117  }
118  },
119  {
121  {
122  "mp4_default",
123  ".mp4 (MP4 video)",
126  }
127  }
128  };
129 
130  // Auto generated inverted lookup map below in this namespace.
131  static const std::map<std::string, visionx::imrec::Format> registry_inv = []()
132  {
133  std::map<std::string, visionx::imrec::Format> m;
134  for (const auto& [format, reg_entry] : ::registry)
135  {
136  m[reg_entry.id] = format;
137  m[reg_entry.hr_name] = format;
138  }
139  return m;
140  }();
141 }
142 
143 
144 const std::string&
146 {
147  return ::registry.at(format).id;
148 }
149 
150 
151 const std::string&
153 {
154  return ::registry.at(format).hr_name;
155 }
156 
157 
159 visionx::imrec::str2format(const std::string& format_str)
160 {
161  if (::registry_inv.find(format_str) == ::registry_inv.end())
162  {
163  const std::string err = "Unknown format str '" + format_str + "' for imrec format.";
164  throw std::runtime_error{err.c_str()};
165  }
166 
167  return ::registry_inv.at(format_str);
168 }
169 
170 
171 std::vector<visionx::imrec::Format>
173 {
174  std::vector<Format> keys;
175  std::transform(::registry.begin(), ::registry.end(), std::back_inserter(keys), [](const auto & e)
176  {
177  return e.first;
178  });
179  return keys;
180 }
181 
182 
183 std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry>
185 {
186  return ::registry;
187 }
188 
189 
190 bool
192 {
193  return ::registry.at(format).compression == Compression::lossless;
194 }
195 
196 
197 bool
199 {
200  return ::registry.at(format).framerate == Framerate::dynamic_fps;
201 }
202 
203 
205 visionx::imrec::newPlayback(const std::filesystem::path& path)
206 {
207  using namespace simox::alg;
208 
209  // String representation just for string operations, so to lower case
210  const std::string pathstr = to_lower(path.string());
211 
212  // Checks against metadata.csv to identify a chunked image sequence as used by the ImageMonitor (individual image recordings)
213  if (ends_with(pathstr, "metadata.csv") or (std::filesystem::is_directory(path) and std::filesystem::exists(path / "metadata.csv")))
214  {
215  return std::make_shared<strats::ChunkedImageSequencePlaybackStrategy>(path);
216  }
217 
218  // If the path is an image file, contains a wildcard, or is a simple directory, try to make sense of the input when interpreted as image sequence
219  const bool isImage = ends_with(pathstr, ".png") or ends_with(pathstr, ".jpg")
220  or ends_with(pathstr, ".jpeg") or ends_with(pathstr, ".bmp");
221  if (isImage or contains(pathstr, "*") or std::filesystem::is_directory(path))
222  {
223  return std::make_shared<strats::ImageSequencePlaybackStrategy>(path);
224  }
225 
226  // Common OpenCV-supported video file extensions
227  if (ends_with(pathstr, ".avi") or ends_with(pathstr, ".mp4"))
228  {
229  return std::make_shared<strats::VideoPlaybackStrategy>(path);
230  }
231 
232  return nullptr;
233 }
234 
235 
237 visionx::imrec::newRecording(const std::filesystem::path& path, const std::string& name, const visionx::imrec::Format format, const double fps)
238 {
239  const unsigned int png_high_quality = 9;
240  const unsigned int png_fast_quality = 1;
241  const unsigned int jpg_default_quality = 95;
242  const unsigned int png_thread_pool_size = std::thread::hardware_concurrency() / 2;
243 
244  switch (format)
245  {
246  case Format::bmp_img_seq:
247  return std::make_shared<strats::BMPRecordingStrategy>(path, name);
248  case Format::png_img_seq:
249  return std::make_shared<strats::PNGRecordingStrategy>(path, name, png_high_quality);
250  case Format::png_fast_img_seq:
251  return std::make_shared<strats::PNGRecordingStrategy>(path, name, png_fast_quality);
252  case Format::png_mt_img_seq:
253  return std::make_shared<strats::PNGParallelRecordingStrategy>(path, name, png_high_quality, png_thread_pool_size);
254  case Format::png_fast_mt_img_seq:
255  return std::make_shared<strats::PNGParallelRecordingStrategy>(path, name, png_fast_quality, png_thread_pool_size);
256  case Format::jpg_img_seq:
257  return std::make_shared<strats::JPGRecordingStrategy>(path, name, jpg_default_quality);
258  case Format::avi_default:
259  return std::make_shared<strats::AVIRecordingStrategy>(path, name, fps);
260  case Format::mp4_default:
261  return std::make_shared<strats::H264RecordingStrategy>(path, name, fps);
262  }
263 
264  return nullptr;
265 }
266 
267 
269 visionx::imrec::newRecording(const std::filesystem::path& path, double fps)
270 {
271  using namespace simox::alg;
272 
273  const std::string ext = to_lower(path.extension().string());
274 
275  Format format;
276 
277  if (ext == ".bmp" or ext == "") // Default (no extention => assume directory).
278  {
279  format = Format::bmp_img_seq;
280  }
281  else if (ext == ".png")
282  {
283  format = Format::png_img_seq;
284  }
285  else if (ext == ".jpg" or ext == ".jpeg")
286  {
287  format = Format::jpg_img_seq;
288  }
289  else if (ext == ".avi")
290  {
291  format = Format::avi_default;
292  }
293  else if (ext == ".mp4")
294  {
295  format = Format::mp4_default;
296  }
297  else
298  {
299  return nullptr;
300  }
301 
302  return newRecording(path.parent_path(), path.stem().string(), format, fps);
303 }
304 
305 
306 void
307 visionx::imrec::takeSnapshot(const CByteImage& image, const std::filesystem::path& filePath)
308 {
309  strats::PNGRecordingStrategy::recordSnapshot(image, filePath);
310 }
311 
312 
313 void
314 visionx::imrec::takeSnapshot(const cv::Mat& image, const std::filesystem::path& filePath)
315 {
316  strats::PNGRecordingStrategy::recordSnapshot(image, filePath);
317 }
visionx::imrec::Format::bmp_img_seq
@ bmp_img_seq
simox::alg
Definition: Impl.cpp:40
visionx::imrec::getFormatsMap
std::map< Format, RegistryEntry > getFormatsMap()
Definition: public_api.cpp:184
visionx::imrec::Format
Format
Supported recording Formats.
Definition: public_api.h:55
visionx::imrec::Framerate::dynamic_fps
@ dynamic_fps
visionx::imrec::getFormats
std::vector< Format > getFormats()
Definition: public_api.cpp:172
visionx::imrec::Format::avi_default
@ avi_default
visionx::imrec::isFormatLossless
bool isFormatLossless(Format format)
Definition: public_api.cpp:191
visionx::imrec::Format::png_fast_mt_img_seq
@ png_fast_mt_img_seq
visionx::imrec::Framerate::static_fps
@ static_fps
AVIRecordingStrategy.h
ImageSequencePlaybackStrategy.h
armarx::armem::contains
bool contains(const MemoryID &general, const MemoryID &specific)
Indicates whether general is "less specific" than, or equal to, specific, i.e.
Definition: MemoryID.cpp:558
visionx::imrec::Playback
std::shared_ptr< visionx::imrec::AbstractPlaybackStrategy > Playback
Convenience alias for an instance of any playback strategy.
Definition: AbstractPlaybackStrategy.h:48
public_api.h
visionx::imrec::format2str
const std::string & format2str(const Format format)
Definition: public_api.cpp:145
H264RecordingStrategy.h
visionx::imrec::Format::png_img_seq
@ png_img_seq
visionx::imrec::Compression::lossless
@ lossless
JPGRecordingStrategy.h
visionx::imrec::takeSnapshot
void takeSnapshot(const CByteImage &image, const std::filesystem::path &filePath)
Takes a snapshot using the default recording method for snapshots.
Definition: public_api.cpp:307
visionx::imrec::format2hrstr
const std::string & format2hrstr(const Format format)
Definition: public_api.cpp:152
visionx::imrec::Format::png_fast_img_seq
@ png_fast_img_seq
visionx::imrec::newRecording
visionx::imrec::Recording newRecording(const std::filesystem::path &path, const std::string &name, const Format format, double fps)
Definition: public_api.cpp:237
BMPRecordingStrategy.h
VideoPlaybackStrategy.h
PNGParallelRecordingStrategy.h
visionx::imrec::Recording
std::shared_ptr< AbstractRecordingStrategy > Recording
Convenience alias for any recording strategy.
Definition: AbstractRecordingStrategy.h:181
visionx::imrec::str2format
Format str2format(const std::string &format_str)
Definition: public_api.cpp:159
visionx::imrec::newPlayback
visionx::imrec::Playback newPlayback(const std::filesystem::path &path)
Instantiates and returns a new playback strategy which is capable of replaying the file or collection...
Definition: public_api.cpp:205
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:315
armarx::ends_with
bool ends_with(const std::string &haystack, const std::string &needle)
Definition: StringHelpers.cpp:50
visionx::imrec::Compression::lossy
@ lossy
visionx::imrec::Format::jpg_img_seq
@ jpg_img_seq
visionx::imrec::Format::png_mt_img_seq
@ png_mt_img_seq
visionx::imrec::Format::mp4_default
@ mp4_default
ChunkedImageSequencePlaybackStrategy.h
visionx::imrec::isFormatDynamicFramerate
bool isFormatDynamicFramerate(Format format)
Definition: public_api.cpp:198
PNGRecordingStrategy.h