22 #include "objdetectdata.pb.h"
28 #include <QStringList>
34 ObjectDetection::ObjectDetection()
35 : display_box_text(1.0)
39 init_effect_details();
46 void ObjectDetection::init_effect_details()
64 std::shared_ptr<QImage> frame_image = frame->GetImage();
67 if(!frame_image || frame_image->isNull()) {
71 QPainter painter(frame_image.get());
72 painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
74 if (detectionsData.find(frame_number) != detectionsData.end()) {
76 for (
int i = 0; i < detections.
boxes.size(); i++) {
77 if (detections.
confidences.at(i) < confidence_threshold ||
78 (!display_classes.empty() &&
79 std::find(display_classes.begin(), display_classes.end(), classNames[detections.
classIds.at(i)]) == display_classes.end())) {
83 int objectId = detections.
objectIds.at(i);
87 std::shared_ptr<TrackedObjectBBox> trackedObject = std::static_pointer_cast<TrackedObjectBBox>(trackedObject_it->second);
90 if (parentClip && trackedObject->Contains(frame_number) && trackedObject->visible.GetValue(frame_number) == 1) {
91 BBox trackedBox = trackedObject->GetBox(frame_number);
92 QRectF boxRect((trackedBox.
cx - trackedBox.
width / 2) * frame_image->width(),
93 (trackedBox.
cy - trackedBox.
height / 2) * frame_image->height(),
94 trackedBox.
width * frame_image->width(),
95 trackedBox.
height * frame_image->height());
98 std::vector<int> stroke_rgba = trackedObject->stroke.GetColorRGBA(frame_number);
99 std::vector<int> bg_rgba = trackedObject->background.GetColorRGBA(frame_number);
100 int stroke_width = trackedObject->stroke_width.GetValue(frame_number);
101 float stroke_alpha = trackedObject->stroke_alpha.GetValue(frame_number);
102 float bg_alpha = trackedObject->background_alpha.GetValue(frame_number);
103 float bg_corner = trackedObject->background_corner.GetValue(frame_number);
106 QPen pen(QColor(stroke_rgba[0], stroke_rgba[1], stroke_rgba[2], 255 * stroke_alpha));
107 pen.setWidth(stroke_width);
111 QBrush brush(QColor(bg_rgba[0], bg_rgba[1], bg_rgba[2], 255 * bg_alpha));
112 painter.setBrush(brush);
114 if (display_boxes.
GetValue(frame_number) == 1 && trackedObject->draw_box.GetValue(frame_number) == 1) {
116 painter.drawRoundedRect(boxRect, bg_corner, bg_corner);
119 if(display_box_text.
GetValue(frame_number) == 1) {
122 int classId = detections.
classIds.at(i);
125 QString label = QString::number(objectId);
126 if (!classNames.empty()) {
127 label = QString::fromStdString(classNames[classId]) +
":" + label;
132 font.setPixelSize(14);
133 painter.setFont(font);
136 QFontMetrics fontMetrics(font);
137 QSize labelSize = fontMetrics.size(Qt::TextSingleLine, label);
140 double left = boxRect.center().x() - (labelSize.width() / 2.0);
141 double top = std::max(
static_cast<int>(boxRect.top()), labelSize.height()) - 4.0;
144 painter.drawText(QPointF(left, top), label);
161 pb_objdetect::ObjDetect objMessage;
162 std::fstream input(inputFilePath, std::ios::in | std::ios::binary);
163 if (!objMessage.ParseFromIstream(&input)) {
164 std::cerr <<
"Failed to parse protobuf message." << std::endl;
170 detectionsData.clear();
175 for (
int i = 0; i < objMessage.classnames_size(); ++i) {
176 classNames.push_back(objMessage.classnames(i));
177 classesColor.push_back(cv::Scalar(
178 std::rand() % 205 + 50,
179 std::rand() % 205 + 50,
180 std::rand() % 205 + 50
185 for (
size_t fi = 0; fi < objMessage.frame_size(); ++fi) {
186 const auto &pbFrame = objMessage.frame(fi);
187 size_t frameId = pbFrame.id();
190 std::vector<int> classIds;
191 std::vector<float> confidences;
192 std::vector<cv::Rect_<float>> boxes;
193 std::vector<int> objectIds;
196 for (
int di = 0; di < pbFrame.bounding_box_size(); ++di) {
197 const auto &b = pbFrame.bounding_box(di);
198 float x = b.x(), y = b.y(), w = b.w(), h = b.h();
199 int classId = b.classid();
200 float confidence= b.confidence();
201 int objectId = b.objectid();
204 classIds.push_back(classId);
205 confidences.push_back(confidence);
206 boxes.emplace_back(x, y, w, h);
207 objectIds.push_back(objectId);
212 it->second->AddBox(frameId, x + w/2, y + h/2, w, h, 0.0);
217 (
int)classesColor[classId][0],
218 (
int)classesColor[classId][1],
219 (
int)classesColor[classId][2],
223 tmpObj.
AddBox(frameId, x + w/2, y + h/2, w, h, 0.0);
225 auto ptr = std::make_shared<TrackedObjectBBox>(tmpObj);
229 std::string prefix = this->
Id();
232 ptr->Id(prefix + std::to_string(objectId));
239 classIds, confidences, boxes, frameId, objectIds
243 google::protobuf::ShutdownProtobufLibrary();
258 root[
"visible_objects_index"] = Json::Value(Json::arrayValue);
259 root[
"visible_objects_id"] = Json::Value(Json::arrayValue);
260 root[
"visible_class_names"] = Json::Value(Json::arrayValue);
263 if (detectionsData.find(frame_number) == detectionsData.end()){
264 return root.toStyledString();
269 for(
int i = 0; i<detections.
boxes.size(); i++){
271 if(detections.
confidences.at(i) < confidence_threshold){
276 auto className = classNames[detections.
classIds.at(i)];
279 if (!display_classes.empty()) {
280 auto it = std::find(display_classes.begin(), display_classes.end(), className);
281 if (it == display_classes.end()) {
285 root[
"visible_class_names"].append(className);
288 root[
"visible_class_names"].append(className);
291 int objectId = detections.
objectIds.at(i);
296 Json::Value trackedObjectJSON = trackedObject->second->PropertiesJSON(frame_number);
298 if (trackedObjectJSON[
"visible"][
"value"].asBool() &&
299 trackedObject->second->ExactlyContains(frame_number)){
301 root[
"visible_objects_index"].append(trackedObject->first);
302 root[
"visible_objects_id"].append(trackedObject->second->Id());
306 return root.toStyledString();
322 root[
"protobuf_data_path"] = protobuf_data_path;
324 root[
"confidence_threshold"] = confidence_threshold;
325 root[
"display_box_text"] = display_box_text.
JsonValue();
326 root[
"display_boxes"] = display_boxes.
JsonValue();
331 Json::Value trackedObjectJSON = trackedObject.second->JsonValue();
333 objects[trackedObject.second->Id()] = trackedObjectJSON;
335 root[
"objects"] = objects;
351 catch (
const std::exception& e)
354 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
365 if (!root[
"protobuf_data_path"].isNull()) {
366 std::string new_path = root[
"protobuf_data_path"].asString();
368 protobuf_data_path = new_path;
370 throw InvalidFile(
"Invalid protobuf data path",
"");
376 if (!root[
"selected_object_index"].isNull())
378 if (!root[
"confidence_threshold"].isNull())
379 confidence_threshold = root[
"confidence_threshold"].asFloat();
380 if (!root[
"display_box_text"].isNull())
381 display_box_text.
SetJsonValue(root[
"display_box_text"]);
382 if (!root[
"display_boxes"].isNull())
385 if (!root[
"class_filter"].isNull()) {
386 class_filter = root[
"class_filter"].asString();
387 QStringList parts = QString::fromStdString(class_filter).split(
',');
388 display_classes.clear();
389 for (
auto &p : parts) {
390 auto s = p.trimmed().toLower();
392 display_classes.push_back(s.toStdString());
398 if (!root[
"objects"].isNull()) {
400 const auto memberNames = root[
"objects"].getMemberNames();
401 for (
const auto& name : memberNames)
405 bool numeric_key = std::all_of(name.begin(), name.end(), ::isdigit);
407 index = std::stoi(name);
411 size_t pos = name.find_last_of(
'-');
412 if (pos != std::string::npos) {
414 index = std::stoi(name.substr(pos + 1));
425 obj_it->second->Id(name);
426 obj_it->second->SetJsonValue(root[
"objects"][name]);
431 if (!root[
"objects_id"].isNull()) {
433 if (!root[
"objects_id"][kv.first].isNull())
434 kv.second->Id(root[
"objects_id"][kv.first].asString());
449 Json::Value trackedObjectJSON = selectedObject->PropertiesJSON(requested_frame);
451 objects[selectedObject->Id()] = trackedObjectJSON;
454 root[
"objects"] = objects;
457 root[
"confidence_threshold"] =
add_property_json(
"Confidence Theshold", confidence_threshold,
"float",
"", NULL, 0, 1,
false, requested_frame);
458 root[
"class_filter"] =
add_property_json(
"Class Filter", 0.0,
"string", class_filter, NULL, -1, -1,
false, requested_frame);
460 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);
464 root[
"display_boxes"] =
add_property_json(
"Draw All Boxes", display_boxes.
GetValue(requested_frame),
"int",
"", &display_boxes, 0, 1,
false, requested_frame);
469 return root.toStyledString();