From 32033e01e4f01549e6825e912901b2388ed0f6f4 Mon Sep 17 00:00:00 2001 From: Brenno Date: Mon, 12 Apr 2021 21:21:42 -0300 Subject: [PATCH] Changed formatting from tab to spaces --- src/TrackedObjectBBox.cpp | 656 ++++++++++++++-------------- src/TrackedObjectBBox.h | 326 +++++++------- src/TrackedObjectBase.h | 32 +- src/effects/ObjectDetection.cpp | 742 ++++++++++++++++---------------- 4 files changed, 878 insertions(+), 878 deletions(-) diff --git a/src/TrackedObjectBBox.cpp b/src/TrackedObjectBBox.cpp index f4288876..89982932 100644 --- a/src/TrackedObjectBBox.cpp +++ b/src/TrackedObjectBBox.cpp @@ -41,413 +41,413 @@ using namespace openshot; // Default Constructor that sets the bounding-box displacement as 0 and the scales as 1 for the first frame TrackedObjectBBox::TrackedObjectBBox() : delta_x(0.0), delta_y(0.0), scale_x(1.0), scale_y(1.0), rotation(0.0), - stroke_width(2) , background_alpha(1.0), stroke_alpha(0.0), background_corner(0), - stroke(0,0,255,0), background(0,0,255,0) + stroke_width(2) , background_alpha(1.0), stroke_alpha(0.0), background_corner(0), + stroke(0,0,255,0), background(0,0,255,0) { - this->TimeScale = 1.0; - return; + this->TimeScale = 1.0; + return; } 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), - stroke_width(2) , background_alpha(1.0), stroke_alpha(0.0), background_corner(0), - stroke(Red,Green,Blue,Alfa), background(0,0,255,0) + stroke_width(2) , background_alpha(1.0), stroke_alpha(0.0), background_corner(0), + stroke(Red,Green,Blue,Alfa), background(0,0,255,0) { - this->TimeScale = 1.0; - return; + this->TimeScale = 1.0; + return; } // Add a BBox to the BoxVec map void TrackedObjectBBox::AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) { - // Check if the given frame number is valid - if (_frame_num < 0) - return; + // Check if the given frame number is valid + if (_frame_num < 0) + return; - // Instantiate a new bounding-box - BBox newBBox = BBox(_cx, _cy, _width, _height, _angle); + // Instantiate a new bounding-box + BBox newBBox = BBox(_cx, _cy, _width, _height, _angle); - // Get the time of given frame - double time = this->FrameNToTime(_frame_num, 1.0); - // Create an iterator that points to the BoxVec pair indexed by the time of given frame - auto BBoxIterator = BoxVec.find(time); - - if (BBoxIterator != BoxVec.end()) - { - // There is a bounding-box indexed by the time of given frame, update-it - BBoxIterator->second = newBBox; - } - else - { - // There isn't a bounding-box indexed by the time of given frame, insert a new one - BoxVec.insert({time, newBBox}); - } + // Get the time of given frame + double time = this->FrameNToTime(_frame_num, 1.0); + // Create an iterator that points to the BoxVec pair indexed by the time of given frame + auto BBoxIterator = BoxVec.find(time); + + if (BBoxIterator != BoxVec.end()) + { + // There is a bounding-box indexed by the time of given frame, update-it + BBoxIterator->second = newBBox; + } + else + { + // There isn't a bounding-box indexed by the time of given frame, insert a new one + BoxVec.insert({time, newBBox}); + } } // Get the size of BoxVec map int64_t TrackedObjectBBox::GetLength() const { - if (BoxVec.empty()) - return 0; - if (BoxVec.size() == 1) - return 1; - return BoxVec.size(); + if (BoxVec.empty()) + return 0; + if (BoxVec.size() == 1) + return 1; + return BoxVec.size(); } // Check if there is a bounding-box in the given frame bool TrackedObjectBBox::Contains(int64_t frame_num) const { - // Get the time of given frame - double time = this->FrameNToTime(frame_num, 1.0); - // Create an iterator that points to the BoxVec pair indexed by the time of given frame (or the closest time) - auto it = BoxVec.lower_bound(time); - if (it == BoxVec.end()){ - // BoxVec pair not found - return false; - } - return true; + // Get the time of given frame + double time = this->FrameNToTime(frame_num, 1.0); + // Create an iterator that points to the BoxVec pair indexed by the time of given frame (or the closest time) + auto it = BoxVec.lower_bound(time); + if (it == BoxVec.end()){ + // BoxVec pair not found + return false; + } + return true; } // Check if there is a bounding-box in the exact frame number bool TrackedObjectBBox::ExactlyContains(int64_t frame_number) const { - // Get the time of given frame - double time = FrameNToTime(frame_number, 1.0); - // Create an iterator that points to the BoxVec pair indexed by the exact time of given frame - auto it = BoxVec.find(time); - if (it == BoxVec.end()){ - // BoxVec pair not found - return false; - } - return true; + // Get the time of given frame + double time = FrameNToTime(frame_number, 1.0); + // Create an iterator that points to the BoxVec pair indexed by the exact time of given frame + auto it = BoxVec.find(time); + if (it == BoxVec.end()){ + // BoxVec pair not found + return false; + } + return true; } // Remove a bounding-box from the BoxVec map void TrackedObjectBBox::RemoveBox(int64_t frame_number) { - // Get the time of given frame - double time = this->FrameNToTime(frame_number, 1.0); - // Create an iterator that points to the BoxVec pair indexed by the time of given frame - auto it = BoxVec.find(time); - if (it != BoxVec.end()) - { - // The BoxVec pair exists, so remove it - BoxVec.erase(time); - } - return; + // Get the time of given frame + double time = this->FrameNToTime(frame_number, 1.0); + // Create an iterator that points to the BoxVec pair indexed by the time of given frame + auto it = BoxVec.find(time); + if (it != BoxVec.end()) + { + // The BoxVec pair exists, so remove it + BoxVec.erase(time); + } + return; } // Return a bounding-box from BoxVec with it's properties adjusted by the Keyframes BBox TrackedObjectBBox::GetBox(int64_t frame_number) { - // Get the time position of the given frame. - double time = this->FrameNToTime(frame_number, this->TimeScale); + // Get the time position of the given frame. + double time = this->FrameNToTime(frame_number, this->TimeScale); - // Return a iterator pointing to the BoxVec pair indexed by time or to the pair indexed - // by the closest upper time value. - auto currentBBoxIterator = BoxVec.lower_bound(time); + // Return a iterator pointing to the BoxVec pair indexed by time or to the pair indexed + // by the closest upper time value. + auto currentBBoxIterator = BoxVec.lower_bound(time); - // Check if there is a pair indexed by time, returns an empty bbox if there isn't. - if (currentBBoxIterator == BoxVec.end()) - { - // Create and return an empty bounding-box object - BBox emptyBBox; - return emptyBBox; - } + // Check if there is a pair indexed by time, returns an empty bbox if there isn't. + if (currentBBoxIterator == BoxVec.end()) + { + // Create and return an empty bounding-box object + BBox emptyBBox; + return emptyBBox; + } - // Check if the iterator matches a BBox indexed by time or points to the first element of BoxVec - if ((currentBBoxIterator->first == time) || (currentBBoxIterator == BoxVec.begin())) - { - // Get the BBox indexed by time - BBox currentBBox = currentBBoxIterator->second; + // Check if the iterator matches a BBox indexed by time or points to the first element of BoxVec + if ((currentBBoxIterator->first == time) || (currentBBoxIterator == BoxVec.begin())) + { + // Get the BBox indexed by time + BBox currentBBox = currentBBoxIterator->second; - // Adjust the BBox properties by the Keyframes values - currentBBox.cx += this->delta_x.GetValue(frame_number); - currentBBox.cy += this->delta_y.GetValue(frame_number); - currentBBox.width *= this->scale_x.GetValue(frame_number); - currentBBox.height *= this->scale_y.GetValue(frame_number); - currentBBox.angle += this->rotation.GetValue(frame_number); - - return currentBBox; - } + // Adjust the BBox properties by the Keyframes values + currentBBox.cx += this->delta_x.GetValue(frame_number); + currentBBox.cy += this->delta_y.GetValue(frame_number); + currentBBox.width *= this->scale_x.GetValue(frame_number); + currentBBox.height *= this->scale_y.GetValue(frame_number); + currentBBox.angle += this->rotation.GetValue(frame_number); + + return currentBBox; + } - // BBox indexed by the closest upper time - BBox currentBBox = currentBBoxIterator->second; - // BBox indexed by the closet lower time - BBox previousBBox = prev(currentBBoxIterator, 1)->second; + // BBox indexed by the closest upper time + BBox currentBBox = currentBBoxIterator->second; + // BBox indexed by the closet lower time + BBox previousBBox = prev(currentBBoxIterator, 1)->second; - // Interpolate a BBox in the middle of previousBBox and currentBBox - BBox interpolatedBBox = InterpolateBoxes(prev(currentBBoxIterator, 1)->first, currentBBoxIterator->first, - previousBBox, currentBBox, time); + // Interpolate a BBox in the middle of previousBBox and currentBBox + BBox interpolatedBBox = InterpolateBoxes(prev(currentBBoxIterator, 1)->first, currentBBoxIterator->first, + previousBBox, currentBBox, time); - // Adjust the BBox properties by the Keyframes values - interpolatedBBox.cx += this->delta_x.GetValue(frame_number); - interpolatedBBox.cy += this->delta_y.GetValue(frame_number); - interpolatedBBox.width *= this->scale_x.GetValue(frame_number); - interpolatedBBox.height *= this->scale_y.GetValue(frame_number); - interpolatedBBox.angle += this->rotation.GetValue(frame_number); - - return interpolatedBBox; + // Adjust the BBox properties by the Keyframes values + interpolatedBBox.cx += this->delta_x.GetValue(frame_number); + interpolatedBBox.cy += this->delta_y.GetValue(frame_number); + interpolatedBBox.width *= this->scale_x.GetValue(frame_number); + interpolatedBBox.height *= this->scale_y.GetValue(frame_number); + interpolatedBBox.angle += this->rotation.GetValue(frame_number); + + return interpolatedBBox; } // Interpolate the bouding-boxes properties BBox TrackedObjectBBox::InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target) { - // Interpolate the x-coordinate of the center point - Point cx_left(t1, left.cx, openshot::InterpolationType::LINEAR); - Point cx_right(t2, right.cx, openshot::InterpolationType::LINEAR); - Point cx = InterpolateBetween(cx_left, cx_right, target, 0.01); + // Interpolate the x-coordinate of the center point + Point cx_left(t1, left.cx, openshot::InterpolationType::LINEAR); + Point cx_right(t2, right.cx, openshot::InterpolationType::LINEAR); + Point cx = InterpolateBetween(cx_left, cx_right, target, 0.01); - // Interpolate de y-coordinate of the center point - Point cy_left(t1, left.cy, openshot::InterpolationType::LINEAR); - Point cy_right(t2, right.cy, openshot::InterpolationType::LINEAR); - Point cy = InterpolateBetween(cy_left, cy_right, target, 0.01); + // Interpolate de y-coordinate of the center point + Point cy_left(t1, left.cy, openshot::InterpolationType::LINEAR); + Point cy_right(t2, right.cy, openshot::InterpolationType::LINEAR); + Point cy = InterpolateBetween(cy_left, cy_right, target, 0.01); - // Interpolate the width - Point width_left(t1, left.width, openshot::InterpolationType::LINEAR); - Point width_right(t2, right.width, openshot::InterpolationType::LINEAR); - Point width = InterpolateBetween(width_left, width_right, target, 0.01); + // Interpolate the width + Point width_left(t1, left.width, openshot::InterpolationType::LINEAR); + Point width_right(t2, right.width, openshot::InterpolationType::LINEAR); + Point width = InterpolateBetween(width_left, width_right, target, 0.01); - // Interpolate the height - Point height_left(t1, left.height, openshot::InterpolationType::LINEAR); - Point height_right(t2, right.height, openshot::InterpolationType::LINEAR); - Point height = InterpolateBetween(height_left, height_right, target, 0.01); + // Interpolate the height + Point height_left(t1, left.height, openshot::InterpolationType::LINEAR); + Point height_right(t2, right.height, openshot::InterpolationType::LINEAR); + Point height = InterpolateBetween(height_left, height_right, target, 0.01); - // Interpolate the rotation angle - Point angle_left(t1, left.angle, openshot::InterpolationType::LINEAR); - Point angle_right(t1, right.angle, openshot::InterpolationType::LINEAR); - Point angle = InterpolateBetween(angle_left, angle_right, target, 0.01); + // Interpolate the rotation angle + Point angle_left(t1, left.angle, openshot::InterpolationType::LINEAR); + Point angle_right(t1, right.angle, openshot::InterpolationType::LINEAR); + Point angle = InterpolateBetween(angle_left, angle_right, target, 0.01); - // Create a bounding box with the interpolated points - BBox interpolatedBox(cx.co.Y, cy.co.Y, width.co.Y, height.co.Y, angle.co.Y); + // Create a bounding box with the interpolated points + BBox interpolatedBox(cx.co.Y, cy.co.Y, width.co.Y, height.co.Y, angle.co.Y); - return interpolatedBox; + return interpolatedBox; } // Update object's BaseFps void TrackedObjectBBox::SetBaseFPS(Fraction fps){ - this->BaseFps = fps; - return; + this->BaseFps = fps; + return; } // Return the object's BaseFps Fraction TrackedObjectBBox::GetBaseFPS(){ - return BaseFps; + return BaseFps; } // Get the time of the given frame double TrackedObjectBBox::FrameNToTime(int64_t frame_number, double time_scale) const{ - double time = ((double)frame_number) * this->BaseFps.Reciprocal().ToDouble() * (1.0 / time_scale); + double time = ((double)frame_number) * this->BaseFps.Reciprocal().ToDouble() * (1.0 / time_scale); - return time; + return time; } // Update the TimeScale member variable void TrackedObjectBBox::ScalePoints(double time_scale){ - this->TimeScale = time_scale; + this->TimeScale = time_scale; } // Load the bounding-boxes information from the protobuf file bool TrackedObjectBBox::LoadBoxData(std::string inputFilePath) { - // Variable to hold the loaded data - pb_tracker::Tracker bboxMessage; + // Variable to hold the loaded data + pb_tracker::Tracker bboxMessage; - // Read the existing tracker message. - fstream input(inputFilePath, ios::in | ios::binary); + // Read the existing tracker message. + fstream input(inputFilePath, ios::in | ios::binary); - // Check if it was able to read the protobuf data - if (!bboxMessage.ParseFromIstream(&input)) - { - cerr << "Failed to parse protobuf message." << endl; - return false; - } - - this->clear(); + // Check if it was able to read the protobuf data + if (!bboxMessage.ParseFromIstream(&input)) + { + cerr << "Failed to parse protobuf message." << endl; + return false; + } + + this->clear(); - // Iterate over all frames of the saved message - for (size_t i = 0; i < bboxMessage.frame_size(); i++) - { - // Get data of the i-th frame - const pb_tracker::Frame &pbFrameData = bboxMessage.frame(i); + // Iterate over all frames of the saved message + for (size_t i = 0; i < bboxMessage.frame_size(); i++) + { + // Get data of the i-th frame + const pb_tracker::Frame &pbFrameData = bboxMessage.frame(i); - // Get frame number - size_t frame_number = pbFrameData.id(); + // Get frame number + size_t frame_number = pbFrameData.id(); - // Get bounding box data from current frame - const pb_tracker::Frame::Box &box = pbFrameData.bounding_box(); + // Get bounding box data from current frame + const pb_tracker::Frame::Box &box = pbFrameData.bounding_box(); - float width = box.x2() - box.x1(); - float height = box.y2() - box.y1(); - float cx = box.x1() + width/2; - float cy = box.y1() + height/2; - float angle = 0.0; + float width = box.x2() - box.x1(); + float height = box.y2() - box.y1(); + float cx = box.x1() + width/2; + float cy = box.y1() + height/2; + float angle = 0.0; - if ( (cx >= 0.0) && (cy >= 0.0) && (width >= 0.0) && (height >= 0.0) ) - { - // The bounding-box properties are valid, so add it to the BoxVec map - this->AddBox(frame_number, cx, cy, width, height, angle); - } - } - - // Show the time stamp from the last update in tracker data file - if (bboxMessage.has_last_updated()) - { - cout << " Loaded Data. Saved Time Stamp: " << TimeUtil::ToString(bboxMessage.last_updated()) << endl; - } + if ( (cx >= 0.0) && (cy >= 0.0) && (width >= 0.0) && (height >= 0.0) ) + { + // The bounding-box properties are valid, so add it to the BoxVec map + this->AddBox(frame_number, cx, cy, width, height, angle); + } + } + + // Show the time stamp from the last update in tracker data file + if (bboxMessage.has_last_updated()) + { + cout << " Loaded Data. Saved Time Stamp: " << TimeUtil::ToString(bboxMessage.last_updated()) << endl; + } - // Delete all global objects allocated by libprotobuf. - google::protobuf::ShutdownProtobufLibrary(); + // Delete all global objects allocated by libprotobuf. + google::protobuf::ShutdownProtobufLibrary(); - return true; + return true; } // Clear the BoxVec map void TrackedObjectBBox::clear() { - BoxVec.clear(); + BoxVec.clear(); } // Generate JSON string of this object std::string TrackedObjectBBox::Json() const { - // Return formatted string - return JsonValue().toStyledString(); + // Return formatted string + return JsonValue().toStyledString(); } // Generate Json::Value for this object Json::Value TrackedObjectBBox::JsonValue() const { - // Create root json object - Json::Value root; + // Create root json object + Json::Value root; - // Object's properties - root["box_id"] = Id(); - root["BaseFPS"]["num"] = BaseFps.num; - root["BaseFPS"]["den"] = BaseFps.den; - root["TimeScale"] = TimeScale; - root["child_clip_id"] = ChildClipId(); + // Object's properties + root["box_id"] = Id(); + 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(); - root["delta_y"] = delta_y.JsonValue(); - root["scale_x"] = scale_x.JsonValue(); - root["scale_y"] = scale_y.JsonValue(); - root["rotation"] = rotation.JsonValue(); - root["visible"] = visible.JsonValue(); - root["draw_box"] = draw_box.JsonValue(); - root["stroke"] = stroke.JsonValue(); - root["background_alpha"] = background_alpha.JsonValue(); - root["background_corner"] = background_corner.JsonValue(); - root["background"] = background.JsonValue(); - root["stroke_width"] = stroke_width.JsonValue(); - root["stroke_alpha"] = stroke_alpha.JsonValue(); + // Keyframe's properties + root["delta_x"] = delta_x.JsonValue(); + root["delta_y"] = delta_y.JsonValue(); + root["scale_x"] = scale_x.JsonValue(); + root["scale_y"] = scale_y.JsonValue(); + root["rotation"] = rotation.JsonValue(); + root["visible"] = visible.JsonValue(); + root["draw_box"] = draw_box.JsonValue(); + root["stroke"] = stroke.JsonValue(); + root["background_alpha"] = background_alpha.JsonValue(); + root["background_corner"] = background_corner.JsonValue(); + root["background"] = background.JsonValue(); + root["stroke_width"] = stroke_width.JsonValue(); + root["stroke_alpha"] = stroke_alpha.JsonValue(); - // return JsonValue - return root; + // return JsonValue + return root; } // Load JSON string into this object void TrackedObjectBBox::SetJson(const std::string value) { - // Parse JSON string into JSON objects - try - { - const Json::Value root = openshot::stringToJson(value); - // Set all values that match - SetJsonValue(root); - } - catch (const std::exception &e) - { - // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); - } - return; + // Parse JSON string into JSON objects + try + { + const Json::Value root = openshot::stringToJson(value); + // Set all values that match + SetJsonValue(root); + } + catch (const std::exception &e) + { + // Error parsing JSON (or missing keys) + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); + } + return; } // Load Json::Value into this object void TrackedObjectBBox::SetJsonValue(const Json::Value root) { - // Set the Id by the given JSON object - if (!root["box_id"].isNull() && root["box_id"].asString() != "None") - Id(root["box_id"].asString()); + // Set the Id by the given JSON object + if (!root["box_id"].isNull() && root["box_id"].asString() != "None") + Id(root["box_id"].asString()); - // Set the BaseFps by the given JSON object - if (!root["BaseFPS"].isNull() && root["BaseFPS"].isObject()) - { - if (!root["BaseFPS"]["num"].isNull()) - BaseFps.num = (int)root["BaseFPS"]["num"].asInt(); - if (!root["BaseFPS"]["den"].isNull()) - BaseFps.den = (int)root["BaseFPS"]["den"].asInt(); - } + // Set the BaseFps by the given JSON object + if (!root["BaseFPS"].isNull() && root["BaseFPS"].isObject()) + { + if (!root["BaseFPS"]["num"].isNull()) + BaseFps.num = (int)root["BaseFPS"]["num"].asInt(); + if (!root["BaseFPS"]["den"].isNull()) + BaseFps.den = (int)root["BaseFPS"]["den"].asInt(); + } - // Set the TimeScale by the given JSON object - if (!root["TimeScale"].isNull()) - { - double scale = (double)root["TimeScale"].asDouble(); - this->ScalePoints(scale); - } + // Set the TimeScale by the given JSON object + if (!root["TimeScale"].isNull()) + { + double scale = (double)root["TimeScale"].asDouble(); + this->ScalePoints(scale); + } - // Set the protobuf data path by the given JSON object - if (!root["protobuf_data_path"].isNull()) - protobufDataPath = root["protobuf_data_path"].asString(); + // Set the protobuf data path by the given JSON object + if (!root["protobuf_data_path"].isNull()) + protobufDataPath = root["protobuf_data_path"].asString(); - // Set the id of the child clip - // Does not allow to link to the parent clip - if (!root["child_clip_id"].isNull() && root["box_id"].asString() != "None"){ - Clip* parentClip = (Clip *) ParentClip(); - - if(parentClip && (root["child_clip_id"].asString() != parentClip->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"]); - if (!root["delta_y"].isNull()) + // Set the id of the child clip + // Does not allow to link to the parent clip + if (!root["child_clip_id"].isNull() && root["box_id"].asString() != "None"){ + Clip* parentClip = (Clip *) ParentClip(); + + if(parentClip && (root["child_clip_id"].asString() != parentClip->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"]); + if (!root["delta_y"].isNull()) delta_y.SetJsonValue(root["delta_y"]); - if (!root["scale_x"].isNull()) - scale_x.SetJsonValue(root["scale_x"]); - if (!root["scale_y"].isNull()) - scale_y.SetJsonValue(root["scale_y"]); - if (!root["rotation"].isNull()) - rotation.SetJsonValue(root["rotation"]); - if (!root["visible"].isNull()) - visible.SetJsonValue(root["visible"]); - if (!root["draw_box"].isNull()) + if (!root["scale_x"].isNull()) + scale_x.SetJsonValue(root["scale_x"]); + if (!root["scale_y"].isNull()) + scale_y.SetJsonValue(root["scale_y"]); + if (!root["rotation"].isNull()) + rotation.SetJsonValue(root["rotation"]); + if (!root["visible"].isNull()) + visible.SetJsonValue(root["visible"]); + if (!root["draw_box"].isNull()) draw_box.SetJsonValue(root["draw_box"]); - if (!root["stroke"].isNull()) + if (!root["stroke"].isNull()) stroke.SetJsonValue(root["stroke"]); - if (!root["background_alpha"].isNull()) + if (!root["background_alpha"].isNull()) background_alpha.SetJsonValue(root["background_alpha"]); - if (!root["background_corner"].isNull()) + if (!root["background_corner"].isNull()) background_corner.SetJsonValue(root["background_corner"]); - if (!root["background"].isNull()) + if (!root["background"].isNull()) background.SetJsonValue(root["background"]); - if (!root["stroke_width"].isNull()) + if (!root["stroke_width"].isNull()) stroke_width.SetJsonValue(root["stroke_width"]); - if (!root["stroke_alpha"].isNull()) + if (!root["stroke_alpha"].isNull()) stroke_alpha.SetJsonValue(root["stroke_alpha"]); - return; + return; } // Get all properties for a specific frame (perfect for a UI to display the current state // of all properties at any time) Json::Value TrackedObjectBBox::PropertiesJSON(int64_t requested_frame) const { - Json::Value root; + Json::Value root; - BBox box = GetBox(requested_frame); + BBox box = GetBox(requested_frame); - // 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 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 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 + // 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); @@ -459,26 +459,26 @@ Json::Value TrackedObjectBBox::PropertiesJSON(int64_t requested_frame) const 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, false, 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"] = 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["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); - root["stroke"]["blue"] = add_property_json("Blue", stroke.blue.GetValue(requested_frame), "float", "", &stroke.blue, 0, 255, false, requested_frame); - root["stroke"]["green"] = add_property_json("Green", stroke.green.GetValue(requested_frame), "float", "", &stroke.green, 0, 255, false, requested_frame); - root["stroke_width"] = add_property_json("Stroke Width", stroke_width.GetValue(requested_frame), "int", "", &stroke_width, 1, 10, false, requested_frame); - root["stroke_alpha"] = add_property_json("Stroke alpha", stroke_alpha.GetValue(requested_frame), "float", "", &stroke_alpha, 0.0, 1.0, false, 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); + root["stroke"]["blue"] = add_property_json("Blue", stroke.blue.GetValue(requested_frame), "float", "", &stroke.blue, 0, 255, false, requested_frame); + root["stroke"]["green"] = add_property_json("Green", stroke.green.GetValue(requested_frame), "float", "", &stroke.green, 0, 255, false, requested_frame); + root["stroke_width"] = add_property_json("Stroke Width", stroke_width.GetValue(requested_frame), "int", "", &stroke_width, 1, 10, false, requested_frame); + 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"] = 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); - root["background"]["blue"] = add_property_json("Blue", background.blue.GetValue(requested_frame), "float", "", &background.blue, 0, 255, false, requested_frame); - root["background"]["green"] = add_property_json("Green", background.green.GetValue(requested_frame), "float", "", &background.green, 0, 255, 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"] = 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); + root["background"]["blue"] = add_property_json("Blue", background.blue.GetValue(requested_frame), "float", "", &background.blue, 0, 255, false, requested_frame); + root["background"]["green"] = add_property_json("Green", background.green.GetValue(requested_frame), "float", "", &background.green, 0, 255, false, requested_frame); // Return formatted string return root; @@ -525,59 +525,59 @@ Json::Value TrackedObjectBBox::add_property_json(std::string name, float value, // Return a map that contains the bounding box properties and it's keyframes indexed by their names std::map TrackedObjectBBox::GetBoxValues(int64_t frame_number) const { - // Create the map - std::map boxValues; + // Create the map + std::map boxValues; - // Get bounding box of the current frame - BBox box = GetBox(frame_number); + // Get bounding box of the current frame + BBox box = GetBox(frame_number); - // Save the bounding box properties - boxValues["cx"] = box.cx; - boxValues["cy"] = box.cy; - boxValues["w"] = box.width; - boxValues["h"] = box.height; - boxValues["ang"] = box.angle; + // Save the bounding box properties + boxValues["cx"] = box.cx; + boxValues["cy"] = box.cy; + boxValues["w"] = box.width; + boxValues["h"] = box.height; + boxValues["ang"] = box.angle; - // Save the keyframes values - boxValues["sx"] = this->scale_x.GetValue(frame_number); - boxValues["sy"] = this->scale_y.GetValue(frame_number); - boxValues["dx"] = this->delta_x.GetValue(frame_number); - boxValues["dy"] = this->delta_y.GetValue(frame_number); - boxValues["r"] = this->rotation.GetValue(frame_number); + // Save the keyframes values + boxValues["sx"] = this->scale_x.GetValue(frame_number); + boxValues["sy"] = this->scale_y.GetValue(frame_number); + boxValues["dx"] = this->delta_x.GetValue(frame_number); + boxValues["dy"] = this->delta_y.GetValue(frame_number); + boxValues["r"] = this->rotation.GetValue(frame_number); - - return boxValues; + + return boxValues; } // Return a map that contains the properties of this object's parent clip std::map TrackedObjectBBox::GetParentClipProperties(int64_t frame_number) const { - - // Get the parent clip of this object as a Clip pointer - Clip* parentClip = (Clip *) ParentClip(); + + // 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; + // 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); + // 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 parentClipProperties; + // Initialize the parent clip properties map + std::map 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; + // 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; + return parentClipProperties; } \ No newline at end of file diff --git a/src/TrackedObjectBBox.h b/src/TrackedObjectBBox.h index e50f3cf8..bf66c388 100644 --- a/src/TrackedObjectBBox.h +++ b/src/TrackedObjectBBox.h @@ -52,197 +52,197 @@ using google::protobuf::util::TimeUtil; namespace openshot { - /** - * @brief This struct holds the information of a bounding-box. - * - * A bounding-box is a rectangular shape that enclosures an - * object or a desired set of pixels in a digital image. - * - * The bounding-box structure holds five floating-point properties: - * the x and y coordinates of the rectangle's center point (cx, cy), - * the rectangle's width, height and rotation. - */ - struct BBox - { - float cx = -1; ///< x-coordinate of the bounding box center - float cy = -1; ///< y-coordinate of the bounding box center - float width = -1; ///< bounding box width - float height = -1; ///< bounding box height - float angle = -1; ///< bounding box rotation angle [degrees] + /** + * @brief This struct holds the information of a bounding-box. + * + * A bounding-box is a rectangular shape that enclosures an + * object or a desired set of pixels in a digital image. + * + * The bounding-box structure holds five floating-point properties: + * the x and y coordinates of the rectangle's center point (cx, cy), + * the rectangle's width, height and rotation. + */ + struct BBox + { + float cx = -1; ///< x-coordinate of the bounding box center + float cy = -1; ///< y-coordinate of the bounding box center + float width = -1; ///< bounding box width + float height = -1; ///< bounding box height + float angle = -1; ///< bounding box rotation angle [degrees] - /// Blank constructor - BBox() {} + /// Blank constructor + BBox() {} - /// Default constructor, which takes the bounding box top-left corner coordinates, width and height. - /// @param _cx X-coordinate of the bounding box center - /// @param _cy Y-coordinate of the bounding box center - /// @param _width Bounding box width - /// @param _height Bounding box height - /// @param _angle Bounding box rotation angle [degrees] - BBox(float _cx, float _cy, float _width, float _height, float _angle) - { - cx = _cx; - cy = _cy; - width = _width; - height = _height; - angle = _angle; - } + /// Default constructor, which takes the bounding box top-left corner coordinates, width and height. + /// @param _cx X-coordinate of the bounding box center + /// @param _cy Y-coordinate of the bounding box center + /// @param _width Bounding box width + /// @param _height Bounding box height + /// @param _angle Bounding box rotation angle [degrees] + BBox(float _cx, float _cy, float _width, float _height, float _angle) + { + cx = _cx; + cy = _cy; + width = _width; + height = _height; + angle = _angle; + } - - /// Generate JSON string of this object - std::string Json() const - { - return JsonValue().toStyledString(); - } + + /// Generate JSON string of this object + std::string Json() const + { + return JsonValue().toStyledString(); + } - /// Generate Json::Value for this object - Json::Value JsonValue() const - { - Json::Value root; - root["cx"] = cx; - root["cy"] = cy; - root["width"] = width; - root["height"] = height; - root["angle"] = angle; + /// Generate Json::Value for this object + Json::Value JsonValue() const + { + Json::Value root; + root["cx"] = cx; + root["cy"] = cy; + root["width"] = width; + root["height"] = height; + root["angle"] = angle; - return root; - } + return root; + } - /// Load JSON string into this object - void SetJson(const std::string value) - { - // Parse JSON string into JSON objects - try - { - const Json::Value root = openshot::stringToJson(value); - // Set all values that match - SetJsonValue(root); - } - catch (const std::exception &e) - { - // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); - } - } + /// Load JSON string into this object + void SetJson(const std::string value) + { + // Parse JSON string into JSON objects + try + { + const Json::Value root = openshot::stringToJson(value); + // Set all values that match + SetJsonValue(root); + } + catch (const std::exception &e) + { + // Error parsing JSON (or missing keys) + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); + } + } - /// Load Json::Value into this object - void SetJsonValue(const Json::Value root) - { + /// Load Json::Value into this object + void SetJsonValue(const Json::Value root) + { - // Set data from Json (if key is found) - if (!root["cx"].isNull()) - cx = root["cx"].asDouble(); - if (!root["cy"].isNull()) - cy = root["cy"].asDouble(); - if (!root["width"].isNull()) - width = root["width"].asDouble(); - if (!root["height"].isNull()) - height = root["height"].asDouble(); - if (!root["angle"].isNull()) - angle = root["angle"].asDouble(); - } - }; + // Set data from Json (if key is found) + if (!root["cx"].isNull()) + cx = root["cx"].asDouble(); + if (!root["cy"].isNull()) + cy = root["cy"].asDouble(); + if (!root["width"].isNull()) + width = root["width"].asDouble(); + if (!root["height"].isNull()) + height = root["height"].asDouble(); + if (!root["angle"].isNull()) + angle = root["angle"].asDouble(); + } + }; - /** - * @brief This class contains the properties of a tracked object - * and functions to manipulate it. - * - * The bounding-box displacement in X and Y directions, it's width, - * height and rotation variation over the frames are set as - * openshot::Keyframe objects. - * - * The bounding-box information over the clip's frames are - * saved into a protobuf file and loaded into an - * object of this class. - */ - class TrackedObjectBBox : public TrackedObjectBase - { - private: - Fraction BaseFps; - double TimeScale; + /** + * @brief This class contains the properties of a tracked object + * and functions to manipulate it. + * + * The bounding-box displacement in X and Y directions, it's width, + * height and rotation variation over the frames are set as + * openshot::Keyframe objects. + * + * The bounding-box information over the clip's frames are + * saved into a protobuf file and loaded into an + * object of this class. + */ + class TrackedObjectBBox : public TrackedObjectBase + { + private: + Fraction BaseFps; + double TimeScale; - public: - std::map BoxVec; ///< Index the bounding-box by time of each frame - Keyframe delta_x; ///< X-direction displacement Keyframe - Keyframe delta_y; ///< Y-direction displacement Keyframe - Keyframe scale_x; ///< X-direction scale Keyframe - Keyframe scale_y; ///< Y-direction scale Keyframe - Keyframe rotation; ///< Rotation Keyframe - Keyframe background_alpha; ///< Background box opacity - Keyframe background_corner; ///< Radius of rounded corners - Keyframe stroke_width; ///< Thickness of border line - Keyframe stroke_alpha; ///< Stroke box opacity - Color stroke; ///< Border line color - Color background; ///< Background fill color + public: + std::map BoxVec; ///< Index the bounding-box by time of each frame + Keyframe delta_x; ///< X-direction displacement Keyframe + Keyframe delta_y; ///< Y-direction displacement Keyframe + Keyframe scale_x; ///< X-direction scale Keyframe + Keyframe scale_y; ///< Y-direction scale Keyframe + Keyframe rotation; ///< Rotation Keyframe + Keyframe background_alpha; ///< Background box opacity + Keyframe background_corner; ///< Radius of rounded corners + Keyframe stroke_width; ///< Thickness of border line + Keyframe stroke_alpha; ///< Stroke box opacity + Color stroke; ///< Border line color + Color background; ///< Background fill color - std::string protobufDataPath; ///< Path to the protobuf file that holds the bounding box points across the frames + std::string protobufDataPath; ///< Path to the protobuf file that holds the bounding box points across the frames - /// Default Constructor - TrackedObjectBBox(); - TrackedObjectBBox(int Red, int Green, int Blue, int Alfa); + /// Default Constructor + TrackedObjectBBox(); + TrackedObjectBBox(int Red, int Green, int Blue, int Alfa); - /// Add a BBox to the BoxVec map - void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) override; - - /// Update object's BaseFps - void SetBaseFPS(Fraction fps); + /// Add a BBox to the BoxVec map + void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) override; + + /// Update object's BaseFps + void SetBaseFPS(Fraction fps); - /// Return the object's BaseFps - Fraction GetBaseFPS(); + /// Return the object's BaseFps + Fraction GetBaseFPS(); - /// Update the TimeScale member variable - void ScalePoints(double scale) override; + /// Update the TimeScale member variable + void ScalePoints(double scale) override; - /// Check if there is a bounding-box in the given frame - bool Contains(int64_t frame_number) const; - /// Check if there is a bounding-box in the exact frame number - bool ExactlyContains(int64_t frame_number) const override; + /// Check if there is a bounding-box in the given frame + bool Contains(int64_t frame_number) const; + /// Check if there is a bounding-box in the exact frame number + bool ExactlyContains(int64_t frame_number) const override; - /// Get the size of BoxVec map - int64_t GetLength() const; + /// Get the size of BoxVec map + int64_t GetLength() const; - /// Remove a bounding-box from the BoxVec map - void RemoveBox(int64_t frame_number); + /// Remove a bounding-box from the BoxVec map + void RemoveBox(int64_t frame_number); - /// Return a bounding-box from BoxVec with it's properties adjusted by the Keyframes - BBox GetBox(int64_t frame_number); - /// Const-cast of the GetBox function, so that it can be called inside other cont function - BBox GetBox(int64_t frame_number) const - { - return const_cast(this)->GetBox(frame_number); - } + /// Return a bounding-box from BoxVec with it's properties adjusted by the Keyframes + BBox GetBox(int64_t frame_number); + /// Const-cast of the GetBox function, so that it can be called inside other cont function + BBox GetBox(int64_t frame_number) const + { + return const_cast(this)->GetBox(frame_number); + } - /// Load the bounding-boxes information from the protobuf file - bool LoadBoxData(std::string inputFilePath); + /// Load the bounding-boxes information from the protobuf file + bool LoadBoxData(std::string inputFilePath); - /// Get the time of the given frame - double FrameNToTime(int64_t frame_number, double time_scale) const; + /// Get the time of the given frame + double FrameNToTime(int64_t frame_number, double time_scale) const; - /// Interpolate the bouding-boxes properties - BBox InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target); + /// Interpolate the bouding-boxes properties + BBox InterpolateBoxes(double t1, double t2, BBox left, BBox right, double target); - /// Clear the BoxVec map - void clear(); + /// Clear the BoxVec map + void clear(); - /// Get and Set JSON methods - std::string Json() const override; ///< Generate JSON string of this object - Json::Value JsonValue() const override; ///< Generate Json::Value for this object - void SetJson(const std::string value) override; ///< Load JSON string into this object - void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object + /// Get and Set JSON methods + std::string Json() const override; ///< Generate JSON string of this object + Json::Value JsonValue() const override; ///< Generate Json::Value for this object + void SetJson(const std::string value) override; ///< Load JSON string into this object + void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object - /// Get all properties for a specific frame (perfect for a UI to display the current state + /// Get all properties for a specific frame (perfect for a UI to display the current state /// of all properties at any time) - Json::Value PropertiesJSON(int64_t requested_frame) const override; + Json::Value PropertiesJSON(int64_t requested_frame) const override; - // Generate JSON for a property - 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 + 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; - /// Return a map that contains the bounding box properties and it's keyframes indexed by their names - std::map GetBoxValues(int64_t frame_number) const override; - /// Return a map that contains the properties of this object's parent clip - std::map GetParentClipProperties(int64_t frame_number) const override; - - }; + /// Return a map that contains the bounding box properties and it's keyframes indexed by their names + std::map GetBoxValues(int64_t frame_number) const override; + /// Return a map that contains the properties of this object's parent clip + std::map GetParentClipProperties(int64_t frame_number) const override; + + }; } // namespace openshot #endif \ No newline at end of file diff --git a/src/TrackedObjectBase.h b/src/TrackedObjectBase.h index af74e45e..371b056f 100644 --- a/src/TrackedObjectBase.h +++ b/src/TrackedObjectBase.h @@ -47,36 +47,36 @@ namespace openshot { - /** + /** * @brief This abstract class is the base class of all Tracked Objects. * * A Tracked Object is an object or a desired set of pixels in a digital image * which properties (such as position, width and height) can be detected and * predicted along the frames of a clip. */ - class TrackedObjectBase { + class TrackedObjectBase { protected: std::string id; std::string childClipId; ClipBase* parentClip; - public: + public: Keyframe visible; Keyframe draw_box; - /// Default constructor - TrackedObjectBase(); + /// Default constructor + TrackedObjectBase(); /// Constructor which takes an object ID TrackedObjectBase(std::string _id); - /// Get the id of this object + /// Get the id of this object std::string Id() const { return id; } /// Set the id of this object void Id(std::string _id) { id = _id; } - /// Get and set the parentClip of this object + /// 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 @@ -84,23 +84,23 @@ namespace openshot { 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 {}; }; + virtual bool ExactlyContains(int64_t frame_number) const { return {}; }; - /// Scale an object's property - virtual void ScalePoints(double scale) { return; }; + /// Scale an object's property + virtual void ScalePoints(double scale) { return; }; /// Return the main properties of a TrackedObjectBBox instance - such as position, size and rotation virtual std::map GetBoxValues(int64_t frame_number) const { std::map ret; return ret; }; - /// Return the main properties of the tracked object's parent clip - such as position, size and rotation - virtual std::map GetParentClipProperties(int64_t frame_number) const { std::map ret; return ret; } + /// Return the main properties of the tracked object's parent clip - such as position, size and rotation + virtual std::map GetParentClipProperties(int64_t frame_number) const { std::map 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; }; /// Get and Set JSON methods - virtual std::string Json() const = 0; ///< Generate JSON string of this object - virtual Json::Value JsonValue() const = 0; ///< Generate Json::Value for this object - virtual void SetJson(const std::string value) = 0; ///< Load JSON string into this object - virtual void SetJsonValue(const Json::Value root) = 0; ///< Load Json::Value into this object + virtual std::string Json() const = 0; ///< Generate JSON string of this object + virtual Json::Value JsonValue() const = 0; ///< Generate Json::Value for this object + virtual void SetJson(const std::string value) = 0; ///< Load JSON string into this object + virtual void SetJsonValue(const Json::Value root) = 0; ///< Load Json::Value into this object /// Get all properties for a specific frame (perfect for a UI to display the current state /// of all properties at any time) diff --git a/src/effects/ObjectDetection.cpp b/src/effects/ObjectDetection.cpp index dbb00522..9c947e91 100644 --- a/src/effects/ObjectDetection.cpp +++ b/src/effects/ObjectDetection.cpp @@ -39,495 +39,495 @@ using namespace openshot; /// Blank constructor, useful when using Json to load the effect properties ObjectDetection::ObjectDetection(std::string clipObDetectDataPath) { - // Init effect properties - init_effect_details(); + // Init effect properties + init_effect_details(); - // Tries to load the tracker data from protobuf - LoadObjDetectdData(clipObDetectDataPath); + // Tries to load the tracker data from protobuf + LoadObjDetectdData(clipObDetectDataPath); - // Initialize the selected object index as the first object index - selectedObjectIndex = trackedObjects.begin()->first; + // Initialize the selected object index as the first object index + selectedObjectIndex = trackedObjects.begin()->first; } // Default constructor ObjectDetection::ObjectDetection() { - // Init effect properties - init_effect_details(); + // Init effect properties + init_effect_details(); - // Initialize the selected object index as the first object index - selectedObjectIndex = trackedObjects.begin()->first; + // Initialize the selected object index as the first object index + selectedObjectIndex = trackedObjects.begin()->first; } // Init effect settings void ObjectDetection::init_effect_details() { - /// Initialize the values of the EffectInfo struct. - InitEffectInfo(); + /// Initialize the values of the EffectInfo struct. + InitEffectInfo(); - /// Set the effect info - info.class_name = "Object Detector"; - info.name = "Object Detector"; - info.description = "Detect objects through the video."; - info.has_audio = false; - info.has_video = true; - info.has_tracked_object = true; + /// Set the effect info + info.class_name = "Object Detector"; + info.name = "Object Detector"; + info.description = "Detect objects through the video."; + info.has_audio = false; + info.has_video = true; + info.has_tracked_object = true; } // This method is required for all derived classes of EffectBase, and returns a // modified openshot::Frame object std::shared_ptr ObjectDetection::GetFrame(std::shared_ptr frame, int64_t frame_number) { - // Get the frame's image - cv::Mat cv_image = frame->GetImageCV(); + // Get the frame's image + cv::Mat cv_image = frame->GetImageCV(); - // Check if frame isn't NULL - if(cv_image.empty()){ - return frame; - } + // Check if frame isn't NULL + if(cv_image.empty()){ + return frame; + } - // Check if track data exists for the requested frame - if (detectionsData.find(frame_number) != detectionsData.end()) { - float fw = cv_image.size().width; - float fh = cv_image.size().height; + // Check if track data exists for the requested frame + if (detectionsData.find(frame_number) != detectionsData.end()) { + float fw = cv_image.size().width; + float fh = cv_image.size().height; - DetectionData detections = detectionsData[frame_number]; - for(int i = 0; i 0 && - std::find(display_classes.begin(), display_classes.end(), classNames[detections.classIds.at(i)]) == display_classes.end()){ - continue; - } - - // Get the object id - int objectId = detections.objectIds.at(i); + DetectionData detections = detectionsData[frame_number]; + for(int i = 0; i 0 && + std::find(display_classes.begin(), display_classes.end(), classNames[detections.classIds.at(i)]) == display_classes.end()){ + continue; + } + + // Get the object id + int objectId = detections.objectIds.at(i); - // Search for the object in the trackedObjects map - auto trackedObject_it = trackedObjects.find(objectId); + // Search for the object in the trackedObjects map + auto trackedObject_it = trackedObjects.find(objectId); - // Cast the object as TrackedObjectBBox - std::shared_ptr trackedObject = std::static_pointer_cast(trackedObject_it->second); + // Cast the object as TrackedObjectBBox + std::shared_ptr trackedObject = std::static_pointer_cast(trackedObject_it->second); - // Check if the tracked object has data for this frame - if (trackedObject->Contains(frame_number) && - trackedObject->visible.GetValue(frame_number) == 1) - { - // Get the bounding-box of given frame - BBox trackedBox = trackedObject->GetBox(frame_number); - - std::vector stroke_rgba = trackedObject->stroke.GetColorRGBA(frame_number); - int stroke_width = trackedObject->stroke_width.GetValue(frame_number); - float stroke_alpha = trackedObject->stroke_alpha.GetValue(frame_number); - std::vector bg_rgba = trackedObject->background.GetColorRGBA(frame_number); - float bg_alpha = trackedObject->background_alpha.GetValue(frame_number); + // Check if the tracked object has data for this frame + if (trackedObject->Contains(frame_number) && + trackedObject->visible.GetValue(frame_number) == 1) + { + // Get the bounding-box of given frame + BBox trackedBox = trackedObject->GetBox(frame_number); + + std::vector stroke_rgba = trackedObject->stroke.GetColorRGBA(frame_number); + int stroke_width = trackedObject->stroke_width.GetValue(frame_number); + float stroke_alpha = trackedObject->stroke_alpha.GetValue(frame_number); + std::vector bg_rgba = trackedObject->background.GetColorRGBA(frame_number); + float bg_alpha = trackedObject->background_alpha.GetValue(frame_number); - // Create a rotated rectangle object that holds the bounding box - // cv::RotatedRect box ( cv::Point2f( (int)(trackedBox.cx*fw), (int)(trackedBox.cy*fh) ), - // cv::Size2f( (int)(trackedBox.width*fw), (int)(trackedBox.height*fh) ), - // (int) (trackedBox.angle) ); + // Create a rotated rectangle object that holds the bounding box + // cv::RotatedRect box ( cv::Point2f( (int)(trackedBox.cx*fw), (int)(trackedBox.cy*fh) ), + // cv::Size2f( (int)(trackedBox.width*fw), (int)(trackedBox.height*fh) ), + // (int) (trackedBox.angle) ); - // DrawRectangleRGBA(cv_image, box, bg_rgba, bg_alpha, 1, true); - // DrawRectangleRGBA(cv_image, box, stroke_rgba, stroke_alpha, stroke_width, false); - - cv::Rect2d box( - (int)( (trackedBox.cx-trackedBox.width/2)*fw), - (int)( (trackedBox.cy-trackedBox.height/2)*fh), - (int)( trackedBox.width*fw), - (int)( trackedBox.height*fh) - ); - drawPred(detections.classIds.at(i), detections.confidences.at(i), - box, cv_image, detections.objectIds.at(i), bg_rgba, bg_alpha, 1, true); - drawPred(detections.classIds.at(i), detections.confidences.at(i), - box, cv_image, detections.objectIds.at(i), stroke_rgba, stroke_alpha, stroke_width, false); - } - } - } + // DrawRectangleRGBA(cv_image, box, bg_rgba, bg_alpha, 1, true); + // DrawRectangleRGBA(cv_image, box, stroke_rgba, stroke_alpha, stroke_width, false); + + cv::Rect2d box( + (int)( (trackedBox.cx-trackedBox.width/2)*fw), + (int)( (trackedBox.cy-trackedBox.height/2)*fh), + (int)( trackedBox.width*fw), + (int)( trackedBox.height*fh) + ); + drawPred(detections.classIds.at(i), detections.confidences.at(i), + box, cv_image, detections.objectIds.at(i), bg_rgba, bg_alpha, 1, true); + drawPred(detections.classIds.at(i), detections.confidences.at(i), + box, cv_image, detections.objectIds.at(i), stroke_rgba, stroke_alpha, stroke_width, false); + } + } + } - // Update Qt image with new Opencv frame - frame->SetImageCV(cv_image); + // Update Qt image with new Opencv frame + frame->SetImageCV(cv_image); - return frame; + return frame; } void ObjectDetection::DrawRectangleRGBA(cv::Mat &frame_image, cv::RotatedRect box, std::vector color, float alpha, - int thickness, bool is_background){ - // Get the bouding box vertices - cv::Point2f vertices2f[4]; - box.points(vertices2f); + int thickness, bool is_background){ + // Get the bouding box vertices + cv::Point2f vertices2f[4]; + box.points(vertices2f); - // TODO: take a rectangle of frame_image by refencence and draw on top of that to improve speed - // select min enclosing rectangle to draw on a small portion of the image - // cv::Rect rect = box.boundingRect(); - // cv::Mat image = frame_image(rect) + // TODO: take a rectangle of frame_image by refencence and draw on top of that to improve speed + // select min enclosing rectangle to draw on a small portion of the image + // cv::Rect rect = box.boundingRect(); + // cv::Mat image = frame_image(rect) - if(is_background){ - cv::Mat overlayFrame; - frame_image.copyTo(overlayFrame); + if(is_background){ + cv::Mat overlayFrame; + frame_image.copyTo(overlayFrame); - // draw bounding box background - cv::Point vertices[4]; - for(int i = 0; i < 4; ++i){ - vertices[i] = vertices2f[i];} + // draw bounding box background + cv::Point vertices[4]; + for(int i = 0; i < 4; ++i){ + vertices[i] = vertices2f[i];} - cv::Rect rect = box.boundingRect(); - cv::fillConvexPoly(overlayFrame, vertices, 4, cv::Scalar(color[2],color[1],color[0]), cv::LINE_AA); - // add opacity - cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image); - } - else{ - cv::Mat overlayFrame; - frame_image.copyTo(overlayFrame); + cv::Rect rect = box.boundingRect(); + cv::fillConvexPoly(overlayFrame, vertices, 4, cv::Scalar(color[2],color[1],color[0]), cv::LINE_AA); + // add opacity + cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image); + } + else{ + cv::Mat overlayFrame; + frame_image.copyTo(overlayFrame); - // Draw bounding box - for (int i = 0; i < 4; i++) - { - cv::line(overlayFrame, vertices2f[i], vertices2f[(i+1)%4], cv::Scalar(color[2],color[1],color[0]), - thickness, cv::LINE_AA); - } + // Draw bounding box + for (int i = 0; i < 4; i++) + { + cv::line(overlayFrame, vertices2f[i], vertices2f[(i+1)%4], cv::Scalar(color[2],color[1],color[0]), + thickness, cv::LINE_AA); + } - // add opacity - cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image); - } + // add opacity + cv::addWeighted(overlayFrame, 1-alpha, frame_image, alpha, 0, frame_image); + } } void ObjectDetection::drawPred(int classId, float conf, cv::Rect2d box, cv::Mat& frame, int objectNumber, std::vector color, - float alpha, int thickness, bool is_background) + float alpha, int thickness, bool is_background) { - if(is_background){ - cv::Mat overlayFrame; - frame.copyTo(overlayFrame); + if(is_background){ + cv::Mat overlayFrame; + frame.copyTo(overlayFrame); - //Draw a rectangle displaying the bounding box - cv::rectangle(overlayFrame, box, cv::Scalar(color[2],color[1],color[0]), cv::FILLED); + //Draw a rectangle displaying the bounding box + cv::rectangle(overlayFrame, box, cv::Scalar(color[2],color[1],color[0]), cv::FILLED); - // add opacity - cv::addWeighted(overlayFrame, 1-alpha, frame, alpha, 0, frame); - } - else{ - cv::Mat overlayFrame; - frame.copyTo(overlayFrame); + // add opacity + cv::addWeighted(overlayFrame, 1-alpha, frame, alpha, 0, frame); + } + else{ + cv::Mat overlayFrame; + frame.copyTo(overlayFrame); - //Draw a rectangle displaying the bounding box - cv::rectangle(overlayFrame, box, cv::Scalar(color[2],color[1],color[0]), thickness); + //Draw a rectangle displaying the bounding box + cv::rectangle(overlayFrame, box, cv::Scalar(color[2],color[1],color[0]), thickness); - //Get the label for the class name and its confidence - std::string label = cv::format("%.2f", conf); - if (!classNames.empty()) - { - CV_Assert(classId < (int)classNames.size()); - label = classNames[classId] + ":" + label; - } + //Get the label for the class name and its confidence + std::string label = cv::format("%.2f", conf); + if (!classNames.empty()) + { + CV_Assert(classId < (int)classNames.size()); + label = classNames[classId] + ":" + label; + } - //Display the label at the top of the bounding box - int baseLine; - cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + //Display the label at the top of the bounding box + int baseLine; + cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); - double left = box.x; - double top = std::max((int)box.y, labelSize.height); + double left = box.x; + double top = std::max((int)box.y, labelSize.height); - cv::rectangle(overlayFrame, cv::Point(left, top - round(1.025*labelSize.height)), cv::Point(left + round(1.025*labelSize.width), top + baseLine), - cv::Scalar(color[2],color[1],color[0]), cv::FILLED); - putText(overlayFrame, label, cv::Point(left+1, top), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,0,0),1); + cv::rectangle(overlayFrame, cv::Point(left, top - round(1.025*labelSize.height)), cv::Point(left + round(1.025*labelSize.width), top + baseLine), + cv::Scalar(color[2],color[1],color[0]), cv::FILLED); + putText(overlayFrame, label, cv::Point(left+1, top), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,0,0),1); - // add opacity - cv::addWeighted(overlayFrame, 1-alpha, frame, alpha, 0, frame); - } + // add opacity + cv::addWeighted(overlayFrame, 1-alpha, frame, alpha, 0, frame); + } } // Load protobuf data file bool ObjectDetection::LoadObjDetectdData(std::string inputFilePath){ - // Create tracker message - pb_objdetect::ObjDetect objMessage; + // Create tracker message + pb_objdetect::ObjDetect objMessage; - - // Read the existing tracker message. - fstream input(inputFilePath, ios::in | ios::binary); - if (!objMessage.ParseFromIstream(&input)) { - cerr << "Failed to parse protobuf message." << endl; - return false; - } - + + // Read the existing tracker message. + fstream input(inputFilePath, ios::in | ios::binary); + if (!objMessage.ParseFromIstream(&input)) { + cerr << "Failed to parse protobuf message." << endl; + return false; + } + - // Make sure classNames, detectionsData and trackedObjects are empty - classNames.clear(); - detectionsData.clear(); - trackedObjects.clear(); + // Make sure classNames, detectionsData and trackedObjects are empty + classNames.clear(); + detectionsData.clear(); + trackedObjects.clear(); - // Seed to generate same random numbers - std::srand(1); - // Get all classes names and assign a color to them - for(int i = 0; i < objMessage.classnames_size(); i++) - { - classNames.push_back(objMessage.classnames(i)); - classesColor.push_back(cv::Scalar(std::rand()%205 + 50, std::rand()%205 + 50, std::rand()%205 + 50)); - } + // Seed to generate same random numbers + std::srand(1); + // Get all classes names and assign a color to them + for(int i = 0; i < objMessage.classnames_size(); i++) + { + classNames.push_back(objMessage.classnames(i)); + classesColor.push_back(cv::Scalar(std::rand()%205 + 50, std::rand()%205 + 50, std::rand()%205 + 50)); + } - // Iterate over all frames of the saved message - for (size_t i = 0; i < objMessage.frame_size(); i++) - { - // Create protobuf message reader - const pb_objdetect::Frame& pbFrameData = objMessage.frame(i); + // Iterate over all frames of the saved message + for (size_t i = 0; i < objMessage.frame_size(); i++) + { + // Create protobuf message reader + const pb_objdetect::Frame& pbFrameData = objMessage.frame(i); - // Get frame Id - size_t id = pbFrameData.id(); + // Get frame Id + size_t id = pbFrameData.id(); - // Load bounding box data - const google::protobuf::RepeatedPtrField &pBox = pbFrameData.bounding_box(); + // Load bounding box data + const google::protobuf::RepeatedPtrField &pBox = pbFrameData.bounding_box(); - // Construct data vectors related to detections in the current frame - std::vector classIds; - std::vector confidences; - std::vector> boxes; - std::vector objectIds; + // Construct data vectors related to detections in the current frame + std::vector classIds; + std::vector confidences; + std::vector> boxes; + std::vector objectIds; - // Iterate through the detected objects - for(int i = 0; i < pbFrameData.bounding_box_size(); i++) - { - // Get bounding box coordinates - float x = pBox.Get(i).x(); - float y = pBox.Get(i).y(); - float w = pBox.Get(i).w(); - float h = pBox.Get(i).h(); - // Get class Id (which will be assign to a class name) - int classId = pBox.Get(i).classid(); - // Get prediction confidence - float confidence = pBox.Get(i).confidence(); - - // Get the object Id - int objectId = pBox.Get(i).objectid(); + // Iterate through the detected objects + for(int i = 0; i < pbFrameData.bounding_box_size(); i++) + { + // Get bounding box coordinates + float x = pBox.Get(i).x(); + float y = pBox.Get(i).y(); + float w = pBox.Get(i).w(); + float h = pBox.Get(i).h(); + // Get class Id (which will be assign to a class name) + int classId = pBox.Get(i).classid(); + // Get prediction confidence + float confidence = pBox.Get(i).confidence(); + + // Get the object Id + int objectId = pBox.Get(i).objectid(); - // Search for the object id on trackedObjects map - auto trackedObject = trackedObjects.find(objectId); - // Check if object already exists on the map - if (trackedObject != trackedObjects.end()) - { - // Add a new BBox to it - trackedObject->second->AddBox(id, x+(w/2), y+(h/2), w, h, 0.0); - } - else - { - // There is no tracked object with that id, so insert a new one - TrackedObjectBBox trackedObj((int)classesColor[classId](0), (int)classesColor[classId](1), (int)classesColor[classId](2), (int)0); - trackedObj.AddBox(id, x+(w/2), y+(h/2), w, h, 0.0); - std::shared_ptr trackedObjPtr = std::make_shared(trackedObj); - trackedObjects.insert({objectId, trackedObjPtr}); - } + // Search for the object id on trackedObjects map + auto trackedObject = trackedObjects.find(objectId); + // Check if object already exists on the map + if (trackedObject != trackedObjects.end()) + { + // Add a new BBox to it + trackedObject->second->AddBox(id, x+(w/2), y+(h/2), w, h, 0.0); + } + else + { + // There is no tracked object with that id, so insert a new one + TrackedObjectBBox trackedObj((int)classesColor[classId](0), (int)classesColor[classId](1), (int)classesColor[classId](2), (int)0); + trackedObj.AddBox(id, x+(w/2), y+(h/2), w, h, 0.0); + std::shared_ptr trackedObjPtr = std::make_shared(trackedObj); + trackedObjects.insert({objectId, trackedObjPtr}); + } - // Create OpenCV rectangle with the bouding box info - cv::Rect_ box(x, y, w, h); + // Create OpenCV rectangle with the bouding box info + cv::Rect_ box(x, y, w, h); - // Push back data into vectors - boxes.push_back(box); - classIds.push_back(classId); - confidences.push_back(confidence); - objectIds.push_back(objectId); - } + // Push back data into vectors + boxes.push_back(box); + classIds.push_back(classId); + confidences.push_back(confidence); + objectIds.push_back(objectId); + } - // Assign data to object detector map - detectionsData[id] = DetectionData(classIds, confidences, boxes, id, objectIds); - } + // Assign data to object detector map + detectionsData[id] = DetectionData(classIds, confidences, boxes, id, objectIds); + } - // Delete all global objects allocated by libprotobuf. - google::protobuf::ShutdownProtobufLibrary(); + // Delete all global objects allocated by libprotobuf. + google::protobuf::ShutdownProtobufLibrary(); - return true; + return true; } // Get tracker info for the desired frame DetectionData ObjectDetection::GetTrackedData(size_t frameId){ - // Check if the tracker info for the requested frame exists - if ( detectionsData.find(frameId) == detectionsData.end() ) { - return DetectionData(); - } else { - return detectionsData[frameId]; - } + // Check if the tracker info for the requested frame exists + if ( detectionsData.find(frameId) == detectionsData.end() ) { + return DetectionData(); + } else { + return detectionsData[frameId]; + } } // Get the indexes and IDs of all visible objects in the given frame std::string ObjectDetection::GetVisibleObjects(int64_t frame_number) const{ - - // Initialize the JSON objects - Json::Value root; - root["visible_objects_index"] = Json::Value(Json::arrayValue); - root["visible_objects_id"] = Json::Value(Json::arrayValue); + + // Initialize the JSON objects + Json::Value root; + root["visible_objects_index"] = Json::Value(Json::arrayValue); + root["visible_objects_id"] = Json::Value(Json::arrayValue); - // Check if track data exists for the requested frame - if (detectionsData.find(frame_number) == detectionsData.end()){ - return root.toStyledString(); - } - DetectionData detections = detectionsData.at(frame_number); + // Check if track data exists for the requested frame + if (detectionsData.find(frame_number) == detectionsData.end()){ + return root.toStyledString(); + } + DetectionData detections = detectionsData.at(frame_number); - // Iterate through the tracked objects - for(int i = 0; i 0 && - std::find(display_classes.begin(), display_classes.end(), classNames[detections.classIds.at(i)]) == display_classes.end()){ - continue; - } + // Just display selected classes + if( display_classes.size() > 0 && + std::find(display_classes.begin(), display_classes.end(), classNames[detections.classIds.at(i)]) == display_classes.end()){ + continue; + } - int objectId = detections.objectIds.at(i); - // Search for the object in the trackedObjects map - auto trackedObject = trackedObjects.find(objectId); + int objectId = detections.objectIds.at(i); + // Search for the object in the trackedObjects map + auto trackedObject = trackedObjects.find(objectId); - // Get the tracked object JSON properties for this frame - Json::Value trackedObjectJSON = trackedObject->second->PropertiesJSON(frame_number); - - if (trackedObjectJSON["visible"]["value"].asBool() && - trackedObject->second->ExactlyContains(frame_number)){ - // Save the object's index and ID if it's visible in this frame - root["visible_objects_index"].append(trackedObject->first); - root["visible_objects_id"].append(trackedObject->second->Id()); - } - } + // Get the tracked object JSON properties for this frame + Json::Value trackedObjectJSON = trackedObject->second->PropertiesJSON(frame_number); + + if (trackedObjectJSON["visible"]["value"].asBool() && + trackedObject->second->ExactlyContains(frame_number)){ + // Save the object's index and ID if it's visible in this frame + root["visible_objects_index"].append(trackedObject->first); + root["visible_objects_id"].append(trackedObject->second->Id()); + } + } - return root.toStyledString(); + return root.toStyledString(); } // Generate JSON string of this object std::string ObjectDetection::Json() const { - // Return formatted string - return JsonValue().toStyledString(); + // Return formatted string + return JsonValue().toStyledString(); } // Generate Json::Value for this object Json::Value ObjectDetection::JsonValue() const { - // Create root json object - Json::Value root = EffectBase::JsonValue(); // get parent properties - root["type"] = info.class_name; - root["protobuf_data_path"] = protobuf_data_path; - root["selected_object_index"] = selectedObjectIndex; - root["confidence_threshold"] = confidence_threshold; - - // Add tracked object's IDs to root - root["objects_id"] = Json::Value(Json::arrayValue); - for (auto const& trackedObject : trackedObjects){ - Json::Value trackedObjectJSON = trackedObject.second->JsonValue(); - root["objects_id"].append(trackedObject.second->Id()); - } + // Create root json object + Json::Value root = EffectBase::JsonValue(); // get parent properties + root["type"] = info.class_name; + root["protobuf_data_path"] = protobuf_data_path; + root["selected_object_index"] = selectedObjectIndex; + root["confidence_threshold"] = confidence_threshold; + + // Add tracked object's IDs to root + root["objects_id"] = Json::Value(Json::arrayValue); + for (auto const& trackedObject : trackedObjects){ + Json::Value trackedObjectJSON = trackedObject.second->JsonValue(); + root["objects_id"].append(trackedObject.second->Id()); + } - // Add the selected object Json to root - if(trackedObjects.count(selectedObjectIndex) != 0){ - auto selectedObject = trackedObjects.at(selectedObjectIndex); - if (selectedObject){ - Json::Value selectedObjectJSON = selectedObject->JsonValue(); - for (auto const& key : selectedObjectJSON.getMemberNames()) - root[key] = selectedObjectJSON[key]; - } - } + // Add the selected object Json to root + if(trackedObjects.count(selectedObjectIndex) != 0){ + auto selectedObject = trackedObjects.at(selectedObjectIndex); + if (selectedObject){ + Json::Value selectedObjectJSON = selectedObject->JsonValue(); + for (auto const& key : selectedObjectJSON.getMemberNames()) + root[key] = selectedObjectJSON[key]; + } + } - // return JsonValue - return root; + // return JsonValue + return root; } // Load JSON string into this object void ObjectDetection::SetJson(const std::string value) { - // Parse JSON string into JSON objects - try - { - std::cout<<"entrou no objectDetection SetJson \n"<SetJsonValue(trackedObjectJSON); - } - } + // Set the tracked object's ids + if (!root["objects_id"].isNull()){ + for (auto const& trackedObject : trackedObjects){ + Json::Value trackedObjectJSON; + trackedObjectJSON["box_id"] = root["objects_id"][trackedObject.first].asString(); + trackedObject.second->SetJsonValue(trackedObjectJSON); + } + } - // Set the selected object's properties - if(trackedObjects.count(selectedObjectIndex) != 0){ - auto selectedObject = trackedObjects.at(selectedObjectIndex); - if (selectedObject) - selectedObject->SetJsonValue(root); - } + // Set the selected object's properties + if(trackedObjects.count(selectedObjectIndex) != 0){ + auto selectedObject = trackedObjects.at(selectedObjectIndex); + if (selectedObject) + selectedObject->SetJsonValue(root); + } } // Get all properties for a specific frame std::string ObjectDetection::PropertiesJSON(int64_t requested_frame) const { - // Generate JSON properties list - Json::Value root; + // Generate JSON properties list + Json::Value root; - // Add the selected object Json to root - if(trackedObjects.count(selectedObjectIndex) != 0){ - auto selectedObject = trackedObjects.at(selectedObjectIndex); - if (selectedObject) - root = selectedObject->PropertiesJSON(requested_frame); - } + // Add the selected object Json to root + if(trackedObjects.count(selectedObjectIndex) != 0){ + auto selectedObject = trackedObjects.at(selectedObjectIndex); + if (selectedObject) + root = selectedObject->PropertiesJSON(requested_frame); + } - root["selected_object_index"] = add_property_json("Selected Object", selectedObjectIndex, "int", "", NULL, 0, 200, false, requested_frame); - root["id"] = add_property_json("ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame); - root["position"] = add_property_json("Position", Position(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame); - root["layer"] = add_property_json("Track", Layer(), "int", "", NULL, 0, 20, false, requested_frame); - root["start"] = add_property_json("Start", Start(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame); - root["end"] = add_property_json("End", End(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame); - root["duration"] = add_property_json("Duration", Duration(), "float", "", NULL, 0, 1000 * 60 * 30, true, requested_frame); - root["confidence_threshold"] = add_property_json("Confidence Theshold", confidence_threshold, "float", "", NULL, 0, 1, false, requested_frame); - root["class_filter"] = add_property_json("Class Filter", 0.0, "string", class_filter, NULL, -1, -1, false, requested_frame); - // Return formatted string - return root.toStyledString(); + root["selected_object_index"] = add_property_json("Selected Object", selectedObjectIndex, "int", "", NULL, 0, 200, false, requested_frame); + root["id"] = add_property_json("ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame); + root["position"] = add_property_json("Position", Position(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame); + root["layer"] = add_property_json("Track", Layer(), "int", "", NULL, 0, 20, false, requested_frame); + root["start"] = add_property_json("Start", Start(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame); + root["end"] = add_property_json("End", End(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame); + root["duration"] = add_property_json("Duration", Duration(), "float", "", NULL, 0, 1000 * 60 * 30, true, requested_frame); + root["confidence_threshold"] = add_property_json("Confidence Theshold", confidence_threshold, "float", "", NULL, 0, 1, false, requested_frame); + root["class_filter"] = add_property_json("Class Filter", 0.0, "string", class_filter, NULL, -1, -1, false, requested_frame); + // Return formatted string + return root.toStyledString(); }