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
51namespace
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
108const std::string&
110{
111 return ::registry.at(format).id;
112}
113
114const std::string&
116{
117 return ::registry.at(format).hr_name;
118}
119
121visionx::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
132std::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
143std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry>
145{
146 return ::registry;
147}
148
149bool
151{
152 return ::registry.at(format).compression == Compression::lossless;
153}
154
155bool
157{
158 return ::registry.at(format).framerate == Framerate::dynamic_fps;
159}
160
162visionx::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
194visionx::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 {
207 return std::make_shared<strats::BMPRecordingStrategy>(path, name);
209 return std::make_shared<strats::PNGRecordingStrategy>(path, name, png_high_quality);
211 return std::make_shared<strats::PNGRecordingStrategy>(path, name, png_fast_quality);
213 return std::make_shared<strats::PNGParallelRecordingStrategy>(
214 path, name, png_high_quality, png_thread_pool_size);
216 return std::make_shared<strats::PNGParallelRecordingStrategy>(
217 path, name, png_fast_quality, png_thread_pool_size);
219 return std::make_shared<strats::JPGRecordingStrategy>(path, name, jpg_default_quality);
221 return std::make_shared<strats::AVIRecordingStrategy>(path, name, fps);
223 return std::make_shared<strats::H264RecordingStrategy>(path, name, fps);
224 }
225
226 return nullptr;
227}
228
230visionx::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
266void
267visionx::imrec::takeSnapshot(const CByteImage& image, const std::filesystem::path& filePath)
268{
270}
271
272void
273visionx::imrec::takeSnapshot(const cv::Mat& image, const std::filesystem::path& filePath)
274{
276}
static void recordSnapshot(const cv::Mat &image, const std::filesystem::path &path)
bool isFormatDynamicFramerate(Format format)
const std::string & format2str(const Format format)
std::vector< Format > getFormats()
visionx::imrec::Recording newRecording(const std::filesystem::path &path, const std::string &name, const Format format, double fps)
std::map< Format, RegistryEntry > getFormatsMap()
void takeSnapshot(const CByteImage &image, const std::filesystem::path &filePath)
Takes a snapshot using the default recording method for snapshots.
Format str2format(const std::string &format_str)
const std::string & format2hrstr(const Format format)
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...
Format
Supported recording Formats.
Definition public_api.h:54
std::shared_ptr< visionx::imrec::AbstractPlaybackStrategy > Playback
Convenience alias for an instance of any playback strategy.
std::shared_ptr< AbstractRecordingStrategy > Recording
Convenience alias for any recording strategy.
bool isFormatLossless(Format format)