Draw precise face

This commit is contained in:
Barzan Hayati 2025-08-27 09:20:08 +00:00
parent 6c8624d6cd
commit 51e4265ce8
9 changed files with 1322 additions and 48 deletions

View File

@ -68,6 +68,13 @@
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"valarray": "cpp"
"valarray": "cpp",
"list": "cpp",
"__bit_reference": "cpp",
"bitset": "cpp",
"charconv": "cpp",
"complex": "cpp",
"typeindex": "cpp",
"variant": "cpp"
}
}

View File

@ -0,0 +1,9 @@
#ifndef CUSTOM_GSTNVDSINFER_HPP
#define CUSTOM_GSTNVDSINFER_HPP
#include "gstnvdsinfer.h"
#include "nvbufsurface.h"
#include "nvdsinfer_custom_impl.h"
#include "nvds_obj_encode.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -3,15 +3,24 @@
#include <fstream>
#include <iostream>
#include "config_manager.hpp"
// #include "gstnvdsinfer.h"
// #include "gstnvdsmeta.h"
#include "gstnvdsmeta.h"
#include "nvds_version.h"
// #include "nvdsinfer_custom_impl.h"
#include "nvdsmeta.h"
#include "nvdsmeta_schema.h"
#include "custom_gstnvdsinfer.hpp"
#include "config_manager.hpp"
class FaceNvInferServerManager {
private:
public:
struct FACE_BODY {
int object_id = 0;
float face_score = 0;
};
static std::vector<FACE_BODY> face_body_list;
GstElement *face_detector = NULL;
int face_batch_size;
@ -41,4 +50,17 @@ class FaceNvInferServerManager {
// static void *set_metadata_ptr(float *);
// static gpointer copy_user_meta(gpointer, gpointer);
// static void release_user_meta(gpointer, gpointer);
static GstPadProbeReturn sgie_pad_buffer_probe(GstPad *, GstPadProbeInfo
*,
gpointer);
// static GstPadProbeReturn osd_sink_pad_buffer_probe_new(GstPad *,
// GstPadProbeInfo
// *, gpointer);
static void *set_metadata_ptr(float *);
static gpointer copy_user_meta(gpointer, gpointer);
static void release_user_meta(gpointer, gpointer);
static NvOSD_RectParams * allign_postprocess(NvOSD_RectParams &, float*);
static float numpy_clip(float, float, float);
static void add_face_body(int, float);
};

View File

@ -22,8 +22,9 @@ float NvInferServerManager::threshold_body_detection = 0;
unsigned int NvInferServerManager::nvds_lib_major_version = NVDS_VERSION_MAJOR;
unsigned int NvInferServerManager::nvds_lib_minor_version = NVDS_VERSION_MINOR;
const gchar pgie_class_str[PGIE_DETECTED_CLASS_NUM][32] = {"Person"};
const gchar imprecise_face_str[PGIE_DETECTED_CLASS_NUM][32] = {"ImpreciseFace"};
const gchar pgie_class_str[PGIE_DETECTED_CLASS_NUM][32] = {"Person_NVINFER"};
const gchar imprecise_face_str[PGIE_DETECTED_CLASS_NUM][32] = {
"ImpreciseFace_NVINFER"};
/* nvds_lib_major_version and nvds_lib_minor_version is the version number of
* deepstream sdk */
@ -244,6 +245,7 @@ GstPadProbeReturn NvInferServerManager::pgie_pad_buffer_probe(
}
(void)stream_height;
(void)stream_width;
uint detected_persons = 0;
/* Iterate user metadata in frames to search PGIE's tensor metadata */
for (NvDsMetaList *l_user = frame_meta->frame_user_meta_list;
@ -251,15 +253,46 @@ GstPadProbeReturn NvInferServerManager::pgie_pad_buffer_probe(
NvDsUserMeta *user_meta = (NvDsUserMeta *)l_user->data;
if (user_meta->base_meta.meta_type != NVDSINFER_TENSOR_OUTPUT_META)
continue;
extract_tensor_metadata(user_meta, networkInfo, batch_meta,
frame_meta);
detected_persons = extract_tensor_metadata(user_meta, networkInfo,
batch_meta, frame_meta);
}
NvDsDisplayMeta *display_meta = NULL;
display_meta = nvds_acquire_display_meta_from_pool(batch_meta);
NvOSD_TextParams *txt_params = &display_meta->text_params[0];
display_meta->num_labels = 1;
txt_params->display_text = (gchar *)g_malloc0(MAX_DISPLAY_LEN);
int offset = 0;
offset = snprintf(txt_params->display_text, MAX_DISPLAY_LEN,
"Person_NVInfer = %d ", detected_persons);
(void)offset;
/* Now set the offsets where the string should appear */
txt_params->x_offset = 10;
txt_params->y_offset = 12;
/* Font , font-color and font-size */
txt_params->font_params.font_name = (gchar *)"Serif";
txt_params->font_params.font_size = 10;
txt_params->font_params.font_color.red = 1.0;
txt_params->font_params.font_color.green = 1.0;
txt_params->font_params.font_color.blue = 1.0;
txt_params->font_params.font_color.alpha = 1.0;
/* Text background color */
txt_params->set_bg_clr = 1;
txt_params->text_bg_clr.red = 0.0;
txt_params->text_bg_clr.green = 0.0;
txt_params->text_bg_clr.blue = 0.0;
txt_params->text_bg_clr.alpha = 1.0;
nvds_add_display_meta_to_frame(frame_meta, display_meta);
}
// use_device_mem = 1 - use_device_mem;
return GST_PAD_PROBE_OK;
}
void NvInferServerManager::extract_tensor_metadata(
uint NvInferServerManager::extract_tensor_metadata(
NvDsUserMeta *user_meta, NvDsInferNetworkInfo networkInfo,
NvDsBatchMeta *batch_meta, NvDsFrameMeta *frame_meta) {
/* convert to tensor metadata */
@ -325,6 +358,7 @@ void NvInferServerManager::extract_tensor_metadata(
}
update_frame_with_face_body_meta(detected_persons, batch_meta, data,
frame_meta);
return detected_persons;
}
void NvInferServerManager::update_frame_with_face_body_meta(
@ -395,14 +429,14 @@ void NvInferServerManager::update_frame_with_face_body_meta(
/* Border of width 3. */
rect_params_imprecise_face.border_width = 3;
rect_params_imprecise_face.has_bg_color = 0;
rect_params_imprecise_face.border_color = NvOSD_ColorParams{0, 0, 1, 1};
rect_params_imprecise_face.border_color =
NvOSD_ColorParams{0, 0, 1, 1}; // Blue box
/* display_text requires heap allocated memory. */
text_params_imprecise_face.display_text =
g_strdup(imprecise_face_str[0]); // g_strdup(pgie_class_str[0]);
/* Display text above the left top corner of the object. */
text_params_imprecise_face.x_offset = rect_params_imprecise_face.left;
text_params_imprecise_face.y_offset =
rect_params_imprecise_face.top - 10;
text_params_imprecise_face.y_offset = rect_params_imprecise_face.top;
/* Set black background for the text. */
text_params_imprecise_face.set_bg_clr = 1;
text_params_imprecise_face.text_bg_clr = NvOSD_ColorParams{0, 0, 0, 1};
@ -413,6 +447,7 @@ void NvInferServerManager::update_frame_with_face_body_meta(
NvOSD_ColorParams{1, 1, 1, 1};
// adding landmarks to imprecise_face_obj_meta as user_meta
NvDsUserMeta *um1 = nvds_acquire_user_meta_from_pool(batch_meta);
assert(um1 != NULL);
um1->user_meta_data =
set_metadata_ptr(&(data[index * 57])); // Add landmarks here
um1->base_meta.meta_type =
@ -451,12 +486,15 @@ void NvInferServerManager::update_frame_with_face_body_meta(
/* Border of width 3. */
rect_params_body.border_width = 3;
rect_params_body.has_bg_color = 0;
rect_params_body.border_color = NvOSD_ColorParams{1, 0, 0, 1};
rect_params_body.border_color =
NvOSD_ColorParams{1, 0, 0, 1}; // Red box
/* display_text requires heap allocated memory. */
text_params_body.display_text = g_strdup(pgie_class_str[0]);
// text_params.display_text = g_strdup_printf("ImpreciseFace %lu",
// face_obj->object_id);
/* Display text above the left top corner of the object. */
text_params_body.x_offset = rect_params_body.left - 30;
text_params_body.y_offset = rect_params_body.top - 50;
text_params_body.y_offset = rect_params_body.top - 30;
/* Set black background for the text. */
text_params_body.set_bg_clr = 1;
text_params_body.text_bg_clr = NvOSD_ColorParams{0, 0, 0, 1};

View File

@ -4,10 +4,11 @@
#include <iostream>
#include "config_manager.hpp"
#include "gstnvdsinfer.h"
// #include "gstnvdsinfer.h"
#include "gstnvdsmeta.h"
#include "nvds_version.h"
#include "nvdsinfer_custom_impl.h"
#include "custom_gstnvdsinfer.hpp"
class NvInferServerManager {
private:
@ -49,7 +50,7 @@ class NvInferServerManager {
static void release_user_meta(gpointer, gpointer);
static void update_frame_with_face_body_meta(uint, NvDsBatchMeta *, float *,
NvDsFrameMeta *);
static void extract_tensor_metadata(NvDsUserMeta *, NvDsInferNetworkInfo,
static uint extract_tensor_metadata(NvDsUserMeta *, NvDsInferNetworkInfo,
NvDsBatchMeta *, NvDsFrameMeta *);
static Point2D find_left_down_corner_shoulder(float *, uint);
};

View File

@ -22,7 +22,8 @@ FaceCandidTrace *NvTrackerManager::face_candidate_trace =
new FaceCandidTrace(); // nullptr; // Definition
gint NvTrackerManager::frame_number = 0;
const gchar face_class_str[FACE_DETECTED_CLASS_NUM][32] = {"FACE_TRACKER"};
const gchar face_class_str[FACE_DETECTED_CLASS_NUM][32] = {
"ImpreciseFace_TRACKER"};
NvTrackerManager::NvTrackerManager() {
const auto &config = ConfigManager::get_instance().get_config();
@ -237,7 +238,7 @@ GstPadProbeReturn NvTrackerManager::tracker_src_pad_buffer_probe(
face_obj->rect_params.has_bg_color = 0;
face_obj->rect_params.border_width = 2;
face_obj->rect_params.border_color =
NvOSD_ColorParams{1.0, 0.0, 0.0, 1.0}; // Red box
NvOSD_ColorParams{0.0, 0.0, 1.0, 1.0}; // Blue box
// FaceCandidate *face_candidate = new FaceCandidate();
FaceCandidTrace::FaceCandidate *face_candidate =
@ -253,6 +254,7 @@ GstPadProbeReturn NvTrackerManager::tracker_src_pad_buffer_probe(
user_meta_data); // manager->face_score;
face_obj->confidence = face_candidate->face_score; // 1.0;
face_candidate->object_id = obj_meta->object_id;
face_obj->object_id = obj_meta->object_id;
face_candidate->source_id = frame_meta->source_id;
bool add_status = face_candidate_trace->add(face_candidate);
@ -263,6 +265,26 @@ GstPadProbeReturn NvTrackerManager::tracker_src_pad_buffer_probe(
face_obj->class_id = 41;
}
NvOSD_TextParams &text_params = face_obj->text_params;
NvOSD_RectParams &rect_params = face_obj->rect_params;
/* display_text requires heap allocated memory. */
// Instead of letting OSD auto-generate text, set your own
text_params.display_text = g_strdup_printf(
"ImpreciseFace_Tracker %lu", face_obj->object_id);
// printf("Imprecise Face ID: %lu, Precise Face ID: %lu\n",
// obj_meta->object_id, final_face_obj->object_id);
/* Display text above the left top corner of the object.*/
text_params.x_offset = rect_params.left;
text_params.y_offset = rect_params.top + 30;
/* Set black background for the text. */
text_params.set_bg_clr = 1;
text_params.text_bg_clr = NvOSD_ColorParams{0, 0, 0, 1};
/* Font face, size and color. */
text_params.font_params.font_name = (gchar *)"Serif";
text_params.font_params.font_size = 11;
text_params.font_params.font_color =
NvOSD_ColorParams{1, 1, 1, 1};
// std::cout << "In Tracker sink "
// << " source_id = " << frame_meta->source_id
// << " object_id = " << obj_meta->object_id
@ -373,12 +395,12 @@ GstPadProbeReturn NvTrackerManager::tracker_src_pad_buffer_probe(
display_meta->num_labels = 1;
txt_params->display_text = (gchar *)g_malloc0(MAX_DISPLAY_LEN);
offset = snprintf(txt_params->display_text, MAX_DISPLAY_LEN,
"Person = %d ", person_count);
"Person_TRACKER = %d ", person_count);
(void)offset;
/* Now set the offsets where the string should appear */
txt_params->x_offset = 10;
txt_params->y_offset = 12;
txt_params->y_offset = 52;
/* Font , font-color and font-size */
txt_params->font_params.font_name = (gchar *)"Serif";

View File

@ -393,6 +393,15 @@ bool PipelineManager::create_pipeline_elements(int num_sources,
nv_infer_server_manager->pgie_pad_buffer_probe,
&use_new_mux, NULL);
/* Add probe to get informed of the meta data generated, we add probe to
* the source pad of SGIE's next queue element, since by that time, SGIE's
* buffer would have had got tensor metadata. */
sgie_src_pad = gst_element_get_static_pad(
face_nv_infer_server_manager->face_detector, "src");
gst_pad_add_probe(sgie_src_pad, GST_PAD_PROBE_TYPE_BUFFER,
face_nv_infer_server_manager->sgie_pad_buffer_probe,
&use_new_mux, NULL);
auto start = std::chrono::system_clock::now();
status_playing = playing_pipeline(num_sources, url_camera);
if (status_playing == false) {

View File

@ -71,6 +71,7 @@ class PipelineManager {
const gchar *new_mux_str;
gboolean use_new_mux;
GstPad *pgie_src_pad = NULL;
GstPad *sgie_src_pad = NULL;
static std::chrono::time_point<std::chrono::steady_clock>
last_time_osd_sink;
static std::chrono::time_point<std::chrono::steady_clock>