22#include "trackerdata.pb.h"
24#include <google/protobuf/util/time_util.h>
34using google::protobuf::util::TimeUtil;
41 init_effect_details();
44 trackedData = std::make_shared<TrackedObjectBBox>();
57void Tracker::init_effect_details()
65 info.
description =
"Track the selected bounding box through the video.";
70 this->TimeScale = 1.0;
78 if (!frame)
return frame;
79 auto frame_image = frame->GetImage();
80 if (!frame_image || frame_image->isNull())
return frame;
88 QPainter painter(frame_image.get());
89 painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
94 (fd.
cx - fd.
width/2) * frame_image->width(),
95 (fd.
cy - fd.
height/2) * frame_image->height(),
96 fd.
width * frame_image->width(),
97 fd.
height * frame_image->height()
100 if (
trackedData->draw_box.GetValue(frame_number) == 1)
102 auto stroke_rgba =
trackedData->stroke.GetColorRGBA(frame_number);
103 int stroke_width =
trackedData->stroke_width.GetValue(frame_number);
104 float stroke_alpha =
trackedData->stroke_alpha.GetValue(frame_number);
105 auto bg_rgba =
trackedData->background.GetColorRGBA(frame_number);
106 float bg_alpha =
trackedData->background_alpha.GetValue(frame_number);
107 float bg_corner =
trackedData->background_corner.GetValue(frame_number);
110 stroke_rgba[0], stroke_rgba[1], stroke_rgba[2],
111 int(255 * stroke_alpha)
113 pen.setWidth(stroke_width);
117 bg_rgba[0], bg_rgba[1], bg_rgba[2],
120 painter.setBrush(brush);
122 painter.drawRoundedRect(boxRect, bg_corner, bg_corner);
133 root[
"visible_objects_index"] = Json::Value(Json::arrayValue);
134 root[
"visible_objects_id"] = Json::Value(Json::arrayValue);
137 return root.toStyledString();
140 auto ptr = kv.second;
144 Json::Value propsJson = ptr->PropertiesJSON(frame_number);
146 if (propsJson[
"visible"][
"value"].asBool()) {
147 root[
"visible_objects_index"].append(kv.first);
148 root[
"visible_objects_id"].append(ptr->Id());
152 return root.toStyledString();
171 root[
"BaseFPS"][
"num"] = BaseFPS.
num;
172 root[
"BaseFPS"][
"den"] = BaseFPS.
den;
173 root[
"TimeScale"] = this->TimeScale;
178 Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
180 objects[trackedObject.second->Id()] = trackedObjectJSON;
182 root[
"objects"] = objects;
198 catch (
const std::exception& e)
201 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
212 if (!root[
"BaseFPS"].isNull()) {
213 if (!root[
"BaseFPS"][
"num"].isNull())
214 BaseFPS.
num = root[
"BaseFPS"][
"num"].asInt();
215 if (!root[
"BaseFPS"][
"den"].isNull())
216 BaseFPS.
den = root[
"BaseFPS"][
"den"].asInt();
219 if (!root[
"TimeScale"].isNull()) {
220 TimeScale = root[
"TimeScale"].asDouble();
223 if (!root[
"protobuf_data_path"].isNull()) {
224 std::string new_path = root[
"protobuf_data_path"].asString();
235 auto ptr = kv.second;
237 std::string prefix = this->
Id();
240 ptr->Id(prefix + std::to_string(idx));
248 if (!root[
"objects"].isNull()) {
250 const auto memberNames = root[
"objects"].getMemberNames();
251 for (
const auto& name : memberNames)
255 bool numeric_key = std::all_of(name.begin(), name.end(), ::isdigit);
257 index = std::stoi(name);
261 size_t pos = name.find_last_of(
'-');
262 if (pos != std::string::npos) {
264 index = std::stoi(name.substr(pos + 1));
275 obj_it->second->Id(name);
276 obj_it->second->SetJsonValue(root[
"objects"][name]);
282 if (!root[
"objects_id"].isNull()) {
284 if (!root[
"objects_id"][kv.first].isNull())
285 kv.second->Id(root[
"objects_id"][kv.first].asString());
299 Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(requested_frame);
301 objects[trackedObject.second->Id()] = trackedObjectJSON;
303 root[
"objects"] = objects;
306 return root.toStyledString();
Header file for all Exception classes.
Header file for Timeline class.
Header file for Tracker effect class.
std::string Id() const
Get the Id of this clip object.
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
openshot::ClipBase * ParentClip()
Parent clip object of this effect (which can be unparented and NULL)
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
EffectInfoStruct info
Information about the current effect.
std::map< int, std::shared_ptr< openshot::TrackedObjectBase > > trackedObjects
Map of Tracked Object's by their indices (used by Effects that track objects on clips)
int num
Numerator for the fraction.
int den
Denominator for the fraction.
Exception for invalid JSON.
std::string Json() const override
Generate JSON string of this object.
std::string GetVisibleObjects(int64_t frame_number) const override
Get the indexes and IDs of all visible objects in the given frame.
Json::Value JsonValue() const override
Generate Json::Value for this object.
void SetJson(const std::string value) override
Load JSON string into this object.
std::shared_ptr< Frame > GetFrame(std::shared_ptr< Frame > frame, int64_t frame_number) override
Apply this effect to an openshot::Frame.
std::string PropertiesJSON(int64_t requested_frame) const override
std::shared_ptr< TrackedObjectBBox > trackedData
Pointer to an object that holds the bounding-box data and it's Keyframes.
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Tracker()
Default constructor.
std::string protobuf_data_path
Path to the protobuf file that holds the bounding-box data.
This namespace is the default namespace for all code in the openshot library.
const Json::Value stringToJson(const std::string value)
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
bool has_video
Determines if this effect manipulates the image of a frame.
bool has_audio
Determines if this effect manipulates the audio of a frame.
std::string class_name
The class name of the effect.
std::string name
The name of the effect.
std::string description
The description of this effect and what it does.
bool has_tracked_object
Determines if this effect track objects through the clip.