22#include "trackerdata.pb.h"
24#include <google/protobuf/util/time_util.h>
32using google::protobuf::util::TimeUtil;
35Tracker::Tracker(std::string clipTrackerDataPath)
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> f(
new Frame(1, frame->GetWidth(), frame->GetHeight(),
"#00000000"));
136 std::shared_ptr<Frame> childClipFrame = childClip->
GetFrame(f, frame_number);
137 childClipImage = childClipFrame->GetImage();
140 boxRect.setRect((
int)((fd.
cx-fd.
width/2)*fw),
152 frame->SetImageCV(frame_image);
157 QImage frameImage = *(frame->GetImage());
160 QPainter painter(&frameImage);
163 painter.drawImage(boxRect, *childClipImage, QRectF(0, 0, frameImage.size().width(), frameImage.size().height()));
166 frame->AddImage(std::make_shared<QImage>(frameImage));
172void Tracker::DrawRectangleRGBA(cv::Mat &frame_image, cv::RotatedRect box, std::vector<int> color,
float alpha,
int thickness,
bool is_background){
174 cv::Point2f vertices2f[4];
175 box.points(vertices2f);
183 cv::Mat overlayFrame;
184 frame_image.copyTo(overlayFrame);
187 cv::Point vertices[4];
188 for(
int i = 0; i < 4; ++i){
189 vertices[i] = vertices2f[i];}
191 cv::Rect rect = box.boundingRect();
192 cv::fillConvexPoly(overlayFrame, vertices, 4, cv::Scalar(color[2],color[1],color[0]), cv::LINE_AA);
194 cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image);
197 cv::Mat overlayFrame;
198 frame_image.copyTo(overlayFrame);
201 for (
int i = 0; i < 4; i++)
203 cv::line(overlayFrame, vertices2f[i], vertices2f[(i+1)%4], cv::Scalar(color[2],color[1],color[0]),
204 thickness, cv::LINE_AA);
208 cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image);
217 root[
"visible_objects_index"] = Json::Value(Json::arrayValue);
218 root[
"visible_objects_id"] = Json::Value(Json::arrayValue);
223 Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(frame_number);
224 if (trackedObjectJSON[
"visible"][
"value"].asBool()){
226 root[
"visible_objects_index"].append(trackedObject.first);
227 root[
"visible_objects_id"].append(trackedObject.second->Id());
231 return root.toStyledString();
250 root[
"BaseFPS"][
"num"] = BaseFPS.
num;
251 root[
"BaseFPS"][
"den"] = BaseFPS.
den;
252 root[
"TimeScale"] = this->TimeScale;
257 Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
259 objects[trackedObject.second->Id()] = trackedObjectJSON;
261 root[
"objects"] = objects;
277 catch (
const std::exception& e)
280 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
291 if (!root[
"BaseFPS"].isNull() && root[
"BaseFPS"].isObject())
293 if (!root[
"BaseFPS"][
"num"].isNull())
295 BaseFPS.
num = (int) root[
"BaseFPS"][
"num"].asInt();
297 if (!root[
"BaseFPS"][
"den"].isNull())
299 BaseFPS.
den = (int) root[
"BaseFPS"][
"den"].asInt();
303 if (!root[
"TimeScale"].isNull())
304 TimeScale = (
double) root[
"TimeScale"].asDouble();
317 if (!root[
"objects"].isNull()){
319 std::string obj_id = std::to_string(trackedObject.first);
320 if(!root[
"objects"][obj_id].isNull()){
321 trackedObject.second->SetJsonValue(root[
"objects"][obj_id]);
327 if (!root[
"objects_id"].isNull()){
329 Json::Value trackedObjectJSON;
330 trackedObjectJSON[
"box_id"] = root[
"objects_id"][trackedObject.first].asString();
331 trackedObject.second->SetJsonValue(trackedObjectJSON);
347 Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(requested_frame);
349 objects[trackedObject.second->Id()] = trackedObjectJSON;
351 root[
"objects"] = objects;
354 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
355 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
357 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
358 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
359 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"", NULL, 0, 1000 * 60 * 30,
true, requested_frame);
362 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.
This class represents a single frame of video (i.e. image & audio data)
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.