Added support to show the transform handler for the selected object

When using the ObjectDetection effect, it's now possible to select one detected object and update it's properties through it's transform handler.
This commit is contained in:
Brenno
2021-01-27 16:52:15 -03:00
parent ce2c4e0198
commit 4a28654bcc
4 changed files with 103 additions and 54 deletions

View File

@@ -290,7 +290,8 @@ std::list<std::string> Timeline::GetTrackedObjectsIds() const{
return trackedObjects_ids;
}
std::string Timeline::GetTrackedObjectValues(std::string id) const {
// Return the trackedObject's properties as a JSON string
std::string Timeline::GetTrackedObjectValues(std::string id, int64_t frame_number) const {
// Initialize the JSON object
Json::Value trackedObjectJson;
@@ -304,19 +305,34 @@ std::string Timeline::GetTrackedObjectValues(std::string id) const {
std::shared_ptr<TrackedObjectBBox> trackedObject = std::static_pointer_cast<TrackedObjectBBox>(iterator->second);
// Get the trackedObject values for it's first frame
auto boxes = trackedObject->BoxVec;
auto firstBox = boxes.begin()->second;
float x1 = firstBox.cx - (firstBox.width/2);
float y1 = firstBox.cy - (firstBox.height/2);
float x2 = firstBox.cx + (firstBox.width/2);
float y2 = firstBox.cy + (firstBox.height/2);
float r = firstBox.angle;
if (trackedObject->ExactlyContains(frame_number)){
BBox box = trackedObject->GetBox(frame_number);
float x1 = box.cx - (box.width/2);
float y1 = box.cy - (box.height/2);
float x2 = box.cx + (box.width/2);
float y2 = box.cy + (box.height/2);
float rotation = box.angle;
trackedObjectJson["x1"] = x1;
trackedObjectJson["y1"] = y1;
trackedObjectJson["x2"] = x2;
trackedObjectJson["y2"] = y2;
trackedObjectJson["r"] = r;
trackedObjectJson["x1"] = x1;
trackedObjectJson["y1"] = y1;
trackedObjectJson["x2"] = x2;
trackedObjectJson["y2"] = y2;
trackedObjectJson["rotation"] = rotation;
} else {
BBox box = trackedObject->BoxVec.begin()->second;
float x1 = box.cx - (box.width/2);
float y1 = box.cy - (box.height/2);
float x2 = box.cx + (box.width/2);
float y2 = box.cy + (box.height/2);
float rotation = box.angle;
trackedObjectJson["x1"] = x1;
trackedObjectJson["y1"] = y1;
trackedObjectJson["x2"] = x2;
trackedObjectJson["y2"] = y2;
trackedObjectJson["rotation"] = rotation;
}
}
else {
@@ -325,7 +341,7 @@ std::string Timeline::GetTrackedObjectValues(std::string id) const {
trackedObjectJson["y1"] = 0;
trackedObjectJson["x2"] = 0;
trackedObjectJson["y2"] = 0;
trackedObjectJson["r"] = 0;
trackedObjectJson["rotation"] = 0;
}
return trackedObjectJson.toStyledString();

View File

@@ -250,8 +250,8 @@ namespace openshot {
std::shared_ptr<openshot::TrackedObjectBase> GetTrackedObject(std::string id) const;
/// Return the ID's of the tracked objects as a list of strings
std::list<std::string> GetTrackedObjectsIds() const;
/// Return the first trackedObject's properties as a JSON string
std::string GetTrackedObjectValues(std::string id) const;
/// Return the trackedObject's properties as a JSON string
std::string GetTrackedObjectValues(std::string id, int64_t frame_number) const;
/// @brief Add an openshot::Clip to the timeline
/// @param clip Add an openshot::Clip to the timeline. A clip can contain any type of Reader.

View File

@@ -45,6 +45,9 @@ ObjectDetection::ObjectDetection(std::string 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;
}
// Default constructor
@@ -53,6 +56,8 @@ ObjectDetection::ObjectDetection()
// Init effect properties
init_effect_details();
// Initialize the selected object index as the first object index
selectedObjectIndex = trackedObjects.begin()->first;
}
// Init effect settings
@@ -273,18 +278,23 @@ Json::Value ObjectDetection::JsonValue() const {
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;
// Add trackedObjects IDs to JSON
for (auto const& trackedObject : trackedObjects){
Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
// Save the trackedObject JSON on root
for (auto const& trackedObject : trackedObjects){
Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
root["box_id-"+to_string(trackedObject.first)] = trackedObjectJSON["box_id"];
root["delta_x-"+to_string(trackedObject.first)] = trackedObjectJSON["delta_x"];
root["delta_y-"+to_string(trackedObject.first)] = trackedObjectJSON["delta_y"];
root["scale_x-"+to_string(trackedObject.first)] = trackedObjectJSON["scale_x"];
root["scale_y-"+to_string(trackedObject.first)] = trackedObjectJSON["scale_y"];
root["rotation-"+to_string(trackedObject.first)] = trackedObjectJSON["rotation"];
}
}
// Add the selected object Json to root
auto selectedObject = trackedObjects.at(selectedObjectIndex);
if (selectedObject){
Json::Value selectedObjectJSON = selectedObject->JsonValue();
root["delta_x-"+to_string(selectedObjectIndex)] = selectedObjectJSON["delta_x"];
root["delta_y-"+to_string(selectedObjectIndex)] = selectedObjectJSON["delta_y"];
root["scale_x-"+to_string(selectedObjectIndex)] = selectedObjectJSON["scale_x"];
root["scale_y-"+to_string(selectedObjectIndex)] = selectedObjectJSON["scale_y"];
root["rotation-"+to_string(selectedObjectIndex)] = selectedObjectJSON["rotation"];
}
// return JsonValue
return root;
@@ -322,17 +332,31 @@ void ObjectDetection::SetJsonValue(const Json::Value root) {
}
}
// Set the selected object index
if (!root["selected_object_index"].isNull())
selectedObjectIndex = root["selected_object_index"].asInt();
for (auto const& trackedObject : trackedObjects){
Json::Value trackedObjectJSON;
trackedObjectJSON["box_id"] = root["box_id-"+to_string(trackedObject.first)];
trackedObjectJSON["delta_x"] = root["delta_x-"+to_string(trackedObject.first)];
trackedObjectJSON["delta_y"] = root["delta_y-"+to_string(trackedObject.first)];
trackedObjectJSON["scale_x"] = root["scale_x-"+to_string(trackedObject.first)];
trackedObjectJSON["scale_y"] = root["scale_y-"+to_string(trackedObject.first)];
trackedObjectJSON["rotation"] = root["rotation-"+to_string(trackedObject.first)];
if (!trackedObjectJSON.isNull())
trackedObject.second->SetJsonValue(trackedObjectJSON);
}
trackedObject.second->SetJsonValue(trackedObjectJSON);
}
// Set the selectec object's properties
if (!root["box_id-"+to_string(selectedObjectIndex)].isNull()){
Json::Value selectedObjectJSON;
selectedObjectJSON["box_id"] = root["box_id-"+to_string(selectedObjectIndex)];
selectedObjectJSON["delta_x"] = root["delta_x-"+to_string(selectedObjectIndex)];
selectedObjectJSON["delta_y"] = root["delta_y-"+to_string(selectedObjectIndex)];
selectedObjectJSON["scale_x"] = root["scale_x-"+to_string(selectedObjectIndex)];
selectedObjectJSON["scale_y"] = root["scale_y-"+to_string(selectedObjectIndex)];
selectedObjectJSON["rotation"] = root["rotation-"+to_string(selectedObjectIndex)];
if (!selectedObjectJSON.isNull()){
auto selectedObject = trackedObjects.at(selectedObjectIndex);
if (selectedObject)
selectedObject->SetJsonValue(selectedObjectJSON);
}
}
}
// Get all properties for a specific frame
@@ -341,27 +365,33 @@ std::string ObjectDetection::PropertiesJSON(int64_t requested_frame) const {
// Generate JSON properties list
Json::Value root;
// Add trackedObjects IDs to JSON
for (auto const& trackedObject : trackedObjects){
// Save the trackedObject Id on root
Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(requested_frame);
root["box_id-"+to_string(trackedObject.first)] = trackedObjectJSON["box_id"];
root["visible-"+to_string(trackedObject.first)] = trackedObjectJSON["visible"];
// Add trackedObject's properties only if it's visible in this frame (performance boost)
if (trackedObjectJSON["visible"]["value"].asBool()){
root["x1-"+to_string(trackedObject.first)] = trackedObjectJSON["x1"];
root["y1-"+to_string(trackedObject.first)] = trackedObjectJSON["y1"];
root["x2-"+to_string(trackedObject.first)] = trackedObjectJSON["x2"];
root["y2-"+to_string(trackedObject.first)] = trackedObjectJSON["y2"];
root["delta_x-"+to_string(trackedObject.first)] = trackedObjectJSON["delta_x"];
root["delta_y-"+to_string(trackedObject.first)] = trackedObjectJSON["delta_y"];
root["scale_x-"+to_string(trackedObject.first)] = trackedObjectJSON["scale_x"];
root["scale_y-"+to_string(trackedObject.first)] = trackedObjectJSON["scale_y"];
root["rotation-"+to_string(trackedObject.first)] = trackedObjectJSON["rotation"];
}
}
// root["visible_objects"] = Json::Value(Json::arrayValue);
for (auto const& trackedObject : trackedObjects){
Json::Value trackedObjectJSON = trackedObject.second->PropertiesJSON(requested_frame);
root["visible-"+to_string(trackedObject.first)] = trackedObjectJSON["visible"];
if (trackedObjectJSON["visible"]["value"].asBool())
root["box_id-"+to_string(trackedObject.first)] = trackedObjectJSON["box_id"];
}
// Add the selected object Json to root
auto selectedObject = trackedObjects.at(selectedObjectIndex);
if (selectedObject){
Json::Value selectedObjectJSON = selectedObject->PropertiesJSON(requested_frame);
root["box_id-"+to_string(selectedObjectIndex)] = selectedObjectJSON["box_id"];
root["visible-"+to_string(selectedObjectIndex)] = selectedObjectJSON["visible"];
root["x1-"+to_string(selectedObjectIndex)] = selectedObjectJSON["x1"];
root["y1-"+to_string(selectedObjectIndex)] = selectedObjectJSON["y1"];
root["x2-"+to_string(selectedObjectIndex)] = selectedObjectJSON["x2"];
root["y2-"+to_string(selectedObjectIndex)] = selectedObjectJSON["y2"];
root["delta_x-"+to_string(selectedObjectIndex)] = selectedObjectJSON["delta_x"];
root["delta_y-"+to_string(selectedObjectIndex)] = selectedObjectJSON["delta_y"];
root["scale_x-"+to_string(selectedObjectIndex)] = selectedObjectJSON["scale_x"];
root["scale_y-"+to_string(selectedObjectIndex)] = selectedObjectJSON["scale_y"];
root["rotation-"+to_string(selectedObjectIndex)] = selectedObjectJSON["rotation"];
}
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);

View File

@@ -86,6 +86,9 @@ namespace openshot
public:
/// Index of the Tracked Object that was selected to modify it's properties
int selectedObjectIndex;
/// Blank constructor, useful when using Json to load the effect properties
ObjectDetection(std::string clipTrackerDataPath);