22#include "trackerdata.pb.h"
24#include <google/protobuf/util/time_util.h>
32using google::protobuf::util::TimeUtil;
38 init_effect_details();
41 trackedData = std::make_shared<TrackedObjectBBox>(trackedDataObject);
55 init_effect_details();
58 trackedData = std::make_shared<TrackedObjectBBox>(trackedDataObject);
68void Tracker::init_effect_details()
76 info.
description =
"Track the selected bounding box through the video.";
81 this->TimeScale = 1.0;
89 cv::Mat frame_image = frame->GetImageCV();
94 std::shared_ptr<QImage> childClipImage =
nullptr;
97 if(!frame_image.empty() &&
102 float fw = frame_image.size().width;
103 float fh = frame_image.size().height;
109 if (
trackedData->draw_box.GetValue(frame_number) == 1)
111 std::vector<int> stroke_rgba =
trackedData->stroke.GetColorRGBA(frame_number);
112 int stroke_width =
trackedData->stroke_width.GetValue(frame_number);
113 float stroke_alpha =
trackedData->stroke_alpha.GetValue(frame_number);
114 std::vector<int> bg_rgba =
trackedData->background.GetColorRGBA(frame_number);
115 float bg_alpha =
trackedData->background_alpha.GetValue(frame_number);
118 cv::RotatedRect box ( cv::Point2f( (
int)(fd.
cx*fw), (
int)(fd.
cy*fh) ),
119 cv::Size2f( (
int)(fd.
width*fw), (
int)(fd.
height*fh) ),
123 DrawRectangleRGBA(frame_image, box, stroke_rgba, stroke_alpha, stroke_width,
false);
135 std::shared_ptr<Frame> childClipFrame = childClip->
GetFrame(frame_number);
136 childClipImage = childClipFrame->GetImage();
139 boxRect.setRect((
int)((fd.
cx-fd.
width/2)*fw),
151 frame->SetImageCV(frame_image);
156 QImage frameImage = *(frame->GetImage());
159 QPainter painter(&frameImage);
162 painter.drawImage(boxRect, *childClipImage);
165 frame->AddImage(std::make_shared<QImage>(frameImage));
171void Tracker::DrawRectangleRGBA(cv::Mat &frame_image, cv::RotatedRect box, std::vector<int> color,
float alpha,
int thickness,
bool is_background){
173 cv::Point2f vertices2f[4];
174 box.points(vertices2f);
182 cv::Mat overlayFrame;
183 frame_image.copyTo(overlayFrame);
186 cv::Point vertices[4];
187 for(
int i = 0; i < 4; ++i){
188 vertices[i] = vertices2f[i];}
190 cv::Rect rect = box.boundingRect();
191 cv::fillConvexPoly(overlayFrame, vertices, 4, cv::Scalar(color[2],color[1],color[0]), cv::LINE_AA);
193 cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image);
196 cv::Mat overlayFrame;
197 frame_image.copyTo(overlayFrame);
200 for (
int i = 0; i < 4; i++)
202 cv::line(overlayFrame, vertices2f[i], vertices2f[(i+1)%4], cv::Scalar(color[2],color[1],color[0]),
203 thickness, cv::LINE_AA);
207 cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image);
216 root[
"visible_objects_index"] = Json::Value(Json::arrayValue);
217 root[
"visible_objects_id"] = Json::Value(Json::arrayValue);
222 Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(frame_number);
223 if (trackedObjectJSON[
"visible"][
"value"].asBool()){
225 root[
"visible_objects_index"].append(trackedObject.first);
226 root[
"visible_objects_id"].append(trackedObject.second->Id());
230 return root.toStyledString();
249 root[
"BaseFPS"][
"num"] = BaseFPS.
num;
250 root[
"BaseFPS"][
"den"] = BaseFPS.
den;
251 root[
"TimeScale"] = this->TimeScale;
256 Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
258 objects[trackedObject.second->Id()] = trackedObjectJSON;
260 root[
"objects"] = objects;
276 catch (
const std::exception& e)
279 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
290 if (!root[
"BaseFPS"].isNull() && root[
"BaseFPS"].isObject())
292 if (!root[
"BaseFPS"][
"num"].isNull())
294 BaseFPS.
num = (int) root[
"BaseFPS"][
"num"].asInt();
296 if (!root[
"BaseFPS"][
"den"].isNull())
298 BaseFPS.
den = (int) root[
"BaseFPS"][
"den"].asInt();
302 if (!root[
"TimeScale"].isNull())
303 TimeScale = (
double) root[
"TimeScale"].asDouble();
316 if (!root[
"objects"].isNull()){
318 std::string obj_id = std::to_string(trackedObject.first);
319 if(!root[
"objects"][obj_id].isNull()){
320 trackedObject.second->SetJsonValue(root[
"objects"][obj_id]);
326 if (!root[
"objects_id"].isNull()){
328 Json::Value trackedObjectJSON;
329 trackedObjectJSON[
"box_id"] = root[
"objects_id"][trackedObject.first].asString();
330 trackedObject.second->SetJsonValue(trackedObjectJSON);
346 Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(requested_frame);
348 objects[trackedObject.second->Id()] = trackedObjectJSON;
350 root[
"objects"] = objects;
353 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
354 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
356 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
357 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
358 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"", NULL, 0, 1000 * 60 * 30,
true, requested_frame);
361 return root.toStyledString();
Header file for all Exception classes.
Header file for Timeline class.
Header file for Tracker effect class.
This abstract class is the base class, used by all clips in libopenshot.
float Start() const
Get start position (in seconds) of clip (trim start of video)
float Duration() const
Get the length of this clip (in seconds)
virtual float End() const
Get end position (in seconds) of clip (trim end of video)
std::string Id() const
Get the Id of this clip object.
int Layer() const
Get layer of clip on timeline (lower number is covered by higher numbers)
float Position() const
Get position on timeline (in seconds)
virtual openshot::TimelineBase * ParentTimeline()
Get the associated Timeline pointer (if any)
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
Generate JSON for a property.
This class represents a clip (used to arrange readers on the timeline)
std::shared_ptr< openshot::Frame > GetFrame(int64_t clip_frame_number) override
Get an openshot::Frame object for a specific frame number of this clip. The image size and number of ...
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)
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.
This class represents a timeline.
openshot::Clip * GetClip(const std::string &id)
Look up a single clip by ID.
This class contains the properties of a tracked object and functions to manipulate it.
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.
void DrawRectangleRGBA(cv::Mat &frame_image, cv::RotatedRect box, std::vector< int > color, float alpha, int thickness, bool is_background)
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
float angle
bounding box rotation angle [degrees]
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.