36 #include "protobuf_messages/trackerdata.pb.h"
37 #include <google/protobuf/util/time_util.h>
39 using google::protobuf::util::TimeUtil;
50 : delta_x(0.0), delta_y(0.0),
51 scale_x(1.0), scale_y(1.0), rotation(0.0),
52 background_alpha(1.0), background_corner(0),
53 stroke_width(2) , stroke_alpha(0.0),
54 stroke(Red, Green, Blue, Alfa),
55 background(0, 0, 255, 0)
57 this->TimeScale = 1.0;
69 BBox newBBox =
BBox(_cx, _cy, _width, _height, _angle);
74 auto BBoxIterator =
BoxVec.find(time);
76 if (BBoxIterator !=
BoxVec.end())
79 BBoxIterator->second = newBBox;
84 BoxVec.insert({time, newBBox});
104 auto it =
BoxVec.lower_bound(time);
118 auto it =
BoxVec.find(time);
132 auto it =
BoxVec.find(time);
145 double time = this->
FrameNToTime(frame_number, this->TimeScale);
149 auto currentBBoxIterator =
BoxVec.lower_bound(time);
152 if (currentBBoxIterator ==
BoxVec.end())
160 if ((currentBBoxIterator->first == time) || (currentBBoxIterator ==
BoxVec.begin()))
163 BBox currentBBox = currentBBoxIterator->second;
176 BBox currentBBox = currentBBoxIterator->second;
178 BBox previousBBox = prev(currentBBoxIterator, 1)->second;
181 BBox interpolatedBBox =
InterpolateBoxes(prev(currentBBoxIterator, 1)->first, currentBBoxIterator->first,
182 previousBBox, currentBBox, time);
191 return interpolatedBBox;
225 return interpolatedBox;
241 double time = ((double)frame_number) * this->BaseFps.
Reciprocal().
ToDouble() * (1.0 / time_scale);
248 this->TimeScale = time_scale;
257 pb_tracker::Tracker bboxMessage;
260 std::fstream input(inputFilePath, ios::in | ios::binary);
263 if (!bboxMessage.ParseFromIstream(&input))
265 std::cerr <<
"Failed to parse protobuf message." << std::endl;
272 for (
size_t i = 0; i < bboxMessage.frame_size(); i++)
275 const pb_tracker::Frame &pbFrameData = bboxMessage.frame(i);
278 size_t frame_number = pbFrameData.id();
281 const pb_tracker::Frame::Box &box = pbFrameData.bounding_box();
283 float width = box.x2() - box.x1();
284 float height = box.y2() - box.y1();
285 float cx = box.x1() + width/2;
286 float cy = box.y1() + height/2;
290 if ( (cx >= 0.0) && (cy >= 0.0) && (width >= 0.0) && (height >= 0.0) )
293 this->
AddBox(frame_number, cx, cy, width, height, angle);
298 if (bboxMessage.has_last_updated())
300 std::cout <<
" Loaded Data. Saved Time Stamp: "
301 << TimeUtil::ToString(bboxMessage.last_updated()) << std::endl;
305 google::protobuf::ShutdownProtobufLibrary();
330 root[
"box_id"] =
Id();
331 root[
"BaseFPS"][
"num"] = BaseFps.
num;
332 root[
"BaseFPS"][
"den"] = BaseFps.
den;
333 root[
"TimeScale"] = TimeScale;
365 catch (
const std::exception &e)
368 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
378 if (!root[
"box_id"].isNull() && root[
"box_id"].asString() !=
"")
379 Id(root[
"box_id"].asString());
382 if (!root[
"BaseFPS"].isNull() && root[
"BaseFPS"].isObject())
384 if (!root[
"BaseFPS"][
"num"].isNull())
385 BaseFps.
num = (int)root[
"BaseFPS"][
"num"].asInt();
386 if (!root[
"BaseFPS"][
"den"].isNull())
387 BaseFps.
den = (
int)root[
"BaseFPS"][
"den"].asInt();
390 if (!root[
"TimeScale"].isNull())
392 double scale = (double)root[
"TimeScale"].asDouble();
396 if (!root[
"protobuf_data_path"].isNull())
400 if (!root[
"child_clip_id"].isNull() && root[
"child_clip_id"].asString() !=
"" && root[
"child_clip_id"].asString() !=
Id()){
403 if (root[
"child_clip_id"].asString() !=
parentClip->
Id())
408 if (!root[
"delta_x"].isNull())
410 if (!root[
"delta_y"].isNull())
412 if (!root[
"scale_x"].isNull())
414 if (!root[
"scale_y"].isNull())
416 if (!root[
"rotation"].isNull())
418 if (!root[
"visible"].isNull())
420 if (!root[
"draw_box"].isNull())
422 if (!root[
"stroke"].isNull())
424 if (!root[
"background_alpha"].isNull())
426 if (!root[
"background_corner"].isNull())
428 if (!root[
"background"].isNull())
430 if (!root[
"stroke_width"].isNull())
432 if (!root[
"stroke_alpha"].isNull())
446 root[
"box_id"] =
add_property_json(
"Box ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
469 root[
"stroke"] =
add_property_json(
"Border", 0.0,
"color",
"", NULL, 0, 255,
false, requested_frame);
479 root[
"background"] =
add_property_json(
"Background", 0.0,
"color",
"", NULL, 0, 255,
false, requested_frame);
493 const Point requested_point(requested_frame, requested_frame);
496 Json::Value prop = Json::Value(Json::objectValue);
498 prop[
"value"] = value;
501 prop[
"min"] = min_value;
502 prop[
"max"] = max_value;
504 prop[
"keyframe"] = keyframe->
Contains(requested_point);
505 prop[
"points"] = int(keyframe->
GetCount());
508 prop[
"closest_point_x"] = closest_point.
co.
X;
512 prop[
"keyframe"] =
false;
515 prop[
"closest_point_x"] = -1;
516 prop[
"previous_point_x"] = -1;
519 prop[
"readonly"] = readonly;
520 prop[
"choices"] = Json::Value(Json::arrayValue);
530 std::map<std::string, float> boxValues;
536 boxValues[
"cx"] = box.
cx;
537 boxValues[
"cy"] = box.
cy;
538 boxValues[
"w"] = box.
width;
539 boxValues[
"h"] = box.
height;
540 boxValues[
"ang"] = box.
angle;
562 float parentClip_frame_number = round(frame_number - parentClip_start_position) + parentClip_start_frame;
565 float parentClip_location_x =
parentClip->location_x.GetValue(parentClip_frame_number);
566 float parentClip_location_y =
parentClip->location_y.GetValue(parentClip_frame_number);
567 float parentClip_scale_x =
parentClip->scale_x.GetValue(parentClip_frame_number);
568 float parentClip_scale_y =
parentClip->scale_y.GetValue(parentClip_frame_number);
569 float parentClip_rotation =
parentClip->rotation.GetValue(parentClip_frame_number);
572 std::map<std::string, float> parentClipProperties;
575 parentClipProperties[
"frame_number"] = parentClip_frame_number;
576 parentClipProperties[
"timeline_frame_number"] = frame_number;
577 parentClipProperties[
"location_x"] = parentClip_location_x;
578 parentClipProperties[
"location_y"] = parentClip_location_y;
579 parentClipProperties[
"scale_x"] = parentClip_scale_x;
580 parentClipProperties[
"scale_y"] = parentClip_scale_y;
581 parentClipProperties[
"rotation"] = parentClip_rotation;
583 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)
std::string Id() const
Get the Id of this clip object.
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]