Fixing parentClipObject and parentTrackedObject transform, so the parent clip can be scaled and moved without breaking the tracking. Also refactoring out unneeded complex code left over.

This commit is contained in:
Jonathan Thomas
2024-03-01 16:47:52 -06:00
parent 3351b52e77
commit 620e894409
7 changed files with 39 additions and 157 deletions

View File

@@ -789,38 +789,8 @@ std::string Clip::PropertiesJSON(int64_t requested_frame) const {
root["waveform"]["choices"].append(add_property_choice_json("Yes", true, waveform));
root["waveform"]["choices"].append(add_property_choice_json("No", false, waveform));
// Add the parentTrackedObject's properties
if (parentTrackedObject && parentClipObject)
{
// Convert Clip's frame position to Timeline's frame position
long clip_start_position = round(Position() * info.fps.ToDouble()) + 1;
long clip_start_frame = (Start() * info.fps.ToDouble()) + 1;
double timeline_frame_number = requested_frame + clip_start_position - clip_start_frame;
// Get attached object's parent clip properties
std::map< std::string, float > trackedObjectParentClipProperties = parentTrackedObject->GetParentClipProperties(timeline_frame_number);
double parentObject_frame_number = trackedObjectParentClipProperties["frame_number"];
// Get attached object properties
std::map< std::string, float > trackedObjectProperties = parentTrackedObject->GetBoxValues(parentObject_frame_number);
// Correct the parent Tracked Object properties by the clip's reference system
float parentObject_location_x = trackedObjectProperties["cx"] - 0.5 + trackedObjectParentClipProperties["cx"];
float parentObject_location_y = trackedObjectProperties["cy"] - 0.5 + trackedObjectParentClipProperties["cy"];
float parentObject_scale_x = trackedObjectProperties["w"]*trackedObjectProperties["sx"];
float parentObject_scale_y = trackedObjectProperties["h"]*trackedObjectProperties["sy"];
float parentObject_rotation = trackedObjectProperties["r"] + trackedObjectParentClipProperties["r"];
// Add the parent Tracked Object properties to JSON
root["location_x"] = add_property_json("Location X", parentObject_location_x, "float", "", &location_x, -1.0, 1.0, false, requested_frame);
root["location_y"] = add_property_json("Location Y", parentObject_location_y, "float", "", &location_y, -1.0, 1.0, false, requested_frame);
root["scale_x"] = add_property_json("Scale X", parentObject_scale_x, "float", "", &scale_x, 0.0, 1.0, false, requested_frame);
root["scale_y"] = add_property_json("Scale Y", parentObject_scale_y, "float", "", &scale_y, 0.0, 1.0, false, requested_frame);
root["rotation"] = add_property_json("Rotation", parentObject_rotation, "float", "", &rotation, -360, 360, false, requested_frame);
root["shear_x"] = add_property_json("Shear X", shear_x.GetValue(requested_frame), "float", "", &shear_x, -1.0, 1.0, false, requested_frame);
root["shear_y"] = add_property_json("Shear Y", shear_y.GetValue(requested_frame), "float", "", &shear_y, -1.0, 1.0, false, requested_frame);
}
// Add the parentClipObject's properties
else if (parentClipObject)
if (parentClipObject)
{
// Convert Clip's frame position to Timeline's frame position
long clip_start_position = round(Position() * info.fps.ToDouble()) + 1;
@@ -1345,7 +1315,7 @@ void Clip::apply_waveform(std::shared_ptr<Frame> frame, QSize timeline_size) {
frame->AddImage(source_image);
}
// Apply keyframes to the source frame (if any)
// Get QTransform from keyframes
QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int height)
{
// Get image from clip
@@ -1440,62 +1410,41 @@ QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int heig
// Get the parentClipObject properties
if (parentClipObject){
// Convert Clip's frame position to Timeline's frame position
long clip_start_position = round(Position() * info.fps.ToDouble()) + 1;
long clip_start_frame = (Start() * info.fps.ToDouble()) + 1;
double timeline_frame_number = frame->number + clip_start_position - clip_start_frame;
// Get the start trim position of the parent clip
long parent_start_offset = parentClipObject->Start() * info.fps.ToDouble();
long parent_frame_number = frame->number + parent_start_offset;
// Get parent object's properties (Clip)
parentObject_location_x = parentClipObject->location_x.GetValue(timeline_frame_number);
parentObject_location_y = parentClipObject->location_y.GetValue(timeline_frame_number);
parentObject_scale_x = parentClipObject->scale_x.GetValue(timeline_frame_number);
parentObject_scale_y = parentClipObject->scale_y.GetValue(timeline_frame_number);
parentObject_shear_x = parentClipObject->shear_x.GetValue(timeline_frame_number);
parentObject_shear_y = parentClipObject->shear_y.GetValue(timeline_frame_number);
parentObject_rotation = parentClipObject->rotation.GetValue(timeline_frame_number);
parentObject_location_x = parentClipObject->location_x.GetValue(parent_frame_number);
parentObject_location_y = parentClipObject->location_y.GetValue(parent_frame_number);
parentObject_scale_x = parentClipObject->scale_x.GetValue(parent_frame_number);
parentObject_scale_y = parentClipObject->scale_y.GetValue(parent_frame_number);
parentObject_shear_x = parentClipObject->shear_x.GetValue(parent_frame_number);
parentObject_shear_y = parentClipObject->shear_y.GetValue(parent_frame_number);
parentObject_rotation = parentClipObject->rotation.GetValue(parent_frame_number);
}
// Get the parentTrackedObject properties
if (parentTrackedObject){
// Convert Clip's frame position to Timeline's frame position
long clip_start_position = round(Position() * info.fps.ToDouble()) + 1;
long clip_start_frame = (Start() * info.fps.ToDouble()) + 1;
double timeline_frame_number = frame->number + clip_start_position - clip_start_frame;
// Get the parentTrackedObject properties
if (parentTrackedObject){
// Get the attached object's parent clip's properties
Clip* parentClip = (Clip*) parentTrackedObject->ParentClip();
if (parentClip)
{
// Get the start trim position of the parent clip
long parent_start_offset = parentClip->Start() * info.fps.ToDouble();
long parent_frame_number = frame->number + parent_start_offset;
// Get parentTrackedObject's parent clip's properties
std::map<std::string, float> trackedObjectParentClipProperties =
parentTrackedObject->GetParentClipProperties(timeline_frame_number);
// Access the parentTrackedObject's properties
std::map<std::string, float> trackedObjectProperties = parentTrackedObject->GetBoxValues(parent_frame_number);
// Get the attached object's parent clip's properties
if (!trackedObjectParentClipProperties.empty())
{
// Get parent object's properties (Tracked Object)
float parentObject_frame_number = trackedObjectParentClipProperties["frame_number"];
// Access the parentTrackedObject's properties
std::map<std::string, float> trackedObjectProperties = parentTrackedObject->GetBoxValues(parentObject_frame_number);
// Get the Tracked Object's properties and correct them by the clip's reference system
parentObject_location_x = trackedObjectProperties["cx"] - 0.5 + trackedObjectParentClipProperties["location_x"];
parentObject_location_y = trackedObjectProperties["cy"] - 0.5 + trackedObjectParentClipProperties["location_y"];
parentObject_scale_x = trackedObjectProperties["w"]*trackedObjectProperties["sx"];
parentObject_scale_y = trackedObjectProperties["h"]*trackedObjectProperties["sy"];
parentObject_rotation = trackedObjectProperties["r"] + trackedObjectParentClipProperties["rotation"];
}
else
{
// Access the parentTrackedObject's properties
std::map<std::string, float> trackedObjectProperties = parentTrackedObject->GetBoxValues(timeline_frame_number);
// Get the Tracked Object's properties and correct them by the clip's reference system
parentObject_location_x = trackedObjectProperties["cx"] - 0.5;
parentObject_location_y = trackedObjectProperties["cy"] - 0.5;
parentObject_scale_x = trackedObjectProperties["w"]*trackedObjectProperties["sx"];
parentObject_scale_y = trackedObjectProperties["h"]*trackedObjectProperties["sy"];
parentObject_rotation = trackedObjectProperties["r"];
}
}
// Get the Tracked Object's properties and correct them by the clip's reference system
parentObject_location_x = parentClip->location_x.GetValue(parent_frame_number) + ((trackedObjectProperties["cx"] - 0.5) * parentClip->scale_x.GetValue(parent_frame_number));
parentObject_location_y = parentClip->location_y.GetValue(parent_frame_number) + ((trackedObjectProperties["cy"] - 0.5) * parentClip->scale_y.GetValue(parent_frame_number));
parentObject_scale_x = trackedObjectProperties["w"] * trackedObjectProperties["sx"] * parentClip->scale_x.GetValue(parent_frame_number);
parentObject_scale_y = trackedObjectProperties["h"] * trackedObjectProperties["sy"] * parentClip->scale_y.GetValue(parent_frame_number);
parentObject_rotation = trackedObjectProperties["r"] + parentClip->rotation.GetValue(parent_frame_number);
}
}
/* GRAVITY LOCATION - Initialize X & Y to the correct values (before applying location curves) */
float x = 0.0; // left
@@ -1561,8 +1510,8 @@ QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int heig
/* LOCATION, ROTATION, AND SCALE */
float r = rotation.GetValue(frame->number) + parentObject_rotation; // rotate in degrees
x += (width * (location_x.GetValue(frame->number) + parentObject_location_x )); // move in percentage of final width
y += (height * (location_y.GetValue(frame->number) + parentObject_location_y )); // move in percentage of final height
x += width * (location_x.GetValue(frame->number) + parentObject_location_x); // move in percentage of final width
y += height * (location_y.GetValue(frame->number) + parentObject_location_y); // move in percentage of final height
float shear_x_value = shear_x.GetValue(frame->number) + parentObject_shear_x;
float shear_y_value = shear_y.GetValue(frame->number) + parentObject_shear_y;
float origin_x_value = origin_x.GetValue(frame->number);

View File

@@ -522,36 +522,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;
}

View File

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

View File

@@ -66,8 +66,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; };

