Skip to content

Commit

Permalink
Merge pull request #950 from OpenShot/invalid-tracker-region
Browse files Browse the repository at this point in the history
Improved Tracker & Object Detector Effects (Faster Drawing, Corner Radius, New Style)
  • Loading branch information
jonoomph authored Mar 26, 2024
2 parents 284904d + 5a0a6a6 commit a9e34a9
Show file tree
Hide file tree
Showing 12 changed files with 398 additions and 679 deletions.
367 changes: 143 additions & 224 deletions src/Clip.cpp

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions src/Clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ namespace openshot {
void apply_background(std::shared_ptr<openshot::Frame> frame, std::shared_ptr<openshot::Frame> background_frame);

/// Apply effects to the source frame (if any)
void apply_effects(std::shared_ptr<openshot::Frame> frame, std::shared_ptr<openshot::Frame> background_frame, TimelineInfoStruct* options, bool before_keyframes);
void apply_effects(std::shared_ptr<openshot::Frame> frame, int64_t timeline_frame_number, TimelineInfoStruct* options, bool before_keyframes);

/// Apply keyframes to an openshot::Frame and use an existing background frame (if any)
void apply_keyframes(std::shared_ptr<Frame> frame, std::shared_ptr<Frame> background_frame);
void apply_keyframes(std::shared_ptr<Frame> frame, QSize timeline_size);

/// Apply waveform image to an openshot::Frame and use an existing background frame (if any)
void apply_waveform(std::shared_ptr<Frame> frame, std::shared_ptr<Frame> background_frame);
void apply_waveform(std::shared_ptr<Frame> frame, QSize timeline_size);

/// Adjust frame number for Clip position and start (which can result in a different number)
int64_t adjust_timeline_framenumber(int64_t clip_frame_number);
Expand All @@ -154,15 +154,14 @@ namespace openshot {
/// Adjust the audio and image of a time mapped frame
void apply_timemapping(std::shared_ptr<openshot::Frame> frame);

/// Compare 2 floating point numbers
bool isEqual(double a, double b);
/// Compare 2 floating point numbers and return true if they are extremely close
bool isNear(double a, double b);

/// Sort effects by order
void sort_effects();

/// Reverse an audio buffer
void reverse_buffer(juce::AudioBuffer<float>* buffer);

/// Scale a source size to a target size (given a specific scale-type)
QSize scale_size(QSize source_size, ScaleType source_scale, int target_width, int target_height);

public:
openshot::GravityType gravity; ///< The gravity of a clip determines where it snaps to its parent
Expand Down Expand Up @@ -224,6 +223,12 @@ namespace openshot {
/// Close the internal reader
void Close() override;

/// Return the associated ParentClip (if any)
openshot::Clip* GetParentClip();

/// Return the associated Parent Tracked Object (if any)
std::shared_ptr<openshot::TrackedObjectBase> GetParentTrackedObject();

/// Return the list of effects on the timeline
std::list<openshot::EffectBase*> Effects() { return effects; };

Expand Down
31 changes: 19 additions & 12 deletions src/KeyFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,18 +374,25 @@ void Keyframe::SetJsonValue(const Json::Value root) {
Points.clear();
Points.shrink_to_fit();

if (!root["Points"].isNull())
// loop through points
for (const auto existing_point : root["Points"]) {
// Create Point
Point p;

// Load Json into Point
p.SetJsonValue(existing_point);

// Add Point to Keyframe
AddPoint(p);
}
if (root.isObject() && !root["Points"].isNull()) {
// loop through points in JSON Object
for (const auto existing_point : root["Points"]) {
// Create Point
Point p;

// Load Json into Point
p.SetJsonValue(existing_point);

// Add Point to Keyframe
AddPoint(p);
}
} else if (root.isNumeric()) {
// Create Point from Numeric value
Point p(root.asFloat());

// Add Point to Keyframe
AddPoint(p);
}
}

// Get the change in Y value (from the previous Y value)
Expand Down
69 changes: 13 additions & 56 deletions src/TrackedObjectBBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,19 @@ using namespace openshot;

// Default Constructor, delegating
TrackedObjectBBox::TrackedObjectBBox()
: TrackedObjectBBox::TrackedObjectBBox(0, 0, 255, 0) {}
: TrackedObjectBBox::TrackedObjectBBox(0, 0, 255, 255) {}

// Constructor that takes RGBA values for stroke, and sets the bounding-box
// displacement as 0 and the scales as 1 for the first frame
TrackedObjectBBox::TrackedObjectBBox(int Red, int Green, int Blue, int Alfa)
: delta_x(0.0), delta_y(0.0),
scale_x(1.0), scale_y(1.0), rotation(0.0),
background_alpha(1.0), background_corner(0),
stroke_width(2) , stroke_alpha(0.0),
background_alpha(0.0), background_corner(12),
stroke_width(2) , stroke_alpha(0.7),
stroke(Red, Green, Blue, Alfa),
background(0, 0, 255, 0)
background(0, 0, 255, Alfa)
{
this->TimeScale = 1.0;
return;
}

// Add a BBox to the BoxVec map
Expand Down Expand Up @@ -315,7 +314,6 @@ Json::Value TrackedObjectBBox::JsonValue() const
root["BaseFPS"]["num"] = BaseFps.num;
root["BaseFPS"]["den"] = BaseFps.den;
root["TimeScale"] = TimeScale;
root["child_clip_id"] = ChildClipId();

// Keyframe's properties
root["delta_x"] = delta_x.JsonValue();
Expand Down Expand Up @@ -380,11 +378,6 @@ void TrackedObjectBBox::SetJsonValue(const Json::Value root)
if (!root["protobuf_data_path"].isNull())
protobufDataPath = root["protobuf_data_path"].asString();

// Set the id of the child clip
if (!root["child_clip_id"].isNull() && root["child_clip_id"].asString() != Id()){
ChildClipId(root["child_clip_id"].asString());
}

// Set the Keyframes by the given JSON object
if (!root["delta_x"].isNull())
delta_x.SetJsonValue(root["delta_x"]);
Expand Down Expand Up @@ -426,26 +419,23 @@ Json::Value TrackedObjectBBox::PropertiesJSON(int64_t requested_frame) const
// Add the ID of this object to the JSON object
root["box_id"] = add_property_json("Box ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame);

// Add the ID of this object's child clip to the JSON object
root["child_clip_id"] = add_property_json("Child Clip ID", 0.0, "string", ChildClipId(), NULL, -1, -1, false, requested_frame);

// Add the data of given frame bounding-box to the JSON object
root["x1"] = add_property_json("X1", box.cx-(box.width/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
root["y1"] = add_property_json("Y1", box.cy-(box.height/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
root["x2"] = add_property_json("X2", box.cx+(box.width/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
root["y2"] = add_property_json("Y2", box.cy+(box.height/2), "float", "", NULL, 0.0, 1.0, false, requested_frame);
root["x1"] = add_property_json("X1", box.cx-(box.width/2), "float", "", NULL, 0.0, 1.0, true, requested_frame);
root["y1"] = add_property_json("Y1", box.cy-(box.height/2), "float", "", NULL, 0.0, 1.0, true, requested_frame);
root["x2"] = add_property_json("X2", box.cx+(box.width/2), "float", "", NULL, 0.0, 1.0, true, requested_frame);
root["y2"] = add_property_json("Y2", box.cy+(box.height/2), "float", "", NULL, 0.0, 1.0, true, requested_frame);

// Add the bounding-box Keyframes to the JSON object
root["delta_x"] = add_property_json("Displacement X-axis", delta_x.GetValue(requested_frame), "float", "", &delta_x, -1.0, 1.0, false, requested_frame);
root["delta_y"] = add_property_json("Displacement Y-axis", delta_y.GetValue(requested_frame), "float", "", &delta_y, -1.0, 1.0, false, requested_frame);
root["scale_x"] = add_property_json("Scale (Width)", scale_x.GetValue(requested_frame), "float", "", &scale_x, 0.0, 1.0, false, requested_frame);
root["scale_y"] = add_property_json("Scale (Height)", scale_y.GetValue(requested_frame), "float", "", &scale_y, 0.0, 1.0, false, requested_frame);
root["rotation"] = add_property_json("Rotation", rotation.GetValue(requested_frame), "float", "", &rotation, 0, 360, false, requested_frame);
root["visible"] = add_property_json("Visible", visible.GetValue(requested_frame), "int", "", &visible, 0, 1, false, requested_frame);
root["visible"] = add_property_json("Visible", visible.GetValue(requested_frame), "int", "", &visible, 0, 1, true, requested_frame);

root["draw_box"] = add_property_json("Draw Box", draw_box.GetValue(requested_frame), "int", "", &draw_box, -1, 1.0, false, requested_frame);
root["draw_box"]["choices"].append(add_property_choice_json("Off", 0, draw_box.GetValue(requested_frame)));
root["draw_box"]["choices"].append(add_property_choice_json("On", 1, draw_box.GetValue(requested_frame)));
root["draw_box"] = add_property_json("Draw Box", draw_box.GetValue(requested_frame), "int", "", &draw_box, 0, 1, false, requested_frame);
root["draw_box"]["choices"].append(add_property_choice_json("Yes", true, draw_box.GetValue(requested_frame)));
root["draw_box"]["choices"].append(add_property_choice_json("No", false, draw_box.GetValue(requested_frame)));

root["stroke"] = add_property_json("Border", 0.0, "color", "", NULL, 0, 255, false, requested_frame);
root["stroke"]["red"] = add_property_json("Red", stroke.red.GetValue(requested_frame), "float", "", &stroke.red, 0, 255, false, requested_frame);
Expand All @@ -455,7 +445,7 @@ Json::Value TrackedObjectBBox::PropertiesJSON(int64_t requested_frame) const
root["stroke_alpha"] = add_property_json("Stroke alpha", stroke_alpha.GetValue(requested_frame), "float", "", &stroke_alpha, 0.0, 1.0, false, requested_frame);

root["background_alpha"] = add_property_json("Background Alpha", background_alpha.GetValue(requested_frame), "float", "", &background_alpha, 0.0, 1.0, false, requested_frame);
root["background_corner"] = add_property_json("Background Corner Radius", background_corner.GetValue(requested_frame), "int", "", &background_corner, 0.0, 60.0, false, requested_frame);
root["background_corner"] = add_property_json("Background Corner Radius", background_corner.GetValue(requested_frame), "int", "", &background_corner, 0.0, 150.0, false, requested_frame);

root["background"] = add_property_json("Background", 0.0, "color", "", NULL, 0, 255, false, requested_frame);
root["background"]["red"] = add_property_json("Red", background.red.GetValue(requested_frame), "float", "", &background.red, 0, 255, false, requested_frame);
Expand Down Expand Up @@ -530,36 +520,3 @@ std::map<std::string, float> TrackedObjectBBox::GetBoxValues(int64_t frame_numbe

return boxValues;
}

// Return a map that contains the properties of this object's parent clip
std::map<std::string, float> TrackedObjectBBox::GetParentClipProperties(int64_t frame_number) const {

// Get the parent clip of this object as a Clip pointer
Clip* parentClip = (Clip *) ParentClip();

// Calculate parentClip's frame number
long parentClip_start_position = round( parentClip->Position() * parentClip->info.fps.ToDouble() ) + 1;
long parentClip_start_frame = ( parentClip->Start() * parentClip->info.fps.ToDouble() ) + 1;
float parentClip_frame_number = round(frame_number - parentClip_start_position) + parentClip_start_frame;

// Get parentClip's Keyframes
float parentClip_location_x = parentClip->location_x.GetValue(parentClip_frame_number);
float parentClip_location_y = parentClip->location_y.GetValue(parentClip_frame_number);
float parentClip_scale_x = parentClip->scale_x.GetValue(parentClip_frame_number);
float parentClip_scale_y = parentClip->scale_y.GetValue(parentClip_frame_number);
float parentClip_rotation = parentClip->rotation.GetValue(parentClip_frame_number);

// Initialize the parent clip properties map
std::map<std::string, float> parentClipProperties;

// Set the map properties
parentClipProperties["frame_number"] = parentClip_frame_number;
parentClipProperties["timeline_frame_number"] = frame_number;
parentClipProperties["location_x"] = parentClip_location_x;
parentClipProperties["location_y"] = parentClip_location_y;
parentClipProperties["scale_x"] = parentClip_scale_x;
parentClipProperties["scale_y"] = parentClip_scale_y;
parentClipProperties["rotation"] = parentClip_rotation;

return parentClipProperties;
}
3 changes: 0 additions & 3 deletions src/TrackedObjectBBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,6 @@ namespace openshot

/// Return a map that contains the bounding box properties and it's keyframes indexed by their names
std::map<std::string, float> GetBoxValues(int64_t frame_number) const override;
/// Return a map that contains the properties of this object's parent clip
std::map<std::string, float> GetParentClipProperties(int64_t frame_number) const override;

};
} // namespace openshot

Expand Down
2 changes: 1 addition & 1 deletion src/TrackedObjectBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace openshot

// Constructor
TrackedObjectBase::TrackedObjectBase(std::string _id)
: visible(1.0), draw_box(1), id(_id), childClipId("") {}
: visible(1.0), draw_box(1), id(_id) {}

Json::Value TrackedObjectBase::add_property_choice_json(
std::string name, int value, int selected_value) const
Expand Down
10 changes: 3 additions & 7 deletions src/TrackedObjectBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ namespace openshot {
class TrackedObjectBase {
protected:
std::string id;
std::string childClipId;

ClipBase* parentClip;

public:

/// Keyframe to track if a box is visible in the current frame (read-only)
Keyframe visible;

/// Keyframe to determine if a specific box is drawn (or hidden)
Keyframe draw_box;

/// Default constructor
Expand All @@ -60,9 +61,6 @@ namespace openshot {
/// Get and set the parentClip of this object
ClipBase* ParentClip() const { return parentClip; }
void ParentClip(ClipBase* clip) { parentClip = clip; }
/// Get and set the Id of the childClip of this object
std::string ChildClipId() const { return childClipId; };
void ChildClipId(std::string _childClipId) { childClipId = _childClipId; };

/// Check if there is data for the exact frame number
virtual bool ExactlyContains(int64_t frame_number) const { return {}; };
Expand All @@ -71,8 +69,6 @@ namespace openshot {
virtual void ScalePoints(double scale) { return; };
/// Return the main properties of a TrackedObjectBBox instance - such as position, size and rotation
virtual std::map<std::string, float> GetBoxValues(int64_t frame_number) const { std::map<std::string, float> ret; return ret; };
/// Return the main properties of the tracked object's parent clip - such as position, size and rotation
virtual std::map<std::string, float> GetParentClipProperties(int64_t frame_number) const { std::map<std::string, float> ret; return ret; }
/// Add a bounding box to the tracked object's BoxVec map
virtual void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) { return; };

Expand Down
Loading

0 comments on commit a9e34a9

Please sign in to comment.