Skip to content

Commit

Permalink
Add new "Display All Boxes" Object Detector property, since it can be…
Browse files Browse the repository at this point in the history
… difficult to turn off each individual box. Made "visible" property read-only on Tracker & Object Detector effects. Improve Keyframe::SetJsonValue method to accept an object or a float.
  • Loading branch information
jonoomph committed Mar 5, 2024
1 parent ffb63f5 commit 5a0a6a6
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 61 deletions.
31 changes: 19 additions & 12 deletions src/KeyFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,18 +374,25 @@ void Keyframe::SetJsonValue(const Json::Value root) {
Points.clear();
Points.shrink_to_fit();

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

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

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

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

// Add Point to Keyframe
AddPoint(p);
}
} else if (root.isNumeric()) {

Check warning on line 389 in src/KeyFrame.cpp

View check run for this annotation

Codecov / codecov/patch

src/KeyFrame.cpp#L389

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

Check warning on line 391 in src/KeyFrame.cpp

View check run for this annotation

Codecov / codecov/patch

src/KeyFrame.cpp#L391

Added line #L391 was not covered by tests

// Add Point to Keyframe
AddPoint(p);

Check warning on line 394 in src/KeyFrame.cpp

View check run for this annotation

Codecov / codecov/patch

src/KeyFrame.cpp#L394

Added line #L394 was not covered by tests
}
}

// Get the change in Y value (from the previous Y value)
Expand Down
4 changes: 1 addition & 3 deletions src/TrackedObjectBBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,7 @@ 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"]["choices"].append(add_property_choice_json("Yes", true, visible.GetValue(requested_frame)));
root["visible"]["choices"].append(add_property_choice_json("No", false, visible.GetValue(requested_frame)));
root["visible"] = add_property_json("Visible", visible.GetValue(requested_frame), "int", "", &visible, 0, 1, true, requested_frame);

Check warning on line 434 in src/TrackedObjectBBox.cpp

View check run for this annotation

Codecov / codecov/patch

src/TrackedObjectBBox.cpp#L434

Added line #L434 was not covered by tests

