32 #include <opencv2/core/core.hpp>
35 #include <SimoxUtility/algorithm.h>
38 #include <Image/ByteImage.h>
53 static const std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry> registry = {
56 ".bmp (Bitmap image sequence)",
61 ".png (PNG image sequence, high compression, single-threaded)",
66 ".png (PNG image sequence, fast, single-threaded)",
71 ".png (PNG image sequence, high compression, multi-threaded)",
76 ".png (PNG image sequence, fast, multi-threaded)",
81 ".jpg (JPG image sequence)",
96 static const std::map<std::string, visionx::imrec::Format> registry_inv = []()
98 std::map<std::string, visionx::imrec::Format> m;
99 for (
const auto& [format, reg_entry] : ::registry)
101 m[reg_entry.id] = format;
102 m[reg_entry.hr_name] = format;
111 return ::registry.at(format).id;
117 return ::registry.at(format).hr_name;
123 if (::registry_inv.find(format_str) == ::registry_inv.end())
125 const std::string err =
"Unknown format str '" + format_str +
"' for imrec format.";
126 throw std::runtime_error{err.c_str()};
129 return ::registry_inv.at(format_str);
132 std::vector<visionx::imrec::Format>
135 std::vector<Format> keys;
138 std::back_inserter(keys),
139 [](
const auto& e) { return e.first; });
143 std::map<visionx::imrec::Format, visionx::imrec::RegistryEntry>
152 return ::registry.at(format).compression == Compression::lossless;
158 return ::registry.at(format).framerate == Framerate::dynamic_fps;
167 const std::string pathstr = to_lower(path.string());
170 if (
ends_with(pathstr,
"metadata.csv") or
171 (std::filesystem::is_directory(path) and std::filesystem::exists(path /
"metadata.csv")))
173 return std::make_shared<strats::ChunkedImageSequencePlaybackStrategy>(path);
179 if (isImage or
contains(pathstr,
"*") or std::filesystem::is_directory(path))
181 return std::make_shared<strats::ImageSequencePlaybackStrategy>(path);
187 return std::make_shared<strats::VideoPlaybackStrategy>(path);
195 const std::string& name,
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;
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);
234 const std::string ext = to_lower(path.extension().string());
238 if (ext ==
".bmp" or ext ==
"")
240 format = Format::bmp_img_seq;
242 else if (ext ==
".png")
244 format = Format::png_img_seq;
246 else if (ext ==
".jpg" or ext ==
".jpeg")
248 format = Format::jpg_img_seq;
250 else if (ext ==
".avi")
252 format = Format::avi_default;
254 else if (ext ==
".mp4")
256 format = Format::mp4_default;
263 return newRecording(path.parent_path(), path.stem().string(), format, fps);
269 strats::PNGRecordingStrategy::recordSnapshot(image, filePath);
275 strats::PNGRecordingStrategy::recordSnapshot(image, filePath);