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