root["draw_box"] = add_property_json("Draw Box", draw_box.GetValue(requested_frame), "int", "", &draw_box, 0, 1, false, requested_frame);
root["draw_box"]["choices"].append(add_property_choice_json("Yes", true, draw_box.GetValue(requested_frame)));
Expand Down
3 changes: 3 additions & 0 deletions src/TrackedObjectBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ namespace openshot {

public:

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

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

/// Default constructor
Expand Down
99 changes: 54 additions & 45 deletions src/effects/ObjectDetection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ using namespace openshot;


/// Blank constructor, useful when using Json to load the effect properties
ObjectDetection::ObjectDetection(std::string clipObDetectDataPath)
ObjectDetection::ObjectDetection(std::string clipObDetectDataPath) :
display_box_text(1.0), display_boxes(1.0)

Check warning on line 34 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L33-L34

Added lines #L33 - L34 were not covered by tests
{
// Init effect properties
init_effect_details();
Expand All @@ -43,7 +44,8 @@ ObjectDetection::ObjectDetection(std::string clipObDetectDataPath)
}

// Default constructor
ObjectDetection::ObjectDetection()
ObjectDetection::ObjectDetection() :
display_box_text(1.0), display_boxes(1.0)

Check warning on line 48 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L47-L48

Added lines #L47 - L48 were not covered by tests
{
// Init effect properties
init_effect_details();
Expand Down Expand Up @@ -104,55 +106,54 @@ std::shared_ptr<Frame> ObjectDetection::GetFrame(std::shared_ptr<Frame> frame, i
trackedBox.width * frame_image->width(),
trackedBox.height * frame_image->height());

Check warning on line 107 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L101-L107

Added lines #L101 - L107 were not covered by tests

if (trackedObject->draw_box.GetValue(frame_number) == 1) {
// Draw bounding box
bool display_text = display_box_text.GetValue(frame_number);
std::vector<int> stroke_rgba = trackedObject->stroke.GetColorRGBA(frame_number);
std::vector<int> bg_rgba = trackedObject->background.GetColorRGBA(frame_number);
int stroke_width = trackedObject->stroke_width.GetValue(frame_number);
float stroke_alpha = trackedObject->stroke_alpha.GetValue(frame_number);
float bg_alpha = trackedObject->background_alpha.GetValue(frame_number);
float bg_corner = trackedObject->background_corner.GetValue(frame_number);

// Set the pen for the border
QPen pen(QColor(stroke_rgba[0], stroke_rgba[1], stroke_rgba[2], 255 * stroke_alpha));
pen.setWidth(stroke_width);
painter.setPen(pen);

// Set the brush for the background
QBrush brush(QColor(bg_rgba[0], bg_rgba[1], bg_rgba[2], 255 * bg_alpha));
painter.setBrush(brush);

// Draw the rounded rectangle
// Get properties of tracked object (i.e. colors, stroke width, etc...)
std::vector<int> stroke_rgba = trackedObject->stroke.GetColorRGBA(frame_number);
std::vector<int> bg_rgba = trackedObject->background.GetColorRGBA(frame_number);
int stroke_width = trackedObject->stroke_width.GetValue(frame_number);
float stroke_alpha = trackedObject->stroke_alpha.GetValue(frame_number);
float bg_alpha = trackedObject->background_alpha.GetValue(frame_number);
float bg_corner = trackedObject->background_corner.GetValue(frame_number);

Check warning on line 115 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L110-L115

Added lines #L110 - L115 were not covered by tests

// Set the pen for the border
QPen pen(QColor(stroke_rgba[0], stroke_rgba[1], stroke_rgba[2], 255 * stroke_alpha));
pen.setWidth(stroke_width);
painter.setPen(pen);

Check warning on line 120 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L118-L120

Added lines #L118 - L120 were not covered by tests

// Set the brush for the background
QBrush brush(QColor(bg_rgba[0], bg_rgba[1], bg_rgba[2], 255 * bg_alpha));
painter.setBrush(brush);

Check warning on line 124 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L123-L124

Added lines #L123 - L124 were not covered by tests

if (display_boxes.GetValue(frame_number) == 1 && trackedObject->draw_box.GetValue(frame_number) == 1) {

Check warning on line 126 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L126

Added line #L126 was not covered by tests
// Only draw boxes if both properties are set to YES (draw all boxes, and draw box of the selected box)
painter.drawRoundedRect(boxRect, bg_corner, bg_corner);

Check warning on line 128 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L128

Added line #L128 was not covered by tests
}

if(display_text) {
// Draw text label above bounding box
// Get the confidence and classId for the current detection
int classId = detections.classIds.at(i);
if(display_box_text.GetValue(frame_number) == 1) {

Check warning on line 131 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L131

Added line #L131 was not covered by tests
// Draw text label above bounding box
// Get the confidence and classId for the current detection
int classId = detections.classIds.at(i);

Check warning on line 134 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L134

Added line #L134 was not covered by tests

// Get the label for the class name and its confidence
QString label = QString::number(objectId);
if (!classNames.empty()) {
label = QString::fromStdString(classNames[classId]) + ":" + label;
}
// Get the label for the class name and its confidence
QString label = QString::number(objectId);
if (!classNames.empty()) {
label = QString::fromStdString(classNames[classId]) + ":" + label;

Check warning on line 139 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L137-L139

Added lines #L137 - L139 were not covered by tests
}

// Set up the painter, font, and pen
QFont font;
font.setPixelSize(14);
painter.setFont(font);
// Set up the painter, font, and pen
QFont font;
font.setPixelSize(14);
painter.setFont(font);

Check warning on line 145 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L143-L145

Added lines #L143 - L145 were not covered by tests

// Calculate the size of the text
QFontMetrics fontMetrics(font);
QSize labelSize = fontMetrics.size(Qt::TextSingleLine, label);
// Calculate the size of the text
QFontMetrics fontMetrics(font);
QSize labelSize = fontMetrics.size(Qt::TextSingleLine, label);

Check warning on line 149 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L148-L149

Added lines #L148 - L149 were not covered by tests

// Define the top left point of the rectangle
double left = boxRect.center().x() - (labelSize.width() / 2.0);
double top = std::max(static_cast<int>(boxRect.top()), labelSize.height()) - 4.0;
// Define the top left point of the rectangle
double left = boxRect.center().x() - (labelSize.width() / 2.0);
double top = std::max(static_cast<int>(boxRect.top()), labelSize.height()) - 4.0;

Check warning on line 153 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L152-L153

Added lines #L152 - L153 were not covered by tests

// Draw the text
painter.drawText(QPointF(left, top), label);
}
// Draw the text
painter.drawText(QPointF(left, top), label);
}
}
}

Check warning on line 159 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L156-L159

Added lines #L156 - L159 were not covered by tests
Expand Down Expand Up @@ -343,6 +344,7 @@ Json::Value ObjectDetection::JsonValue() const {
root["selected_object_index"] = selectedObjectIndex;
root["confidence_threshold"] = confidence_threshold;
root["display_box_text"] = display_box_text.JsonValue();
root["display_boxes"] = display_boxes.JsonValue();

Check warning on line 347 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L347

Added line #L347 was not covered by tests

// Add tracked object's IDs to root
Json::Value objects;
Expand Down Expand Up @@ -399,6 +401,9 @@ void ObjectDetection::SetJsonValue(const Json::Value root) {
if (!root["display_box_text"].isNull())
display_box_text.SetJsonValue(root["display_box_text"]);

if (!root["display_boxes"].isNull())
display_boxes.SetJsonValue(root["display_boxes"]);

Check warning on line 405 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L404-L405

Added lines #L404 - L405 were not covered by tests

if (!root["class_filter"].isNull()) {
class_filter = root["class_filter"].asString();

Check warning on line 408 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L407-L408

Added lines #L407 - L408 were not covered by tests

Expand Down Expand Up @@ -458,10 +463,14 @@ std::string ObjectDetection::PropertiesJSON(int64_t requested_frame) const {
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);

root["display_box_text"] = add_property_json("Draw Box Text", display_box_text.GetValue(requested_frame), "int", "", &display_box_text, 0, 1, false, requested_frame);
root["display_box_text"] = add_property_json("Draw All Text", display_box_text.GetValue(requested_frame), "int", "", &display_box_text, 0, 1, false, requested_frame);
root["display_box_text"]["choices"].append(add_property_choice_json("Yes", true, display_box_text.GetValue(requested_frame)));
root["display_box_text"]["choices"].append(add_property_choice_json("No", false, display_box_text.GetValue(requested_frame)));

Check warning on line 468 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L466-L468

Added lines #L466 - L468 were not covered by tests

root["display_boxes"] = add_property_json("Draw All Boxes", display_boxes.GetValue(requested_frame), "int", "", &display_boxes, 0, 1, false, requested_frame);
root["display_boxes"]["choices"].append(add_property_choice_json("Yes", true, display_boxes.GetValue(requested_frame)));
root["display_boxes"]["choices"].append(add_property_choice_json("No", false, display_boxes.GetValue(requested_frame)));

Check warning on line 472 in src/effects/ObjectDetection.cpp

View check run for this annotation

Codecov / codecov/patch

src/effects/ObjectDetection.cpp#L470-L472

Added lines #L470 - L472 were not covered by tests

// Return formatted string
return root.toStyledString();
}
7 changes: 6 additions & 1 deletion src/effects/ObjectDetection.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ namespace openshot
std::vector<std::string> classNames;
std::vector<cv::Scalar> classesColor;

/// Draw class name and confidence score on top of the bounding box
/// Draw ALL class name and ID #'s on top of the bounding boxes (or hide all text)
Keyframe display_box_text;

/// Draw ALL tracked bounding boxes (or hide all boxes)
Keyframe display_boxes;

/// Minimum confidence value to display the detected objects
float confidence_threshold = 0.5;

/// Contain the user selected classes for visualization
std::vector<std::string> display_classes;
std::string class_filter;
Expand Down

0 comments on commit 5a0a6a6

Please sign in to comment.