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 namespace
52 {
53  static const std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry> registry = {
55  {"bmp_img_seq",
56  ".bmp (Bitmap image sequence)",
60  {"png_img_seq",
61  ".png (PNG image sequence, high compression, single-threaded)",
65  {"png_fast_img_seq",
66  ".png (PNG image sequence, fast, single-threaded)",
70  {"png_img_seq",
71  ".png (PNG image sequence, high compression, multi-threaded)",
75  {"png_fast_img_seq",
76  ".png (PNG image sequence, fast, multi-threaded)",
80  {"jpg_img_seq",
81  ".jpg (JPG image sequence)",
85  {"avi_default",
86  ".avi (AVI video)",
90  {"mp4_default",
91  ".mp4 (MP4 video)",
94 
95  // Auto generated inverted lookup map below in this namespace.
96  static const std::map<std::string, visionx::imrec::Format> registry_inv = []()
97  {
98  std::map<std::string, visionx::imrec::Format> m;
99  for (const auto& [format, reg_entry] : ::registry)
100  {
101  m[reg_entry.id] = format;
102  m[reg_entry.hr_name] = format;
103  }
104  return m;
105  }();
106 } // namespace
107 
108 const std::string&
110 {
111  return ::registry.at(format).id;
112 }
113 
114 const std::string&
116 {
117  return ::registry.at(format).hr_name;
118 }
119 
121 visionx::imrec::str2format(const std::string& format_str)
122 {
123  if (::registry_inv.find(format_str) == ::registry_inv.end())
124  {
125  const std::string err = "Unknown format str '" + format_str + "' for imrec format.";
126  throw std::runtime_error{err.c_str()};
127  }
128 
129  return ::registry_inv.at(format_str);
130 }
131 
132 std::vector<visionx::imrec::Format>
134 {
135  std::vector<Format> keys;
136  std::transform(::registry.begin(),
137  ::registry.end(),
138  std::back_inserter(keys),
139  [](const auto& e) { return e.first; });
140  return keys;
141 }
142 
143 std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry>
145 {
146  return ::registry;
147 }
148 
149 bool
151 {
152  return ::registry.at(format).compression == Compression::lossless;
153 }
154 
155 bool
157 {
158  return ::registry.at(format).framerate == Framerate::dynamic_fps;
159 }
160 
162 visionx::imrec::newPlayback(const std::filesystem::path& path)
163 {
164  using namespace simox::alg;
165 
166  // String representation just for string operations, so to lower case
167  const std::string pathstr = to_lower(path.string());
168 
169  // Checks against metadata.csv to identify a chunked image sequence as used by the ImageMonitor (individual image recordings)
170  if (ends_with(pathstr, "metadata.csv") or
171  (std::filesystem::is_directory(path) and std::filesystem::exists(path / "metadata.csv")))
172  {
173  return std::make_shared<strats::ChunkedImageSequencePlaybackStrategy>(path);
174  }
175 
176  // 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
177  const bool isImage = ends_with(pathstr, ".png") or ends_with(pathstr, ".jpg") or
178  ends_with(pathstr, ".jpeg") or ends_with(pathstr, ".bmp");
179  if (isImage or contains(pathstr, "*") or std::filesystem::is_directory(path))
180  {
181  return std::make_shared<strats::ImageSequencePlaybackStrategy>(path);
182  }
183 
184  // Common OpenCV-supported video file extensions
185  if (ends_with(pathstr, ".avi") or ends_with(pathstr, ".mp4"))
186  {
187  return std::make_shared<strats::VideoPlaybackStrategy>(path);
188  }
189 
190  return nullptr;
191 }
192 
194 visionx::imrec::newRecording(const std::filesystem::path& path,
195  const std::string& name,
196  const visionx::imrec::Format format,
197  const double fps)
198 {
199  const unsigned int png_high_quality = 9;
200  const unsigned int png_fast_quality = 1;
201  const unsigned int jpg_default_quality = 95;
202  const unsigned int png_thread_pool_size = std::thread::hardware_concurrency() / 2;
203 
204  switch (format)
205  {
206  case Format::bmp_img_seq:
207  return std::make_shared<strats::BMPRecordingStrategy>(path, name);
208  case Format::png_img_seq:
209  return std::make_shared<strats::PNGRecordingStrategy>(path, name, png_high_quality);
210  case Format::png_fast_img_seq:
211  return std::make_shared<strats::PNGRecordingStrategy>(path, name, png_fast_quality);
212  case Format::png_mt_img_seq:
213  return std::make_shared<strats::PNGParallelRecordingStrategy>(
214  path, name, png_high_quality, png_thread_pool_size);
215  case Format::png_fast_mt_img_seq:
216  return std::make_shared<strats::PNGParallelRecordingStrategy>(
217  path, name, png_fast_quality, png_thread_pool_size);
218  case Format::jpg_img_seq:
219  return std::make_shared<strats::JPGRecordingStrategy>(path, name, jpg_default_quality);
220  case Format::avi_default:
221  return std::make_shared<strats::AVIRecordingStrategy>(path, name, fps);
222  case Format::mp4_default:
223  return std::make_shared<strats::H264RecordingStrategy>(path, name, fps);
224  }
225 
226  return nullptr;
227 }
228 
230 visionx::imrec::newRecording(const std::filesystem::path& path, double fps)
231 {
232  using namespace simox::alg;
233 
234  const std::string ext = to_lower(path.extension().string());
235 
236  Format format;
237 
238  if (ext == ".bmp" or ext == "") // Default (no extention => assume directory).
239  {
240  format = Format::bmp_img_seq;
241  }
242  else if (ext == ".png")
243  {
244  format = Format::png_img_seq;
245  }
246  else if (ext == ".jpg" or ext == ".jpeg")
247  {
248  format = Format::jpg_img_seq;
249  }
250  else if (ext == ".avi")
251  {
252  format = Format::avi_default;
253  }
254  else if (ext == ".mp4")
255  {
256  format = Format::mp4_default;
257  }
258  else
259  {
260  return nullptr;
261  }
262 
263  return newRecording(path.parent_path(), path.stem().string(), format, fps);
264 }
265 
266 void
267 visionx::imrec::takeSnapshot(const CByteImage& image, const std::filesystem::path& filePath)
268 {
269  strats::PNGRecordingStrategy::recordSnapshot(image, filePath);
270 }
271 
272 void
273 visionx::imrec::takeSnapshot(const cv::Mat& image, const std::filesystem::path& filePath)
274 {
275  strats::PNGRecordingStrategy::recordSnapshot(image, filePath);
276 }
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:144
visionx::imrec::Format
Format
Supported recording Formats.
Definition: public_api.h:53
visionx::imrec::Framerate::dynamic_fps
@ dynamic_fps
visionx::imrec::getFormats
std::vector< Format > getFormats()
Definition: public_api.cpp:133
visionx::imrec::Format::avi_default
@ avi_default
visionx::imrec::isFormatLossless
bool isFormatLossless(Format format)
Definition: public_api.cpp:150
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:563
visionx::imrec::Playback
std::shared_ptr< visionx::imrec::AbstractPlaybackStrategy > Playback
Convenience alias for an instance of any playback strategy.
Definition: AbstractPlaybackStrategy.h:47
public_api.h
visionx::imrec::format2str
const std::string & format2str(const Format format)
Definition: public_api.cpp:109
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:267
visionx::imrec::format2hrstr
const std::string & format2hrstr(const Format format)
Definition: public_api.cpp:115
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:194
BMPRecordingStrategy.h
VideoPlaybackStrategy.h
PNGParallelRecordingStrategy.h
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:351
visionx::imrec::Recording
std::shared_ptr< AbstractRecordingStrategy > Recording
Convenience alias for any recording strategy.
Definition: AbstractRecordingStrategy.h:179
visionx::imrec::str2format
Format str2format(const std::string &format_str)
Definition: public_api.cpp:121
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:162
armarx::ends_with
bool ends_with(const std::string &haystack, const std::string &needle)
Definition: StringHelpers.cpp:53
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:156
PNGRecordingStrategy.h