OpenShot Library | libopenshot  0.2.6
TrackedObjectBBox.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Source file for the TrackedObjectBBox class
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  * @author Brenno Caldato <brenno.caldato@outlook.com>
6  *
7  * @ref License
8  */
9 
10 /* LICENSE
11  *
12  * Copyright (c) 2008-2019 OpenShot Studios, LLC
13  * <http://www.openshotstudios.com/>. This file is part of
14  * OpenShot Library (libopenshot), an open-source project dedicated to
15  * delivering high quality video editing and animation solutions to the
16  * world. For more information visit <http://www.openshot.org/>.
17  *
18  * OpenShot Library (libopenshot) is free software: you can redistribute it
19  * and/or modify it under the terms of the GNU Lesser General Public License
20  * as published by the Free Software Foundation, either version 3 of the
21  * License, or (at your option) any later version.
22  *
23  * OpenShot Library (libopenshot) is distributed in the hope that it will be
24  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public License
29  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
30  */
31 
32 #include "TrackedObjectBBox.h"
33 
34 #include "Clip.h"
35 
36 #include "protobuf_messages/trackerdata.pb.h"
37 #include <google/protobuf/util/time_util.h>
38 
39 using google::protobuf::util::TimeUtil;
40 
41 using namespace openshot;
42 
43 // Default Constructor, delegating
45  : TrackedObjectBBox::TrackedObjectBBox(0, 0, 255, 0) {}
46 
47 // Constructor that takes RGBA values for stroke, and sets the bounding-box
48 // displacement as 0 and the scales as 1 for the first frame
49 TrackedObjectBBox::TrackedObjectBBox(int Red, int Green, int Blue, int Alfa)
50  : delta_x(0.0), delta_y(0.0),
51  scale_x(1.0), scale_y(1.0), rotation(0.0),
53  stroke_width(2) , stroke_alpha(0.0),
54  stroke(Red, Green, Blue, Alfa),
55  background(0, 0, 255, 0)
56 {
57  this->TimeScale = 1.0;
58  return;
59 }
60 
61 // Add a BBox to the BoxVec map
62 void TrackedObjectBBox::AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle)
63 {
64  // Check if the given frame number is valid
65  if (_frame_num < 0)
66  return;
67 
68  // Instantiate a new bounding-box
69  BBox newBBox = BBox(_cx, _cy, _width, _height, _angle);
70 
71  // Get the time of given frame
72  double time = this->FrameNToTime(_frame_num, 1.0);
73  // Create an iterator that points to the BoxVec pair indexed by the time of given frame
74  auto BBoxIterator = BoxVec.find(time);
75 
76  if (BBoxIterator != BoxVec.end())
77  {
78  // There is a bounding-box indexed by the time of given frame, update-it
79  BBoxIterator->second = newBBox;
80  }
81  else
82  {
83  // There isn't a bounding-box indexed by the time of given frame, insert a new one
84  BoxVec.insert({time, newBBox});
85  }
86 }
87 
88 // Get the size of BoxVec map
90 {
91  if (BoxVec.empty())
92  return 0;
93  if (BoxVec.size() == 1)
94  return 1;
95  return BoxVec.size();
96 }
97 
98 // Check if there is a bounding-box in the given frame
99 bool TrackedObjectBBox::Contains(int64_t frame_num) const
100 {
101  // Get the time of given frame
102  double time = this->FrameNToTime(frame_num, 1.0);
103  // Create an iterator that points to the BoxVec pair indexed by the time of given frame (or the closest time)
104  auto it = BoxVec.lower_bound(time);
105  if (it == BoxVec.end()){
106  // BoxVec pair not found
107  return false;
108  }
109  return true;
110 }
111 
112 // Check if there is a bounding-box in the exact frame number
113 bool TrackedObjectBBox::ExactlyContains(int64_t frame_number) const
114 {
115  // Get the time of given frame
116  double time = FrameNToTime(frame_number, 1.0);
117  // Create an iterator that points to the BoxVec pair indexed by the exact time of given frame
118  auto it = BoxVec.find(time);
119  if (it == BoxVec.end()){
120  // BoxVec pair not found
121  return false;
122  }
123  return true;
124 }
125 
126 // Remove a bounding-box from the BoxVec map
127 void TrackedObjectBBox::RemoveBox(int64_t frame_number)
128 {
129  // Get the time of given frame
130  double time = this->FrameNToTime(frame_number, 1.0);
131  // Create an iterator that points to the BoxVec pair indexed by the time of given frame
132  auto it = BoxVec.find(time);
133  if (it != BoxVec.end())
134  {
135  // The BoxVec pair exists, so remove it
136  BoxVec.erase(time);
137  }
138  return;
139 }
140 
141 // Return a bounding-box from BoxVec with it's properties adjusted by the Keyframes
142 BBox TrackedObjectBBox::GetBox(int64_t frame_number)
143 {
144  // Get the time position of the given frame.
145  double time = this->FrameNToTime(frame_number, this->TimeScale);
146 
147  // Return a iterator pointing to the BoxVec pair indexed by time or to the pair indexed
148  // by the closest upper time value.
149  auto currentBBoxIterator = BoxVec.lower_bound(time);
150 
151  // Check if there is a pair indexed by time, returns an empty bbox if there isn't.
152  if (currentBBoxIterator == BoxVec.end())
153  {
154  // Create and return an empty bounding-box object
155  BBox emptyBBox;
156  return emptyBBox;
157  }
158 
159  // Check if the iterator matches a BBox indexed by time or points to the first element of BoxVec
160  if ((currentBBoxIterator->first == time) || (currentBBoxIterator == BoxVec.begin()))
161  {
162  // Get the BBox indexed by time
163  BBox currentBBox = currentBBoxIterator->second;
164 
165  // Adjust the BBox properties by the Keyframes values
166  currentBBox.cx += this->delta_x.GetValue(frame_number);
167  currentBBox.cy += this->delta_y.GetValue(frame_number);
168  currentBBox.width *= this->scale_x.GetValue(frame_number);
169  currentBBox.height *= this->scale_y.GetValue(frame_number);
170  currentBBox.angle += this->rotation.GetValue(frame_number);
171 
172  return currentBBox;
173  }
174 
175  // BBox indexed by the closest upper time
176  BBox currentBBox = currentBBoxIterator->second;
177  // BBox indexed by the closet lower time
178  BBox previousBBox = prev(currentBBoxIterator, 1)->second;
179 
180  // Interpolate a BBox in the middle of previousBBox and currentBBox
181  BBox interpolatedBBox = InterpolateBoxes(prev(currentBBoxIterator, 1)->first, currentBBoxIterator->first,
182  previousBBox, currentBBox, time);
183 
184  // Adjust the BBox properties by the Keyframes values
185  interpolatedBBox.cx += this->delta_x.GetValue(frame_number);
186  interpolatedBBox.cy += this->delta_y.GetValue(frame_number);
187  interpolatedBBox.width *= this->scale_x.GetValue(frame_number);
188  interpolatedBBox.height *= this->scale_y.GetValue(frame_number);
189  interpolatedBBox.angle += this->rotation.GetValue(frame_number);
190 
191  return interpolatedBBox;
192 }
193 
194 // Interpolate the bouding-boxes properties
195 BBox TrackedObjectBBox::InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target)
196 {
197  // Interpolate the x-coordinate of the center point
198  Point cx_left(t1, left.cx, openshot::InterpolationType::LINEAR);
199  Point cx_right(t2, right.cx, openshot::InterpolationType::LINEAR);
200  Point cx = InterpolateBetween(cx_left, cx_right, target, 0.01);
201 
202  // Interpolate de y-coordinate of the center point
203  Point cy_left(t1, left.cy, openshot::InterpolationType::LINEAR);
204  Point cy_right(t2, right.cy, openshot::InterpolationType::LINEAR);
205  Point cy = InterpolateBetween(cy_left, cy_right, target, 0.01);
206 
207  // Interpolate the width
208  Point width_left(t1, left.width, openshot::InterpolationType::LINEAR);
209  Point width_right(t2, right.width, openshot::InterpolationType::LINEAR);
210  Point width = InterpolateBetween(width_left, width_right, target, 0.01);
211 
212  // Interpolate the height
213  Point height_left(t1, left.height, openshot::InterpolationType::LINEAR);
214  Point height_right(t2, right.height, openshot::InterpolationType::LINEAR);
215  Point height = InterpolateBetween(height_left, height_right, target, 0.01);
216 
217  // Interpolate the rotation angle
218  Point angle_left(t1, left.angle, openshot::InterpolationType::LINEAR);
219  Point angle_right(t1, right.angle, openshot::InterpolationType::LINEAR);
220  Point angle = InterpolateBetween(angle_left, angle_right, target, 0.01);
221 
222  // Create a bounding box with the interpolated points
223  BBox interpolatedBox(cx.co.Y, cy.co.Y, width.co.Y, height.co.Y, angle.co.Y);
224 
225  return interpolatedBox;
226 }
227 
228 // Update object's BaseFps
230  this->BaseFps = fps;
231  return;
232 }
233 
234 // Return the object's BaseFps
236  return BaseFps;
237 }
238 
239 // Get the time of the given frame
240 double TrackedObjectBBox::FrameNToTime(int64_t frame_number, double time_scale) const{
241  double time = ((double)frame_number) * this->BaseFps.Reciprocal().ToDouble() * (1.0 / time_scale);
242 
243  return time;
244 }
245 
246 // Update the TimeScale member variable
247 void TrackedObjectBBox::ScalePoints(double time_scale){
248  this->TimeScale = time_scale;
249 }
250 
251 // Load the bounding-boxes information from the protobuf file
252 bool TrackedObjectBBox::LoadBoxData(std::string inputFilePath)
253 {
254  using std::ios;
255 
256  // Variable to hold the loaded data
257  pb_tracker::Tracker bboxMessage;
258 
259  // Read the existing tracker message.
260  std::fstream input(inputFilePath, ios::in | ios::binary);
261 
262  // Check if it was able to read the protobuf data
263  if (!bboxMessage.ParseFromIstream(&input))
264  {
265  std::cerr << "Failed to parse protobuf message." << std::endl;
266  return false;
267  }
268 
269  this->clear();
270 
271  // Iterate over all frames of the saved message
272  for (size_t i = 0; i < bboxMessage.frame_size(); i++)
273  {
274  // Get data of the i-th frame
275  const pb_tracker::Frame &pbFrameData = bboxMessage.frame(i);
276 
277  // Get frame number
278  size_t frame_number = pbFrameData.id();
279 
280  // Get bounding box data from current frame
281  const pb_tracker::Frame::Box &box = pbFrameData.bounding_box();
282 
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;
287  float angle = 0.0;
288 
289 
290  if ( (cx >= 0.0) && (cy >= 0.0) && (width >= 0.0) && (height >= 0.0) )
291  {
292  // The bounding-box properties are valid, so add it to the BoxVec map
293  this->AddBox(frame_number, cx, cy, width, height, angle);
294  }
295  }
296 
297  // Show the time stamp from the last update in tracker data file
298  if (bboxMessage.has_last_updated())
299  {
300  std::cout << " Loaded Data. Saved Time Stamp: "
301  << TimeUtil::ToString(bboxMessage.last_updated()) << std::endl;
302  }
303 
304  // Delete all global objects allocated by libprotobuf.
305  google::protobuf::ShutdownProtobufLibrary();
306 
307  return true;
308 }
309 
310 // Clear the BoxVec map
312 {
313  BoxVec.clear();
314 }
315 
316 // Generate JSON string of this object
317 std::string TrackedObjectBBox::Json() const
318 {
319  // Return formatted string
320  return JsonValue().toStyledString();
321 }
322 
323 // Generate Json::Value for this object
324 Json::Value TrackedObjectBBox::JsonValue() const
325 {
326  // Create root json object
327  Json::Value root;
328 
329  // Object's properties
330  root["box_id"] = Id();
331  root["BaseFPS"]["num"] = BaseFps.num;
332  root["BaseFPS"]["den"] = BaseFps.den;
333  root["TimeScale"] = TimeScale;
334  root["child_clip_id"] = ChildClipId();
335 
336  // Keyframe's properties
337  root["delta_x"] = delta_x.JsonValue();
338  root["delta_y"] = delta_y.JsonValue();
339  root["scale_x"] = scale_x.JsonValue();
340  root["scale_y"] = scale_y.JsonValue();
341  root["rotation"] = rotation.JsonValue();
342  root["visible"] = visible.JsonValue();
343  root["draw_box"] = draw_box.JsonValue();
344  root["stroke"] = stroke.JsonValue();
345  root["background_alpha"] = background_alpha.JsonValue();
346  root["background_corner"] = background_corner.JsonValue();
347  root["background"] = background.JsonValue();
348  root["stroke_width"] = stroke_width.JsonValue();
349  root["stroke_alpha"] = stroke_alpha.JsonValue();
350 
351  // return JsonValue
352  return root;
353 }
354 
355 // Load JSON string into this object
356 void TrackedObjectBBox::SetJson(const std::string value)
357 {
358  // Parse JSON string into JSON objects
359  try
360  {
361  const Json::Value root = openshot::stringToJson(value);
362  // Set all values that match
363  SetJsonValue(root);
364  }
365  catch (const std::exception &e)
366  {
367  // Error parsing JSON (or missing keys)
368  throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
369  }
370  return;
371 }
372 
373 // Load Json::Value into this object
374 void TrackedObjectBBox::SetJsonValue(const Json::Value root)
375 {
376 
377  // Set the Id by the given JSON object
378  if (!root["box_id"].isNull() && root["box_id"].asString() != "")
379  Id(root["box_id"].asString());
380 
381  // Set the BaseFps by the given JSON object
382  if (!root["BaseFPS"].isNull() && root["BaseFPS"].isObject())
383  {
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();
388  }
389  // Set the TimeScale by the given JSON object
390  if (!root["TimeScale"].isNull())
391  {
392  double scale = (double)root["TimeScale"].asDouble();
393  this->ScalePoints(scale);
394  }
395  // Set the protobuf data path by the given JSON object
396  if (!root["protobuf_data_path"].isNull())
397  protobufDataPath = root["protobuf_data_path"].asString();
398 
399  // Set the id of the child clip
400  if (!root["child_clip_id"].isNull() && root["child_clip_id"].asString() != "" && root["child_clip_id"].asString() != Id()){
401  Clip* parentClip = (Clip *) ParentClip();
402 
403  if (root["child_clip_id"].asString() != parentClip->Id())
404  ChildClipId(root["child_clip_id"].asString());
405  }
406 
407  // Set the Keyframes by the given JSON object
408  if (!root["delta_x"].isNull())
409  delta_x.SetJsonValue(root["delta_x"]);
410  if (!root["delta_y"].isNull())
411  delta_y.SetJsonValue(root["delta_y"]);
412  if (!root["scale_x"].isNull())
413  scale_x.SetJsonValue(root["scale_x"]);
414  if (!root["scale_y"].isNull())
415  scale_y.SetJsonValue(root["scale_y"]);
416  if (!root["rotation"].isNull())
417  rotation.SetJsonValue(root["rotation"]);
418  if (!root["visible"].isNull())
419  visible.SetJsonValue(root["visible"]);
420  if (!root["draw_box"].isNull())
421  draw_box.SetJsonValue(root["draw_box"]);
422  if (!root["stroke"].isNull())
423  stroke.SetJsonValue(root["stroke"]);
424  if (!root["background_alpha"].isNull())
425  background_alpha.SetJsonValue(root["background_alpha"]);
426  if (!root["background_corner"].isNull())
427  background_corner.SetJsonValue(root["background_corner"]);
428  if (!root["background"].isNull())
429  background.SetJsonValue(root["background"]);
430  if (!root["stroke_width"].isNull())
431  stroke_width.SetJsonValue(root["stroke_width"]);
432  if (!root["stroke_alpha"].isNull())
433  stroke_alpha.SetJsonValue(root["stroke_alpha"]);
434  return;
435 }
436 
437 // Get all properties for a specific frame (perfect for a UI to display the current state
438 // of all properties at any time)
439 Json::Value TrackedObjectBBox::PropertiesJSON(int64_t requested_frame) const
440 {
441  Json::Value root;
442 
443  BBox box = GetBox(requested_frame);
444 
445  // Add the ID of this object to the JSON object
446  root["box_id"] = add_property_json("Box ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame);
447 
448  // Add the ID of this object's child clip to the JSON object
449  root["child_clip_id"] = add_property_json("Child Clip ID", 0.0, "string", ChildClipId(), NULL, -1, -1, false, requested_frame);
450 
451  // Add the data of given frame bounding-box to the JSON object
452  root["x1"] = add_property_json("X1", box.cx-(box.width/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
453  root["y1"] = add_property_json("Y1", box.cy-(box.height/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
454  root["x2"] = add_property_json("X2", box.cx+(box.width/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
455  root["y2"] = add_property_json("Y2", box.cy+(box.height/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
456 
457  // Add the bounding-box Keyframes to the JSON object
458  root["delta_x"] = add_property_json("Displacement X-axis", delta_x.GetValue(requested_frame), "float", "", &delta_x, -1.0, 1.0, false, requested_frame);
459  root["delta_y"] = add_property_json("Displacement Y-axis", delta_y.GetValue(requested_frame), "float", "", &delta_y, -1.0, 1.0, false, requested_frame);
460  root["scale_x"] = add_property_json("Scale (Width)", scale_x.GetValue(requested_frame), "float", "", &scale_x, 0.0, 1.0, false, requested_frame);
461  root["scale_y"] = add_property_json("Scale (Height)", scale_y.GetValue(requested_frame), "float", "", &scale_y, 0.0, 1.0, false, requested_frame);
462  root["rotation"] = add_property_json("Rotation", rotation.GetValue(requested_frame), "float", "", &rotation, 0, 360, false, requested_frame);
463  root["visible"] = add_property_json("Visible", visible.GetValue(requested_frame), "int", "", &visible, 0, 1, false, requested_frame);
464 
465  root["draw_box"] = add_property_json("Draw Box", draw_box.GetValue(requested_frame), "int", "", &draw_box, -1, 1.0, false, requested_frame);
466  root["draw_box"]["choices"].append(add_property_choice_json("Off", 0, draw_box.GetValue(requested_frame)));
467  root["draw_box"]["choices"].append(add_property_choice_json("On", 1, draw_box.GetValue(requested_frame)));
468 
469  root["stroke"] = add_property_json("Border", 0.0, "color", "", NULL, 0, 255, false, requested_frame);
470  root["stroke"]["red"] = add_property_json("Red", stroke.red.GetValue(requested_frame), "float", "", &stroke.red, 0, 255, false, requested_frame);
471  root["stroke"]["blue"] = add_property_json("Blue", stroke.blue.GetValue(requested_frame), "float", "", &stroke.blue, 0, 255, false, requested_frame);
472  root["stroke"]["green"] = add_property_json("Green", stroke.green.GetValue(requested_frame), "float", "", &stroke.green, 0, 255, false, requested_frame);
473  root["stroke_width"] = add_property_json("Stroke Width", stroke_width.GetValue(requested_frame), "int", "", &stroke_width, 1, 10, false, requested_frame);
474  root["stroke_alpha"] = add_property_json("Stroke alpha", stroke_alpha.GetValue(requested_frame), "float", "", &stroke_alpha, 0.0, 1.0, false, requested_frame);
475 
476  root["background_alpha"] = add_property_json("Background Alpha", background_alpha.GetValue(requested_frame), "float", "", &background_alpha, 0.0, 1.0, false, requested_frame);
477  root["background_corner"] = add_property_json("Background Corner Radius", background_corner.GetValue(requested_frame), "int", "", &background_corner, 0.0, 60.0, false, requested_frame);
478 
479  root["background"] = add_property_json("Background", 0.0, "color", "", NULL, 0, 255, false, requested_frame);
480  root["background"]["red"] = add_property_json("Red", background.red.GetValue(requested_frame), "float", "", &background.red, 0, 255, false, requested_frame);
481  root["background"]["blue"] = add_property_json("Blue", background.blue.GetValue(requested_frame), "float", "", &background.blue, 0, 255, false, requested_frame);
482  root["background"]["green"] = add_property_json("Green", background.green.GetValue(requested_frame), "float", "", &background.green, 0, 255, false, requested_frame);
483 
484  // Return formatted string
485  return root;
486 }
487 
488 
489 // Generate JSON for a property
490 Json::Value TrackedObjectBBox::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 {
491 
492  // Requested Point
493  const Point requested_point(requested_frame, requested_frame);
494 
495  // Create JSON Object
496  Json::Value prop = Json::Value(Json::objectValue);
497  prop["name"] = name;
498  prop["value"] = value;
499  prop["memo"] = memo;
500  prop["type"] = type;
501  prop["min"] = min_value;
502  prop["max"] = max_value;
503  if (keyframe) {
504  prop["keyframe"] = keyframe->Contains(requested_point);
505  prop["points"] = int(keyframe->GetCount());
506  Point closest_point = keyframe->GetClosestPoint(requested_point);
507  prop["interpolation"] = closest_point.interpolation;
508  prop["closest_point_x"] = closest_point.co.X;
509  prop["previous_point_x"] = keyframe->GetPreviousPoint(closest_point).co.X;
510  }
511  else {
512  prop["keyframe"] = false;
513  prop["points"] = 0;
514  prop["interpolation"] = CONSTANT;
515  prop["closest_point_x"] = -1;
516  prop["previous_point_x"] = -1;
517  }
518 
519  prop["readonly"] = readonly;
520  prop["choices"] = Json::Value(Json::arrayValue);
521 
522  // return JsonValue
523  return prop;
524 }
525 
526 // Return a map that contains the bounding box properties and it's keyframes indexed by their names
527 std::map<std::string, float> TrackedObjectBBox::GetBoxValues(int64_t frame_number) const {
528 
529  // Create the map
530  std::map<std::string, float> boxValues;
531 
532  // Get bounding box of the current frame
533  BBox box = GetBox(frame_number);
534 
535  // Save the bounding box properties
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;
541 
542  // Save the keyframes values
543  boxValues["sx"] = this->scale_x.GetValue(frame_number);
544  boxValues["sy"] = this->scale_y.GetValue(frame_number);
545  boxValues["dx"] = this->delta_x.GetValue(frame_number);
546  boxValues["dy"] = this->delta_y.GetValue(frame_number);
547  boxValues["r"] = this->rotation.GetValue(frame_number);
548 
549 
550  return boxValues;
551 }
552 
553 // Return a map that contains the properties of this object's parent clip
554 std::map<std::string, float> TrackedObjectBBox::GetParentClipProperties(int64_t frame_number) const {
555 
556  // Get the parent clip of this object as a Clip pointer
557  Clip* parentClip = (Clip *) ParentClip();
558 
559  // Calculate parentClip's frame number
560  long parentClip_start_position = round( parentClip->Position() * parentClip->info.fps.ToDouble() ) + 1;
561  long parentClip_start_frame = ( parentClip->Start() * parentClip->info.fps.ToDouble() ) + 1;
562  float parentClip_frame_number = round(frame_number - parentClip_start_position) + parentClip_start_frame;
563 
564  // Get parentClip's Keyframes
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);
570 
571  // Initialize the parent clip properties map
572  std::map<std::string, float> parentClipProperties;
573 
574  // Set the map properties
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;
582 
583  return parentClipProperties;
584 }
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: Color.cpp:138
int num
Numerator for the fraction.
Definition: Fraction.h:50
bool ExactlyContains(int64_t frame_number) const override
Check if there is a bounding-box in the exact frame number.
Json::Value PropertiesJSON(int64_t requested_frame) const override
Json::Value JsonValue() const override
Generate Json::Value for this object.
std::string Id() const
Get the Id of this clip object.
Definition: ClipBase.h:107
void clear()
Clear the BoxVec map.
float Start() const
Get start position (in seconds) of clip (trim start of video)
Definition: ClipBase.h:110
float cy
y-coordinate of the bounding box center
ClipBase * ParentClip() const
Get and set the parentClip of this object.
Keyframe background_alpha
Background box opacity.
InterpolationType interpolation
This is the interpolation mode.
Definition: Point.h:87
openshot::Keyframe location_y
Curve representing the relative Y position in percent based on the gravity (-1 to 1) ...
Definition: Clip.h:308
float height
bounding box height
Keyframe stroke_alpha
Stroke box opacity.
Json::Value add_property_choice_json(std::string name, int value, int selected_value) const
Generate JSON choice for a property (dropdown properties)
void SetBaseFPS(Fraction fps)
Update object&#39;s BaseFps.
double ToDouble() const
Return this fraction as a double (i.e. 1/2 = 0.5)
Definition: Fraction.cpp:59
Keyframe delta_y
Y-direction displacement Keyframe.
A Point is the basic building block of a key-frame curve.
Definition: Point.h:82
std::map< std::string, float > GetParentClipProperties(int64_t frame_number) const override
Return a map that contains the properties of this object&#39;s parent clip.
openshot::Keyframe scale_x
Curve representing the horizontal scaling in percent (0 to 1)
Definition: Clip.h:305
Point GetPreviousPoint(Point p) const
Get previous point (.
Definition: KeyFrame.cpp:236
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:34
openshot::Keyframe scale_y
Curve representing the vertical scaling in percent (0 to 1)
Definition: Clip.h:306
bool Contains(Point p) const
Does this keyframe contain a specific point.
Definition: KeyFrame.cpp:194
float angle
bounding box rotation angle [degrees]
openshot::Keyframe blue
Curve representing the red value (0 - 255)
Definition: Color.h:50
Keyframe stroke_width
Thickness of border line.
Color background
Background fill color.
std::string protobufDataPath
Path to the protobuf file that holds the bounding box points across the frames.
Color stroke
Border line color.
bool LoadBoxData(std::string inputFilePath)
Load the bounding-boxes information from the protobuf file.
BBox InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target)
Interpolate the bouding-boxes properties.
This class represents a clip (used to arrange readers on the timeline)
Definition: Clip.h:109
double Y
The Y value of the coordinate (usually representing the value of the property being animated) ...
Definition: Coordinate.h:57
Keyframe delta_x
X-direction displacement Keyframe.
openshot::Keyframe green
Curve representing the green value (0 - 255)
Definition: Color.h:49
Point GetClosestPoint(Point p) const
Get current point (or closest point to the right) from the X coordinate (i.e. the frame number) ...
Definition: KeyFrame.cpp:231
BBox GetBox(int64_t frame_number)
Return a bounding-box from BoxVec with it&#39;s properties adjusted by the Keyframes. ...
openshot::Keyframe rotation
Curve representing the rotation (0 to 360)
Definition: Clip.h:312
Header file for Clip class.
float width
bounding box width
This class represents a fraction.
Definition: Fraction.h:48
std::map< std::string, float > GetBoxValues(int64_t frame_number) const override
Return a map that contains the bounding box properties and it&#39;s keyframes indexed by their names...
Fraction GetBaseFPS()
Return the object&#39;s BaseFps.
double InterpolateBetween(Point const &left, Point const &right, double target, double allowed_error)
Interpolate two points using the right Point&#39;s interpolation method.
Definition: KeyFrame.cpp:96
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
double FrameNToTime(int64_t frame_number, double time_scale) const
Get the time of the given frame.
void RemoveBox(int64_t frame_number)
Remove a bounding-box from the BoxVec map.
Fraction Reciprocal() const
Return the reciprocal as a Fraction.
Definition: Fraction.cpp:94
std::map< double, BBox > BoxVec
Index the bounding-box by time of each frame.
double X
The X value of the coordinate (usually representing the frame #)
Definition: Coordinate.h:56
void SetJson(const std::string value) override
Load JSON string into this object.
This struct holds the information of a bounding-box.
Keyframe scale_y
Y-direction scale Keyframe.
TrackedObjectBBox()
Default Constructor.
void ScalePoints(double scale) override
Update the TimeScale member variable.
openshot::ReaderInfo info
Information about the current media file.
Definition: ReaderBase.h:111
Header file for the TrackedObjectBBox class.
int64_t GetLength() const
Get the size of BoxVec map.
std::string ChildClipId() const
Get and set the Id of the childClip of this object.
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: KeyFrame.cpp:368
Keyframe rotation
Rotation Keyframe.
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:46
Keyframe scale_x
X-direction scale Keyframe.
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
float cx
x-coordinate of the bounding box center
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: KeyFrame.cpp:335
Linear curves are angular, straight lines between two points.
Definition: Point.h:48
Coordinate co
This is the primary coordinate.
Definition: Point.h:84
Exception for invalid JSON.
Definition: Exceptions.h:205
std::string Id() const
Get the id of this object.
int64_t GetCount() const
Get the number of points (i.e. # of points)
Definition: KeyFrame.cpp:516
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:268
void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) override
Add a BBox to the BoxVec map.
openshot::Keyframe red
Curve representing the red value (0 - 255)
Definition: Color.h:48
bool Contains(int64_t frame_number) const
Check if there is a bounding-box in the given frame.
openshot::Keyframe location_x
Curve representing the relative X position in percent based on the gravity (-1 to 1) ...
Definition: Clip.h:307
float Position() const
Get position on timeline (in seconds)
Definition: ClipBase.h:108
std::string Json() const override
Get and Set JSON methods.
int den
Denominator for the fraction.
Definition: Fraction.h:51
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
Definition: KeyFrame.h:72
Keyframe background_corner
Radius of rounded corners.
This class contains the properties of a tracked object and functions to manipulate it...
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: ReaderBase.h:70
Constant curves jump from their previous position to a new one (with no interpolation).
Definition: Point.h:49
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: Color.cpp:107