Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Tracker & Object Detector Effects (Faster Drawing, Corner Radius, New Style) #950

Merged
merged 15 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
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()) {

Check warning on line 389 in src/KeyFrame.cpp

View check run for this annotation

Codecov / codecov/patch

src/KeyFrame.cpp#L389

Added line #L389 was not covered by tests
// Create Point from Numeric value
Point p(root.asFloat());

Check warning on line 391 in src/KeyFrame.cpp

View check run for this annotation

Codecov / codecov/patch

src/KeyFrame.cpp#L391

Added line #L391 was not covered by tests

// Add Point to Keyframe
AddPoint(p);

Check warning on line 394 in src/KeyFrame.cpp

View check run for this annotation

Codecov / codecov/patch

src/KeyFrame.cpp#L394

Added line #L394 was not covered by tests
}
}

// 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 @@

// 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 @@
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 @@
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 @@
// 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);

Check warning on line 426 in src/TrackedObjectBBox.cpp

View check run for this annotation

Codecov / codecov/patch

src/TrackedObjectBBox.cpp#L423-L426

Added lines #L423 - L426 were not covered by tests

// 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);

Check warning on line 434 in src/TrackedObjectBBox.cpp

View check run for this annotation

Codecov / codecov/patch

src/TrackedObjectBBox.cpp#L434

Added line #L434 was not covered by tests

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)));

Check warning on line 438 in src/TrackedObjectBBox.cpp

View check run for this annotation

Codecov / codecov/patch

src/TrackedObjectBBox.cpp#L436-L438

Added lines #L436 - L438 were not covered by tests

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 @@
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);

Check warning on line 448 in src/TrackedObjectBBox.cpp

View check run for this annotation

Codecov / codecov/patch

src/TrackedObjectBBox.cpp#L448

Added line #L448 was not covered by tests

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 @@

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
Loading