Save encoded images to disk

This commit is contained in:
Barzan Hayati 2025-09-12 20:20:37 +00:00
parent e90b08bd42
commit 434f3c79ec
7 changed files with 150 additions and 21 deletions

View File

@ -116,6 +116,7 @@ set_source_files_properties(
src/pipeline_manager.cpp
src/nv_tracker_manager.cpp
src/face_nv_infer_server_manager.cpp
src/nv_osd_manager.cpp
PROPERTIES COMPILE_FLAGS "-Wno-missing-field-initializers"
)

View File

@ -66,5 +66,7 @@
"redis_broker_port": 6379,
"topic_redis": "redis_stream"
},
"compression_coefficient": 0.125
"compression_coefficient": 0.125,
"write_full_frame_to_disk": true,
"write_cropped_objects_to_disk": true
}

View File

@ -9,6 +9,7 @@
#define PGIE_CLASS_ID_PERSON 0
#define PGIE_DETECTED_CLASS_NUM 1
#define SGIE_DETECTED_CLASS_NUM 1
#define BODY_COMPONENT_ID 1
#define IMPRECISE_FACE_COMPONENT_ID 2
#define FINAL_FACE_COMPONENT_ID 3
@ -1164,14 +1165,26 @@ void FaceNvInferServerManager::encode_objects_attach_meta(
/* Preset */
// objData.objNum = num_rects;
/* Quality */
objData.quality = 80;
// objData.quality = 80;
/* Set to calculate time taken to encode JPG image. */
// if (calc_enc) {
// objData.calcEncodeTime = 1;
// }
/*Main Function Call */
// bool nvds_obj_enc_process (NvDsObjEncCtxHandle, NvDsObjEncUsrArgs *,
// NvBufSurface *, NvDsObjectMeta *, NvDsFrameMeta *);
nvds_obj_enc_process(static_cast<NvDsObjEncCtxHandle>(ctx), &objData,
ip_surf, obj_meta, frame_meta);
if (obj_meta->unique_component_id == 1) {
std::cout << "obj_meta->unique_component_id = "
<< obj_meta->unique_component_id
<< " obj_meta->rect_params.width = "
<< obj_meta->rect_params.width
<< " obj_meta->rect_params.height = "
<< obj_meta->rect_params.height << std::endl;
std::quick_exit(0);
}
}
void FaceNvInferServerManager::encode_full_frame_attach_meta(
@ -1198,7 +1211,7 @@ void FaceNvInferServerManager::encode_full_frame_attach_meta(
}
// AVX check function
bool FaceNvInferServerManager::allZeroAVX(const float *data, size_t size) {
bool FaceNvInferServerManager::all_zero_avx(const float *data, size_t size) {
size_t i = 0;
__m256 zero = _mm256_setzero_ps(); // 8 floats of 0.0
for (; i + 8 <= size; i += 8) {
@ -1213,7 +1226,7 @@ bool FaceNvInferServerManager::allZeroAVX(const float *data, size_t size) {
return true;
}
bool FaceNvInferServerManager::allZero(const float *data, size_t size) {
bool FaceNvInferServerManager::all_zero(const float *data, size_t size) {
size_t i = 0;
#if defined(__AVX512F__)
@ -1293,12 +1306,34 @@ GstPadProbeReturn FaceNvInferServerManager::sgie_pad_buffer_probe(
for (NvDsMetaList *l_obj = frame_meta->obj_meta_list; l_obj != NULL;
l_obj = l_obj->next) {
NvDsObjectMeta *obj_meta = (NvDsObjectMeta *)l_obj->data;
NvDsObjectMeta *parent = NULL;
if (obj_meta->unique_component_id != 1) {
NvDsObjectMeta *parent = obj_meta->parent;
(void)parent;
if (obj_meta->unique_component_id == 1 &&
obj_meta->obj_user_meta_list != NULL) {
// body object obj_user_meta_list list is empty so
// for loop : Iterate user metadata in object to search SGIE's
// tensor data could not execute.
std::cout << "obj_meta->unique_component_id = "
<< obj_meta->unique_component_id
<< " obj_meta->rect_params.width = "
<< obj_meta->rect_params.width
<< " obj_meta->rect_params.height = "
<< obj_meta->rect_params.height << std::endl;
}
(void)parent;
// if (obj_meta->unique_component_id == 2) {
// body = obj_meta->parent;
// // if(body)
// // {
// // std::cout<<"body->class_id = "<<body->class_id
// // << " body->unique_component_id =
// "<<body->unique_component_id<<std::endl;
// // if (body->unique_component_id==1){
// // std::quick_exit(0);
// // }
// // }
// }
// (void)parent;
// if (obj_meta->unique_component_id !=
// IMPRECISE_FACE_COMPONENT_ID){
// continue;
@ -1331,7 +1366,9 @@ GstPadProbeReturn FaceNvInferServerManager::sgie_pad_buffer_probe(
// // std::cout<<"obj_meta->class_id ="
// <<obj_meta->class_id<<std::endl; continue;
// }
// std::cout<<"obj_meta->class_id = "<<obj_meta->class_id
// << " obj_meta->unique_component_id =
// "<<obj_meta->unique_component_id<<std::endl;
/* Iterate user metadata in object to search SGIE's tensor data */
for (NvDsMetaList *l_user = obj_meta->obj_user_meta_list;
l_user != NULL; l_user = l_user->next) {
@ -1442,7 +1479,7 @@ GstPadProbeReturn FaceNvInferServerManager::sgie_pad_buffer_probe(
0.0f) // if the first element is zero, then its
// possible all element are zero
{
is_zero_embedding_vector = allZero(data_face, 512);
is_zero_embedding_vector = all_zero(data_face, 512);
// is_zero_embedding_vector = 1 where approximately
// 3 times more than is_zero_embedding_vector 0
} else {
@ -1556,8 +1593,6 @@ GstPadProbeReturn FaceNvInferServerManager::sgie_pad_buffer_probe(
// um1->base_meta.release_func =
// (NvDsMetaReleaseFunc)release_user_meta;
// nvds_add_user_meta_to_obj(obj_meta, um1);
nvds_add_obj_meta_to_frame(frame_meta, final_face_obj,
obj_meta);
// nvds_add_obj_meta_to_frame(frame_meta, final_face_obj,
// NULL);
if (is_zero_embedding_vector == false) {
@ -1571,6 +1606,8 @@ GstPadProbeReturn FaceNvInferServerManager::sgie_pad_buffer_probe(
encode_objects_attach_meta(ctx, ip_surf, frame_meta,
final_face_obj);
}
nvds_add_obj_meta_to_frame(frame_meta, final_face_obj,
obj_meta);
}
// for (size_t jkl = 0; jkl < outputLayersInfo.size(); jkl++) {

View File

@ -66,8 +66,8 @@ class FaceNvInferServerManager {
static NvOSD_RectParams *allign_postprocess(NvOSD_RectParams &, float *);
static float numpy_clip(float, float, float);
static void add_face_body(int, float);
static bool allZeroAVX(const float *, size_t);
static bool allZero(const float *, size_t);
static bool all_zero_avx(const float *, size_t);
static bool all_zero(const float *, size_t);
static void encode_full_frame_attach_meta(gpointer, NvBufSurface *,
NvDsFrameMeta *);
static void encode_objects_attach_meta(gpointer, NvBufSurface *,

View File

@ -11,8 +11,16 @@
#define PGIE_CLASS_ID_PERSON 0
gint NvOsdManager::frame_number = 0;
bool NvOsdManager::write_full_frame_to_disk = false;
bool NvOsdManager::write_cropped_objects_to_disk = false;
NvOsdManager::NvOsdManager() {}
NvOsdManager::NvOsdManager() {
const auto &config = ConfigManager::get_instance().get_config();
write_full_frame_to_disk =
config.at("write_full_frame_to_disk").get<bool>();
write_cropped_objects_to_disk =
config.at("write_cropped_objects_to_disk").get<bool>();
}
bool NvOsdManager::create_nv_osd() {
/* Create OSD to draw on the converted RGBA buffer */
@ -30,7 +38,8 @@ bool NvOsdManager::create_nv_osd() {
}
// Attach probe to a pad in the pipeline
void NvOsdManager::attach_probe_to_src_nvosd() {
void NvOsdManager::attach_probe_to_src_nvosd(
NvDsObjEncCtxHandle obj_ctx_handle) {
GstPad *src_pad = gst_element_get_static_pad(nvosd, "src");
if (!src_pad) {
std::cerr << "Unable to get nvosd src pad\n";
@ -38,10 +47,82 @@ void NvOsdManager::attach_probe_to_src_nvosd() {
}
gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER,
osd_src_pad_buffer_probe, NULL, NULL);
osd_src_pad_buffer_probe, (gpointer)obj_ctx_handle, NULL);
gst_object_unref(src_pad);
}
void NvOsdManager::save_full_frame(NvDsFrameMeta *frame_meta) {
char fileFrameNameString[FILE_NAME_SIZE];
const char *osd_string = "OSD";
/* For Demonstration Purposes we are writing metadata to jpeg images of
* the first 10 frames only.
* The files generated have an 'OSD' prefix. */
NvDsUserMetaList *usrMetaList = frame_meta->frame_user_meta_list;
FILE *file;
int stream_num = 0;
while (usrMetaList != NULL) {
NvDsUserMeta *usrMetaData = (NvDsUserMeta *)usrMetaList->data;
// std::cout<<"usrMetaData->base_meta.meta_type frame =
// "<<usrMetaData->base_meta.meta_type<<std::endl;
if (usrMetaData->base_meta.meta_type == NVDS_CROP_IMAGE_META) {
snprintf(fileFrameNameString, FILE_NAME_SIZE, "%s_frame_%d_%d.jpg",
osd_string, frame_number, stream_num++);
NvDsObjEncOutParams *enc_jpeg_image =
(NvDsObjEncOutParams *)usrMetaData->user_meta_data;
/* Write to File */
file = fopen(fileFrameNameString, "wb");
fwrite(enc_jpeg_image->outBuffer, sizeof(uint8_t),
enc_jpeg_image->outLen, file);
fclose(file);
// std::cout<<"fileFrameNameString =
// "<<fileFrameNameString<<std::endl;
}
usrMetaList = usrMetaList->next;
}
}
void NvOsdManager::save_cropped_objects(NvDsFrameMeta *frame_meta,
NvDsObjectMeta *obj_meta,
guint num_rects) {
const char *osd_string = "OSD";
// std::cout<<"obj_meta->unique_component_id =
// "<<obj_meta->unique_component_id<<std::endl;
char fileObjNameString[FILE_NAME_SIZE];
/* For Demonstration Purposes we are writing metadata to jpeg images of
* vehicles or persons for the first 100 frames only.
* The files generated have a 'OSD' prefix. */
// std::cout<<"in obj_meta_list NvOsdManager"<<std::endl;
// std::quick_exit(0);
NvDsUserMetaList *usrMetaList = obj_meta->obj_user_meta_list;
FILE *file;
while (usrMetaList != NULL) {
NvDsUserMeta *usrMetaData = (NvDsUserMeta *)usrMetaList->data;
// std::cout<<"usrMetaData->base_meta.meta_type object =
// "<<usrMetaData->base_meta.meta_type<<std::endl;
if (usrMetaData->base_meta.meta_type == NVDS_CROP_IMAGE_META) {
NvDsObjEncOutParams *enc_jpeg_image =
(NvDsObjEncOutParams *)usrMetaData->user_meta_data;
snprintf(fileObjNameString, FILE_NAME_SIZE, "%s_%d_%d_%d_%s.jpg",
osd_string, frame_number, frame_meta->batch_id, num_rects,
obj_meta->obj_label);
/* Write to File */
file = fopen(fileObjNameString, "wb");
fwrite(enc_jpeg_image->outBuffer, sizeof(uint8_t),
enc_jpeg_image->outLen, file);
fclose(file);
std::cout << "fileObjNameString = " << fileObjNameString
<< " obj_meta->class_id =" << obj_meta->class_id
<< std::endl;
usrMetaList = NULL;
} else {
usrMetaList = usrMetaList->next;
}
}
}
/* This is the buffer probe function that we have registered on the sink pad
* of the OSD element. All the infer elements in the pipeline shall attach
* their metadata to the GstBuffer, here we will iterate & process the metadata
@ -65,6 +146,7 @@ GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_probe(GstPad *pad,
l_frame = l_frame->next) {
NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)(l_frame->data);
int offset = 0;
if (write_full_frame_to_disk == true) save_full_frame(frame_meta);
for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;
l_obj = l_obj->next) {
obj_meta = (NvDsObjectMeta *)(l_obj->data);
@ -80,6 +162,8 @@ GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_probe(GstPad *pad,
// << " Object ID: " << obj_meta->object_id
// << std::endl;
}
if (write_cropped_objects_to_disk == true)
save_cropped_objects(frame_meta, obj_meta, num_rects);
}
display_meta = nvds_acquire_display_meta_from_pool(batch_meta);
NvOSD_TextParams *txt_params = &display_meta->text_params[0];

View File

@ -4,16 +4,19 @@
#include <iostream>
#include "gstnvdsmeta.h"
#include "config_manager.hpp"
#include "custom_gstnvdsinfer.hpp"
class NvOsdManager {
private:
public:
GstElement *nvosd = NULL;
static bool write_full_frame_to_disk, write_cropped_objects_to_disk;
NvOsdManager();
bool create_nv_osd();
~NvOsdManager();
static gint frame_number;
void attach_probe_to_src_nvosd();
void attach_probe_to_src_nvosd(NvDsObjEncCtxHandle);
static GstPadProbeReturn osd_src_pad_buffer_probe(GstPad *,
GstPadProbeInfo *,
gpointer);
@ -21,4 +24,6 @@ class NvOsdManager {
static GstPadProbeReturn osd_sink_pad_buffer_probe(GstPad *,
GstPadProbeInfo *,
gpointer);
static void save_full_frame(NvDsFrameMeta *);
static void save_cropped_objects(NvDsFrameMeta *, NvDsObjectMeta *, guint);
};

View File

@ -623,8 +623,8 @@ bool PipelineManager::create_pipeline_elements(int num_sources,
face_nv_infer_server_manager->create_face_nv_infer_server(num_sources);
nv_osd_manager
->attach_probe_to_src_nvosd(); // nvinfer Or use "nvtracker" if after
nv_osd_manager->attach_probe_to_src_nvosd(
obj_ctx_handle); // nvinfer Or use "nvtracker" if after
message_handling->create_message_handler(pipeline, g_run_forever, loop);
setup_pipeline();