35#include <SimoxUtility/algorithm/string/string_tools.h>
62namespace fs = std::filesystem;
72 std::vector<std::string> recordingFiles = simox::alg::split(recordingFilesStr,
";");
76 if (recordingFiles.size() != 2)
78 throw LocalException() <<
"Stereo calibration file and/or reference frame were set, "
79 <<
"but there are " << recordingFiles.size() <<
" recording "
80 <<
"files (expected 2).";
83 init_stereo_calibration_file();
84 init_stereo_calibration();
87 auto parse_fps = [](
const std::string& setting,
double source_fps) -> std::tuple<double, double>
92 const unsigned long int prefix_length = std::string(
"sourceX").size();
93 std::string setting_value;
94 std::function<double(
double,
double)> operation;
97 if (setting ==
"source")
99 return std::make_tuple(source_fps, 1.);
102 else if (simox::alg::starts_with(setting,
"source*"))
105 operation = [](
double x,
double y) ->
double {
return x * y; };
106 setting_value = setting.substr(prefix_length);
109 else if (simox::alg::starts_with(setting,
"source/"))
112 operation = [](
double x,
double y) ->
double {
return x / y; };
113 setting_value = setting.substr(prefix_length);
116 else if (simox::alg::starts_with(setting,
"source="))
118 return std::make_tuple(std::stod(setting.substr(prefix_length)), 1.);
124 operation = [](double,
double fps) ->
double {
return fps; };
125 setting_value = setting;
128 const double derived_fps = operation(source_fps, std::stod(setting_value));
129 const double playback_speed_normalisation = source_fps / derived_fps;
131 return std::make_tuple(derived_fps, playback_speed_normalisation);
134 unsigned int refFrameHeight = 0;
135 unsigned int refFrameWidth = 0;
136 unsigned int actual_source_fps = 0;
139 for (std::string
const& recordingFile : recordingFiles)
141 fs::path fullPath = basePath !=
"" ? basePath / recordingFile : fs::path(recordingFile);
147 ARMARX_ERROR <<
"Could not find a playback strategy for '" << fullPath.string() <<
"'";
154 if (refFrameHeight == 0 and refFrameWidth == 0)
156 refFrameHeight =
playback->getFrameHeight();
157 refFrameWidth =
playback->getFrameWidth();
162 <<
"Image source frame height cannot be 0 pixel";
164 <<
"Image source frame width cannot be 0 pixel";
168 <<
"Image source frames must have the same dimensions";
170 <<
"Image source frames must have the same dimensions";
174 if (
playback->getFps() > actual_source_fps)
176 actual_source_fps =
playback->getFps();
181 double playback_speed_normalisation;
182 std::tie(
frameRate, playback_speed_normalisation) =
193 ImageDimension(
static_cast<int>(refFrameWidth),
static_cast<int>(refFrameHeight)),
228 for (
unsigned int i = 0; i < static_cast<unsigned int>(
getNumberImages()); ++i)
233 if (not
playback->hasNextFrame() and loop)
238 const unsigned int current_frame =
static_cast<unsigned int>(std::round(
m_current_frame));
239 const unsigned int min_frame = 0;
240 const unsigned int max_frame =
playback->getFrameCount() - 1;
241 unsigned int frame_index = std::clamp(current_frame, min_frame, max_frame);
242 playback->setCurrentFrame(frame_index);
256 if (memoryEnabled and imageBuffer !=
nullptr)
267 assert_stereo_initialized();
274 assert_stereo_initialized();
281 assert_stereo_initialized();
288 return "PlaybackImageProvider";
296 defs->defineRequiredProperty<std::string>(
298 "List of recording files, separated by semicolons `;` for each channel. For video files, "
299 "use the filename, for image sequences, use the folder name where the image sequence is "
300 "located or any frame as pattern.\n"
301 "Wildcards (e.g. `frame_left_*.jpg;frame_right_*.jpg`) are supported as well.\n"
302 "Files will be interpreted as absolute paths, or relative paths to the current working "
303 "directory if base_path is not set. If base_path is set, all paths in recording_files are "
304 "interpreted relative to base_path");
305 defs->defineOptionalProperty<std::string>(
308 "Common base path of recording_files (will be prepened if set). To unset, use \"\"");
309 defs->defineOptionalProperty<
double>(
"playback_speed_multiplier",
311 "Adjust the playback speed with this multiplier, e.g. `2` "
312 "= double playback speed, `0.5` = "
313 "half playback speed")
315 defs->defineOptionalProperty<std::string>(
318 "Lock the FPS to an absolute value, or a value relative to source FPS. Valid inputs:\n"
319 " 1) `source` => Derive FPS from source\n"
320 " 2) `source*<X>`, with <X> being a positive decimal or integer => Playback with FPS "
322 "source FPS multiplied by <X>\n"
323 " 3) `source/<X>`, with <X> being a positive decimal or integer => Playback with FPS "
325 "source FPS devided by <X>\n"
326 " 4) `<X>`, with <X> being a positive decimal or integer => Playback with FPS at <X>\n"
327 " 5) `source=<X>`, with <X> being a positive decimal or integer => Playback with FPS "
329 "<X>, ignoring source FPS completely (Assume that <X> is source FPS)\n"
330 "With the exception of 5), all settings only have direct effect of the FPS the image "
331 "provider delivers the frames, but not on the playback speed. "
332 "Use `playback_speed_multiplier` to adjust that.\n"
333 "5) is only useful if the metadata of the recording is incomplete or incorrect (for "
334 "example when replaying generic image sequences where the FPS cannot be derived)")
336 R
"(source(\/|\*|=)(\d+(\.\d*)?|\.\d+)|(\d+(\.\d*)?|\.\d+)|(\d+(\.\d*)?|\.\d+)|source)");
337 defs->defineOptionalProperty<bool>(
338 "loop",
true,
"Whether the playback should restart after the last frame was provided");
341 defs->defineOptionalProperty<std::string>(
342 "stereo.calibration_file",
344 "Path to a stereo calibration file that should additionally be provided.");
345 defs->defineOptionalProperty<std::string>(
346 "stereo.reference_frame",
348 "Path to a stereo calibration file that should additionally be provided.");
352 defs->defineOptionalProperty<
bool>(
353 "memory.enable",
true,
"If true, also provide the images as a memory server.");
359PlaybackImageProvider::init_stereo_calibration_file()
371PlaybackImageProvider::init_stereo_calibration()
373 const bool transform_left_camera_to_identity =
true;
377 if (not loading_calibration_sucessful)
387PlaybackImageProvider::assert_stereo_initialized()
391 throw LocalException() <<
"Stereo calibration API was called, but the calibration of this "
392 <<
"PlaybackProvider (instance name '" <<
getName() <<
"') was "
393 <<
"never initialized.\n"
394 <<
"Provide this PlaybackProvider instance with a calibration file "
395 <<
"using the 'stereo.calibration_file' property.";
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Default component property definition container.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
std::string getName() const
Retrieve name of object.
Represents a point in time.
std::int64_t toMicroSecondsSinceEpoch() const
float frameRate
Required frame rate.
void setImageSyncMode(ImageSyncMode imageSyncMode)
Sets the image synchronization mode.
void updateTimestamp(Ice::Long timestamp, bool threadSafe=true)
Updates the timestamp of the currently captured image.
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
int getNumberImages(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve number of images handled by this provider.
void setNumberImages(int numberImages)
Sets the number of images on each capture.
Plugin & getImagesServerPlugin()
virtual std::string getReferenceFrame(const Ice::Current &c=Ice::emptyCurrent) override
std::string m_stereo_reference_frame
std::string m_stereo_calibration_file
virtual ~PlaybackImageProvider() override
bool m_stereo_initialized
virtual bool getImagesAreUndistorted(const Ice::Current &c=Ice::emptyCurrent) override
virtual visionx::StereoCalibration getStereoCalibration(const Ice::Current &c=Ice::emptyCurrent) override
virtual void onStopCapture() override
This is called when the image provider capturing has been stopped.
virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
virtual void onExitCapturingImageProvider() override
This is called when the Component::onExitComponent() setup is called.
std::vector< visionx::imrec::Playback > m_playbacks
CStereoCalibration m_stereo_calibration_ivt
virtual void onStartCapture(float) override
This is called when the image provider capturing has been started.
virtual void onInitCapturingImageProvider() override
This is called when the Component::onInitComponent() is called.
visionx::StereoCalibration m_stereo_calibration
virtual std::string getDefaultName() const override
Retrieve default name of component.
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
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...
std::shared_ptr< visionx::imrec::AbstractPlaybackStrategy > Playback
Convenience alias for an instance of any playback strategy.