20 #include "trackerdata.pb.h"
21 #include <google/protobuf/util/time_util.h>
23 using google::protobuf::util::TimeUtil;
34 : delta_x(0.0), delta_y(0.0),
35 scale_x(1.0), scale_y(1.0), rotation(0.0),
36 background_alpha(1.0), background_corner(0),
37 stroke_width(2) , stroke_alpha(0.0),
38 stroke(Red, Green, Blue, Alfa),
39 background(0, 0, 255, 0)
41 this->TimeScale = 1.0;
53 BBox newBBox =
BBox(_cx, _cy, _width, _height, _angle);
58 auto BBoxIterator =
BoxVec.find(time);
60 if (BBoxIterator !=
BoxVec.end())
63 BBoxIterator->second = newBBox;
68 BoxVec.insert({time, newBBox});
88 auto it =
BoxVec.lower_bound(time);
102 auto it =
BoxVec.find(time);
116 auto it =
BoxVec.find(time);
129 double time = this->
FrameNToTime(frame_number, this->TimeScale);
133 auto currentBBoxIterator =
BoxVec.lower_bound(time);
136 if (currentBBoxIterator ==
BoxVec.end())
144 if ((currentBBoxIterator->first == time) || (currentBBoxIterator ==
BoxVec.begin()))
147 BBox currentBBox = currentBBoxIterator->second;
160 BBox currentBBox = currentBBoxIterator->second;
162 BBox previousBBox = prev(currentBBoxIterator, 1)->second;
165 BBox interpolatedBBox =
InterpolateBoxes(prev(currentBBoxIterator, 1)->first, currentBBoxIterator->first,
166 previousBBox, currentBBox, time);
175 return interpolatedBBox;
209 return interpolatedBox;
225 double time = ((double)frame_number) * this->BaseFps.
Reciprocal().
ToDouble() * (1.0 / time_scale);
232 this->TimeScale = time_scale;
241 pb_tracker::Tracker bboxMessage;
244 std::fstream input(inputFilePath, ios::in | ios::binary);
247 if (!bboxMessage.ParseFromIstream(&input))
249 std::cerr <<
"Failed to parse protobuf message." << std::endl;
256 for (
size_t i = 0; i < bboxMessage.frame_size(); i++)
259 const pb_tracker::Frame &pbFrameData = bboxMessage.frame(i);
262 size_t frame_number = pbFrameData.id();
265 const pb_tracker::Frame::Box &box = pbFrameData.bounding_box();
267 float width = box.x2() - box.x1();
268 float height = box.y2() - box.y1();
269 float cx = box.x1() + width/2;
270 float cy = box.y1() + height/2;
274 if ( (cx >= 0.0) && (cy >= 0.0) && (width >= 0.0) && (height >= 0.0) )
277 this->
AddBox(frame_number, cx, cy, width, height, angle);
282 if (bboxMessage.has_last_updated())
284 std::cout <<
" Loaded Data. Saved Time Stamp: "
285 << TimeUtil::ToString(bboxMessage.last_updated()) << std::endl;
289 google::protobuf::ShutdownProtobufLibrary();
314 root[
"box_id"] =
Id();
315 root[
"BaseFPS"][
"num"] = BaseFps.
num;
316 root[
"BaseFPS"][
"den"] = BaseFps.
den;
317 root[
"TimeScale"] = TimeScale;
349 catch (
const std::exception &e)
352 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
362 if (!root[
"box_id"].isNull() && root[
"box_id"].asString() !=
"")
363 Id(root[
"box_id"].asString());
366 if (!root[
"BaseFPS"].isNull() && root[
"BaseFPS"].isObject())
368 if (!root[
"BaseFPS"][
"num"].isNull())
369 BaseFps.
num = (int)root[
"BaseFPS"][
"num"].asInt();
370 if (!root[
"BaseFPS"][
"den"].isNull())
371 BaseFps.
den = (
int)root[
"BaseFPS"][
"den"].asInt();
374 if (!root[
"TimeScale"].isNull())
376 double scale = (double)root[
"TimeScale"].asDouble();
380 if (!root[
"protobuf_data_path"].isNull())
384 if (!root[
"child_clip_id"].isNull() && root[
"child_clip_id"].asString() !=
Id()){
389 if (!root[
"delta_x"].isNull())
391 if (!root[
"delta_y"].isNull())
393 if (!root[
"scale_x"].isNull())
395 if (!root[
"scale_y"].isNull())
397 if (!root[
"rotation"].isNull())
399 if (!root[
"visible"].isNull())
401 if (!root[
"draw_box"].isNull())
403 if (!root[
"stroke"].isNull())
405 if (!root[
"background_alpha"].isNull())
407 if (!root[
"background_corner"].isNull())
409 if (!root[
"background"].isNull())
411 if (!root[
"stroke_width"].isNull())
413 if (!root[
"stroke_alpha"].isNull())
427 root[
"box_id"] =
add_property_json(
"Box ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
450 root[
"stroke"] =
add_property_json(
"Border", 0.0,
"color",
"", NULL, 0, 255,
false, requested_frame);
460 root[
"background"] =
add_property_json(
"Background", 0.0,
"color",
"", NULL, 0, 255,
false, requested_frame);
474 const Point requested_point(requested_frame, requested_frame);
477 Json::Value prop = Json::Value(Json::objectValue);
479 prop[
"value"] = value;
482 prop[
"min"] = min_value;
483 prop[
"max"] = max_value;
485 prop[
"keyframe"] = keyframe->
Contains(requested_point);
486 prop[
"points"] = int(keyframe->
GetCount());
489 prop[
"closest_point_x"] = closest_point.
co.
X;
493 prop[
"keyframe"] =
false;
496 prop[
"closest_point_x"] = -1;
497 prop[
"previous_point_x"] = -1;
500 prop[
"readonly"] = readonly;
501 prop[
"choices"] = Json::Value(Json::arrayValue);
511 std::map<std::string, float> boxValues;
517 boxValues[
"cx"] = box.
cx;
518 boxValues[
"cy"] = box.
cy;
519 boxValues[
"w"] = box.
width;
520 boxValues[
"h"] = box.
height;
521 boxValues[
"ang"] = box.
angle;
543 float parentClip_frame_number = round(frame_number - parentClip_start_position) + parentClip_start_frame;
546 float parentClip_location_x =
parentClip->location_x.GetValue(parentClip_frame_number);
547 float parentClip_location_y =
parentClip->location_y.GetValue(parentClip_frame_number);
548 float parentClip_scale_x =
parentClip->scale_x.GetValue(parentClip_frame_number);
549 float parentClip_scale_y =
parentClip->scale_y.GetValue(parentClip_frame_number);
550 float parentClip_rotation =
parentClip->rotation.GetValue(parentClip_frame_number);
553 std::map<std::string, float> parentClipProperties;
556 parentClipProperties[
"frame_number"] = parentClip_frame_number;
557 parentClipProperties[
"timeline_frame_number"] = frame_number;
558 parentClipProperties[
"location_x"] = parentClip_location_x;
559 parentClipProperties[
"location_y"] = parentClip_location_y;
560 parentClipProperties[
"scale_x"] = parentClip_scale_x;
561 parentClipProperties[
"scale_y"] = parentClip_scale_y;
562 parentClipProperties[
"rotation"] = parentClip_rotation;
564 return parentClipProperties;
Header file for Clip class.
Header file for the TrackedObjectBBox class.
float Start() const
Get start position (in seconds) of clip (trim start of video)
float Position() const
Get position on timeline (in seconds)
This class represents a clip (used to arrange readers on the timeline)
openshot::Keyframe blue
Curve representing the red value (0 - 255)
openshot::Keyframe red
Curve representing the red value (0 - 255)
openshot::Keyframe green
Curve representing the green value (0 - 255)
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Json::Value JsonValue() const
Generate Json::Value for this object.
double X
The X value of the coordinate (usually representing the frame #)
double Y
The Y value of the coordinate (usually representing the value of the property being animated)
This class represents a fraction.
int num
Numerator for the fraction.
double ToDouble() const
Return this fraction as a double (i.e. 1/2 = 0.5)
Fraction Reciprocal() const
Return the reciprocal as a Fraction.
int den
Denominator for the fraction.
Exception for invalid JSON.
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
bool Contains(Point p) const
Does this keyframe contain a specific point.
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Point GetPreviousPoint(Point p) const
Get previous point (.
double GetValue(int64_t index) const
Get the value at a specific index.
Json::Value JsonValue() const
Generate Json::Value for this object.
int64_t GetCount() const
Get the number of points (i.e. # of points)
Point GetClosestPoint(Point p) const
Get current point (or closest point to the right) from the X coordinate (i.e. the frame number)
A Point is the basic building block of a key-frame curve.
Coordinate co
This is the primary coordinate.
InterpolationType interpolation
This is the interpolation mode.
This class contains the properties of a tracked object and functions to manipulate it.
Keyframe delta_x
X-direction displacement Keyframe.
bool LoadBoxData(std::string inputFilePath)
Load the bounding-boxes information from the protobuf file.
Color stroke
Border line color.
Keyframe rotation
Rotation Keyframe.
int64_t GetLength() const
Get the size of BoxVec map.
Keyframe stroke_width
Thickness of border line.
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
std::map< std::string, float > GetParentClipProperties(int64_t frame_number) const override
Return a map that contains the properties of this object's parent clip.
void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) override
Add a BBox to the BoxVec map.
TrackedObjectBBox()
Default Constructor.
void SetBaseFPS(Fraction fps)
Update object's BaseFps.
void SetJson(const std::string value) override
Load JSON string into this object.
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const
void clear()
Clear the BoxVec map.
Keyframe delta_y
Y-direction displacement Keyframe.
Color background
Background fill color.
std::map< double, BBox > BoxVec
Index the bounding-box by time of each frame.
std::string Json() const override
Get and Set JSON methods.
bool ExactlyContains(int64_t frame_number) const override
Check if there is a bounding-box in the exact frame number.
void ScalePoints(double scale) override
Update the TimeScale member variable.
BBox InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target)
Interpolate the bouding-boxes properties.
Fraction GetBaseFPS()
Return the object's BaseFps.
Json::Value PropertiesJSON(int64_t requested_frame) const override
Keyframe background_alpha
Background box opacity.
void RemoveBox(int64_t frame_number)
Remove a bounding-box from the BoxVec map.
bool Contains(int64_t frame_number) const
Check if there is a bounding-box in the given frame.
std::map< std::string, float > GetBoxValues(int64_t frame_number) const override
Return a map that contains the bounding box properties and it's keyframes indexed by their names.
Json::Value JsonValue() const override
Generate Json::Value for this object.
Keyframe scale_y
Y-direction scale Keyframe.
std::string protobufDataPath
Path to the protobuf file that holds the bounding box points across the frames.
Keyframe stroke_alpha
Stroke box opacity.
double FrameNToTime(int64_t frame_number, double time_scale) const
Get the time of the given frame.
Keyframe scale_x
X-direction scale Keyframe.
BBox GetBox(int64_t frame_number)
Return a bounding-box from BoxVec with it's properties adjusted by the Keyframes.
Keyframe background_corner
Radius of rounded corners.
std::string ChildClipId() const
Get and set the Id of the childClip of this object.
ClipBase * ParentClip() const
Get and set the parentClip of this object.
Json::Value add_property_choice_json(std::string name, int value, int selected_value) const
Generate JSON choice for a property (dropdown properties)
std::string Id() const
Get the id of this object.
This namespace is the default namespace for all code in the openshot library.
double InterpolateBetween(Point const &left, Point const &right, double target, double allowed_error)
Interpolate two points using the right Point's interpolation method.
const Json::Value stringToJson(const std::string value)
@ CONSTANT
Constant curves jump from their previous position to a new one (with no interpolation).
@ LINEAR
Linear curves are angular, straight lines between two points.
This struct holds the information of a bounding-box.
float cy
y-coordinate of the bounding box center
float height
bounding box height
float cx
x-coordinate of the bounding box center
float width
bounding box width
float angle
bounding box rotation angle [degrees]