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();
169 root[
"type"] =
info.class_name;
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).
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.