32 #include <opencv2/core/core.hpp>
35 #include <SimoxUtility/algorithm.h>
38 #include <Image/ByteImage.h>
54 static const std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry> registry =
60 ".bmp (Bitmap image sequence)",
69 ".png (PNG image sequence, high compression, single-threaded)",
78 ".png (PNG image sequence, fast, single-threaded)",
87 ".png (PNG image sequence, high compression, multi-threaded)",
96 ".png (PNG image sequence, fast, multi-threaded)",
105 ".jpg (JPG image sequence)",
131 static const std::map<std::string, visionx::imrec::Format> registry_inv = []()
133 std::map<std::string, visionx::imrec::Format> m;
134 for (
const auto& [format, reg_entry] : ::registry)
136 m[reg_entry.id] = format;
137 m[reg_entry.hr_name] = format;
147 return ::registry.at(format).id;
154 return ::registry.at(format).hr_name;
161 if (::registry_inv.find(format_str) == ::registry_inv.end())
163 const std::string err =
"Unknown format str '" + format_str +
"' for imrec format.";
164 throw std::runtime_error{err.c_str()};
167 return ::registry_inv.at(format_str);
171 std::vector<visionx::imrec::Format>
174 std::vector<Format> keys;
175 std::transform(::registry.begin(), ::registry.end(), std::back_inserter(keys), [](
const auto & e)
183 std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry>
193 return ::registry.at(format).compression == Compression::lossless;
200 return ::registry.at(format).framerate == Framerate::dynamic_fps;
210 const std::string pathstr = to_lower(path.string());
213 if (
ends_with(pathstr,
"metadata.csv") or (std::filesystem::is_directory(path) and std::filesystem::exists(path /
"metadata.csv")))
215 return std::make_shared<strats::ChunkedImageSequencePlaybackStrategy>(path);
221 if (isImage or
contains(pathstr,
"*") or std::filesystem::is_directory(path))
223 return std::make_shared<strats::ImageSequencePlaybackStrategy>(path);
229 return std::make_shared<strats::VideoPlaybackStrategy>(path);
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;
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);
273 const std::string ext = to_lower(path.extension().string());
277 if (ext ==
".bmp" or ext ==
"")
279 format = Format::bmp_img_seq;
281 else if (ext ==
".png")
283 format = Format::png_img_seq;
285 else if (ext ==
".jpg" or ext ==
".jpeg")
287 format = Format::jpg_img_seq;
289 else if (ext ==
".avi")
291 format = Format::avi_default;
293 else if (ext ==
".mp4")
295 format = Format::mp4_default;
302 return newRecording(path.parent_path(), path.stem().string(), format, fps);
309 strats::PNGRecordingStrategy::recordSnapshot(image, filePath);
316 strats::PNGRecordingStrategy::recordSnapshot(image, filePath);