View File

@@ -82,9 +82,6 @@ std::shared_ptr<Frame> ObjectDetection::GetFrame(std::shared_ptr<Frame> frame, i
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
if (detectionsData.find(frame_number) != detectionsData.end()) {
float fw = frame_image->width();
float fh = frame_image->height();
DetectionData detections = detectionsData[frame_number];
for (int i = 0; i < detections.boxes.size(); i++) {
if (detections.confidences.at(i) < confidence_threshold ||
@@ -99,13 +96,13 @@ std::shared_ptr<Frame> ObjectDetection::GetFrame(std::shared_ptr<Frame> frame, i
if (trackedObject_it != trackedObjects.end()) {
std::shared_ptr<TrackedObjectBBox> trackedObject = std::static_pointer_cast<TrackedObjectBBox>(trackedObject_it->second);
if (trackedObject->Contains(frame_number) && trackedObject->visible.GetValue(frame_number) == 1) {
Clip* parentClip = (Clip*) trackedObject->ParentClip();
if (parentClip && trackedObject->Contains(frame_number) && trackedObject->visible.GetValue(frame_number) == 1) {
BBox trackedBox = trackedObject->GetBox(frame_number);
QRectF boxRect((trackedBox.cx - trackedBox.width / 2) * fw,
(trackedBox.cy - trackedBox.height / 2) * fh,
trackedBox.width * fw,
trackedBox.height * fh);
QRectF boxRect((trackedBox.cx - trackedBox.width / 2) * frame_image->width(),
(trackedBox.cy - trackedBox.height / 2) * frame_image->height(),
trackedBox.width * frame_image->width(),
trackedBox.height * frame_image->height());
if (trackedObject->draw_box.GetValue(frame_number) == 1) {
// Draw bounding box

View File

@@ -135,29 +135,6 @@ std::shared_ptr<Frame> Tracker::GetFrame(std::shared_ptr<Frame> frame, int64_t f
return frame;
}
QRectF Tracker::scaleAndCenterRect(const QRectF& sourceRect, const QRectF& targetRect) {
float sourceAspectRatio = sourceRect.width() / sourceRect.height();
float targetWidth = targetRect.width();
float targetHeight = targetRect.height();
float newWidth, newHeight;
if (sourceAspectRatio > targetRect.width() / targetRect.height()) {
// Source is wider relative to target, so it's constrained by target's width
newWidth = targetWidth;
newHeight = newWidth / sourceAspectRatio;
} else {
// Source is taller relative to target, so it's constrained by target's height
newHeight = targetHeight;
newWidth = newHeight * sourceAspectRatio;
}
// Center the new rectangle within the target rectangle
float newX = targetRect.left() + (targetWidth - newWidth) / 2.0;
float newY = targetRect.top() + (targetHeight - newHeight) / 2.0;
return QRectF(newX, newY, newWidth, newHeight);
}
// Get the indexes and IDs of all visible objects in the given frame
std::string Tracker::GetVisibleObjects(int64_t frame_number) const{

View File

@@ -71,9 +71,6 @@ namespace openshot
/// Get the indexes and IDs of all visible objects in the given frame
std::string GetVisibleObjects(int64_t frame_number) const override;
/// Find a rectangle inside another (centered)
static QRectF scaleAndCenterRect(const QRectF& sourceRect, const QRectF& targetRect);
// Get and Set JSON methods
/// Generate JSON string of this object