def osd_sink_pad_buffer_probe(pad, info, u_data): frame_number = 0 #Intiallizing object counter with 0. obj_counter = { PGIE_CLASS_ID_VEHICLE: 0, PGIE_CLASS_ID_PERSON: 0, PGIE_CLASS_ID_BICYCLE: 0, PGIE_CLASS_ID_ROADSIGN: 0 } is_first_object = True gst_buffer = info.get_buffer() if not gst_buffer: print("Unable to get GstBuffer ") return # Retrieve batch metadata from the gst_buffer # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the # C address of gst_buffer as input, which is obtained with hash(gst_buffer) batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer)) if not batch_meta: return Gst.PadProbeReturn.OK l_frame = batch_meta.frame_meta_list while l_frame is not None: try: # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta # The casting is done by pyds.glist_get_nvds_frame_meta() # The casting also keeps ownership of the underlying memory # in the C code, so the Python garbage collector will leave # it alone. frame_meta = pyds.glist_get_nvds_frame_meta(l_frame.data) except StopIteration: continue is_first_object = True ''' print("Frame Number is ", frame_meta.frame_num) print("Source id is ", frame_meta.source_id) print("Batch id is ", frame_meta.batch_id) print("Source Frame Width ", frame_meta.source_frame_width) print("Source Frame Height ", frame_meta.source_frame_height) print("Num object meta ", frame_meta.num_obj_meta) ''' frame_number = frame_meta.frame_num l_obj = frame_meta.obj_meta_list while l_obj is not None: try: obj_meta = pyds.glist_get_nvds_object_meta(l_obj.data) except StopIteration: continue # Update the object text display txt_params = obj_meta.text_params if (txt_params.display_text): pyds.free_buffer(txt_params.display_text) txt_params.display_text = pgie_classes_str[obj_meta.class_id] obj_counter[obj_meta.class_id] += 1 # Font , font-color and font-size txt_params.font_params.font_name = "Serif" txt_params.font_params.font_size = 10 # set(red, green, blue, alpha); set to White txt_params.font_params.font_color.set(1.0, 1.0, 1.0, 1.0) # Text background color txt_params.set_bg_clr = 1 # set(red, green, blue, alpha); set to Black txt_params.text_bg_clr.set(0.0, 0.0, 0.0, 1.0) # Ideally NVDS_EVENT_MSG_META should be attached to buffer by the # component implementing detection / recognition logic. # Here it demonstrates how to use / attach that meta data. if (is_first_object and not (frame_number % 30)): # Frequency of messages to be send will be based on use case. # Here message is being sent for first object every 30 frames. # Allocating an NvDsEventMsgMeta instance and getting reference # to it. The underlying memory is not manged by Python so that # downstream plugins can access it. Otherwise the garbage collector # will free it when this probe exits. msg_meta = pyds.alloc_nvds_event_msg_meta() msg_meta.bbox.top = obj_meta.rect_params.top msg_meta.bbox.left = obj_meta.rect_params.left msg_meta.bbox.width = obj_meta.rect_params.width msg_meta.bbox.height = obj_meta.rect_params.height msg_meta.frameId = frame_number msg_meta.trackingId = long_to_int(obj_meta.object_id) msg_meta.confidence = obj_meta.confidence msg_meta = generate_event_msg_meta(msg_meta, obj_meta.class_id) user_event_meta = pyds.nvds_acquire_user_meta_from_pool( batch_meta) if (user_event_meta): user_event_meta.user_meta_data = msg_meta user_event_meta.base_meta.meta_type = pyds.NvDsMetaType.NVDS_EVENT_MSG_META # Setting callbacks in the event msg meta. The bindings layer # will wrap these callables in C functions. Currently only one # set of callbacks is supported. pyds.set_user_copyfunc(user_event_meta, meta_copy_func) pyds.set_user_releasefunc(user_event_meta, meta_free_func) pyds.nvds_add_user_meta_to_frame(frame_meta, user_event_meta) else: print("Error in attaching event meta to buffer\n") is_first_object = False try: l_obj = l_obj.next except StopIteration: break try: l_frame = l_frame.next except StopIteration: break print("Frame Number =", frame_number, "Vehicle Count =", obj_counter[PGIE_CLASS_ID_VEHICLE], "Person Count =", obj_counter[PGIE_CLASS_ID_PERSON]) return Gst.PadProbeReturn.OK
def osd_sink_pad_buffer_probe(pad, info, u_data): frame_number = 0 obj_counter = { PGIE_CLASS_ID_VEHICLE: 0, PGIE_CLASS_ID_PERSON: 0, PGIE_CLASS_ID_BICYCLE: 0, PGIE_CLASS_ID_ROADSIGN: 0 } gst_buffer = info.get_buffer() if not gst_buffer: print("Unable to get GSTBuffer") return # Retrieve batch metadata from the GST Buffer # Note that pyds.gst_buffer_get_nvds_batch_meta() expects # the C address of gst_buffer as input, # which is obtained with hash(gst_buffer) batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer)) if not batch_meta: return Gst.PadProbeReturn.OK l_frame = batch_meta.frame_meta_list while l_frame is not None: try: # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta # The casting is done by pyds.NvDSFrameMeta.cast() # The casting also keeps ownership of the underlying memory # in the C code, so the Python garbage collection # will leave it alone frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data) except StopIteration: continue frame_number = frame_meta.frame_num l_obj = frame_meta.obj_meta_list while l_obj is not None: try: obj_meta = pyds.NvDsObjectMeta.cast(l_obj.data) except StopIteration: continue obj_counter[obj_meta.class_id] += 1 if ((frame_number % 30) == 0): # Allocating an NvDsEventMsgMeta instance and getting reference # to it. The underlying memory is not managed by Python so that # downstream plugins can access it. Otherwise the garbage collector # will free it when this probe exits. # See the "MetaData Access" section at this link: # https://docs.nvidia.com/metropolis/deepstream/dev-guide/index.html#page/DeepStream_Development_Guide/deepstream_Python_sample_apps.html # See also the struct fields here (C++ API reference): # https://docs.nvidia.com/metropolis/deepstream/5.0/dev-guide/DeepStream_Development_Guide/baggage/structNvDsEventMsgMeta.html msg_meta = pyds.alloc_nvds_event_msg_meta() msg_meta.bbox.top = obj_meta.rect_params.top msg_meta.bbox.left = obj_meta.rect_params.left msg_meta.bbox.width = obj_meta.rect_params.width msg_meta.bbox.height = obj_meta.rect_params.height msg_meta.frameId = frame_number msg_meta.trackingId = long_to_int(obj_meta.object_id) msg_meta.confidence = obj_meta.confidence # What is this msg_meta thing even for? Can we get rid of this bit? # https://docs.nvidia.com/metropolis/deepstream/python-api/NvDsMeta_Schema/NvDsEventMsgMeta.html # No we can't this is the thing that actually sends it out # TODO I need to understand what this is msg_meta = generate_event_msg_meta(msg_meta, obj_meta.class_id) user_event_meta = pyds.nvds_acquire_user_meta_from_pool( batch_meta) if (user_event_meta): user_event_meta.user_meta_data = msg_meta user_event_meta.base_meta.meta_type = pyds.NvDsMetaType.NVDS_EVENT_MSG_META # Custom MetaData added to NvDsUserMeta require # custom copy and release functions. # The MetaData library relies on these custom functions to perform deep-copy of the custom structure, # and free allocated resources. # These functions are registered as callback function pointers in the NvDsUserMeta structure. # Setting callbacks in the event msg meta. The bindings layer # will wrap these callables in C functions. Currently only one # set of callbacks is supported. # pyds.set_user_copyfunc(user_event_meta, meta_copy_func) # pyds.set_user_releasefunc(user_event_meta, meta_free_func) pyds.nvds_add_user_meta_to_frame(frame_meta, user_event_meta) else: print("Error in attaching event meta to buffer\n") try: l_obj = l_obj.next except StopIteration: break try: l_frame = l_frame.next except StopIteration: break print( f"Frame Number = {frame_number}, Person Count = {obj_counter[PGIE_CLASS_ID_PERSON]}" ) return Gst.PadProbeReturn.OK
def tiler_src_pad_buffer_probe(pad, info, u_data): frame_number = 0 obj_counter = {PGIE_CLASS_ID_PERSON: 0} is_first_object = True num_rects = 0 gst_buffer = info.get_buffer() if not gst_buffer: print("Unable to get GstBuffer ") return # Retrieve batch metadata from the gst_buffer # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the # C address of gst_buffer as input, which is obtained with hash(gst_buffer) batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer)) if not batch_meta: return Gst.PadProbeReturn.OK l_frame = batch_meta.frame_meta_list while l_frame is not None: try: # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta # The casting is done by pyds.NvDsFrameMeta.cast() # The casting also keeps ownership of the underlying memory # in the C code, so the Python garbage collector will leave # it alone. frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data) except StopIteration: continue ''' print("Frame Number is ", frame_meta.frame_num) print("Source id is ", frame_meta.source_id) print("Batch id is ", frame_meta.batch_id) print("Source Frame Width ", frame_meta.source_frame_width) print("Source Frame Height ", frame_meta.source_frame_height) print("Num object meta ", frame_meta.num_obj_meta) ''' frame_number = frame_meta.frame_num l_obj = frame_meta.obj_meta_list num_rects = frame_meta.num_obj_meta is_first_object = True while l_obj is not None: try: # Casting l_obj.data to pyds.NvDsObjectMeta obj_meta = pyds.NvDsObjectMeta.cast(l_obj.data) except StopIteration: continue obj_counter[obj_meta.class_id] += 1 # Ideally NVDS_EVENT_MSG_META should be attached to buffer by the # component implementing detection / recognition logic. # Here it demonstrates how to use / attach that meta data. # print("########################") # print("before entering is first object", is_first_object) if (is_first_object and not (frame_number % 30)): # print("Entered is first object") # Frequency of messages to be send will be based on use case. # Here message is being sent for first object every 30 frames. # Allocating an NvDsEventMsgMeta instance and getting reference # to it. The underlying memory is not manged by Python so that # downstream plugins can access it. Otherwise the garbage collector # will free it when this probe exits. msg_meta = pyds.alloc_nvds_event_msg_meta() msg_meta.bbox.top = obj_meta.rect_params.top msg_meta.bbox.left = obj_meta.rect_params.left msg_meta.bbox.width = obj_meta.rect_params.width msg_meta.bbox.height = obj_meta.rect_params.height msg_meta.frameId = frame_number msg_meta.trackingId = long_to_int(obj_meta.object_id) msg_meta.confidence = obj_meta.confidence msg_meta = generate_event_msg_meta(msg_meta, obj_meta.class_id) user_event_meta = pyds.nvds_acquire_user_meta_from_pool( batch_meta) if (user_event_meta): user_event_meta.user_meta_data = msg_meta user_event_meta.base_meta.meta_type = pyds.NvDsMetaType.NVDS_EVENT_MSG_META # Setting callbacks in the event msg meta. The bindings layer # will wrap these callables in C functions. Currently only one # set of callbacks is supported. pyds.set_user_copyfunc(user_event_meta, meta_copy_func) pyds.set_user_releasefunc(user_event_meta, meta_free_func) pyds.nvds_add_user_meta_to_frame(frame_meta, user_event_meta) else: print("Error in attaching event meta to buffer\n") is_first_object = False try: l_obj = l_obj.next except StopIteration: break """display_meta=pyds.nvds_acquire_display_meta_from_pool(batch_meta) display_meta.num_labels = 1 py_nvosd_text_params = display_meta.text_params[0] py_nvosd_text_params.display_text = "Frame Number={} Number of Objects={} Vehicle_count={} Person_count={}".format(frame_number, num_rects, vehicle_count, person) py_nvosd_text_params.x_offset = 10; py_nvosd_text_params.y_offset = 12; py_nvosd_text_params.font_params.font_name = "Serif" py_nvosd_text_params.font_params.font_size = 10 py_nvosd_text_params.font_params.font_color.red = 1.0 py_nvosd_text_params.font_params.font_color.green = 1.0 py_nvosd_text_params.font_params.font_color.blue = 1.0 py_nvosd_text_params.font_params.font_color.alpha = 1.0 py_nvosd_text_params.set_bg_clr = 1 py_nvosd_text_params.text_bg_clr.red = 0.0 py_nvosd_text_params.text_bg_clr.green = 0.0 py_nvosd_text_params.text_bg_clr.blue = 0.0 py_nvosd_text_params.text_bg_clr.alpha = 1.0 #print("Frame Number=", frame_number, "Number of Objects=",num_rects,"Vehicle_count=",vehicle_count,"Person_count=",person) pyds.nvds_add_display_meta_to_frame(frame_meta, display_meta)""" # Get frame rate through this probe fps_streams["stream{0}".format(frame_meta.pad_index)].get_fps() try: l_frame = l_frame.next except StopIteration: break print("Frame Number=", frame_number, "Number of Objects=", num_rects, "Face=", obj_counter[PGIE_CLASS_ID_PERSON]) return Gst.PadProbeReturn.OK
def tiler_src_pad_buffer_probe(pad, info, u_data): global number_sources frame_number = 0 num_rects = 0 gst_buffer = info.get_buffer() if not gst_buffer: print("Unable to get GstBuffer ") return lp_dict = {i: {} for i in range(number_sources)} # Retrieve batch metadata from the gst_buffer # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the # C address of gst_buffer as input, which is obtained with hash(gst_buffer) batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer)) l_frame = batch_meta.frame_meta_list while l_frame is not None: try: # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta # The casting is done by pyds.NvDsFrameMeta.cast() # The casting also keeps ownership of the underlying memory # in the C code, so the Python garbage collector will leave # it alone. frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data) except StopIteration: break ''' print("Frame Number is ", frame_meta.frame_num) print("Source id is ", frame_meta.source_id) print("Batch id is ", frame_meta.batch_id) print("Source Frame Width ", frame_meta.source_frame_width) print("Source Frame Height ", frame_meta.source_frame_height) print("Num object meta ", frame_meta.num_obj_meta) ''' frame_number = frame_meta.frame_num l_obj = frame_meta.obj_meta_list num_rects = frame_meta.num_obj_meta while l_obj is not None: try: # Casting l_obj.data to pyds.NvDsObjectMeta obj_meta = pyds.NvDsObjectMeta.cast(l_obj.data) except StopIteration: break # print(obj_meta.confidence) l_user_meta = obj_meta.obj_user_meta_list while l_user_meta: try: user_meta = pyds.NvDsUserMeta.cast(l_user_meta.data) if user_meta.base_meta.meta_type == pyds.nvds_get_user_meta_type( "NVIDIA.DSANALYTICSOBJ.USER_META"): user_meta_data = pyds.NvDsAnalyticsObjInfo.cast( user_meta.user_meta_data) print("Object {0} line crossing status: {1}".format( obj_meta.object_id, user_meta_data.lcStatus)) # print("Object {0} roi status: {1}".format(obj_meta.object_id, user_meta_data.roiStatus)) # if user_meta_data.dirStatus: print("Object {0} moving in direction: {1}".format(obj_meta.object_id, user_meta_data.dirStatus)) # if user_meta_data.lcStatus: print("Object {0} line crossing status: {1}".format(obj_meta.object_id, user_meta_data.lcStatus)) # if user_meta_data.ocStatus: print("Object {0} overcrowding status: {1}".format(obj_meta.object_id, user_meta_data.ocStatus)) # if user_meta_data.roiStatus: print("Object {0} roi status: {1}".format(obj_meta.object_id, user_meta_data.roiStatus)) l_class = obj_meta.classifier_meta_list # print(l_class) if user_meta_data.lcStatus: while l_class is not None: try: class_meta = pyds.NvDsClassifierMeta.cast( l_class.data) except StopIteration: break l_label = class_meta.label_info_list # print(class_meta.num_labels) while l_label is not None: try: label_info = pyds.NvDsLabelInfo.cast( l_label.data) except StopIteration: break print(label_info.result_label) # print(long_to_int(obj_meta.object_id)) x = obj_meta.rect_params.left y = obj_meta.rect_params.top w = obj_meta.rect_params.width h = obj_meta.rect_params.height lp_dict[frame_meta.pad_index][long_to_int( obj_meta.object_id)] = [ label_info.result_label, obj_meta.confidence, int(x), int(y), int(x + w), int(y + h) ] try: l_label = l_label.next except StopIteration: break try: l_class = l_class.next except StopIteration: break except StopIteration: break try: l_user_meta = l_user_meta.next except StopIteration: break try: l_obj = l_obj.next except StopIteration: break #write image when object detected in "positive" folder for source_id, data in lp_dict.items(): for tracking_id, bbox_info in data.items(): if tracking_id not in list(id_list.queue): if id_list.full(): id_list.get() id_list.put(tracking_id) try: frame = get_frame(gst_buffer, frame_meta.batch_id) name = "img_" + str( tracking_id) + "_" + datetime.datetime.now( ).strftime("%Y%m%d_%H%M%S") + ".jpg" if bbox_info[1] > 0.3: cv2.rectangle(frame, (bbox_info[2], bbox_info[3]), (bbox_info[4], bbox_info[5]), (255, 0, 255), 1) cv2.rectangle(frame, (bbox_info[2], bbox_info[3] - 20), (bbox_info[4], bbox_info[3]), (255, 0, 255), -1) cv2.putText(frame, bbox_info[0], (bbox_info[2], bbox_info[3] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA) cv2.imwrite( os.path.join( os.path.join(path1, "stream_" + str(source_id)), name), frame) print(bbox_info) except cv2.error as e: print(e) print(lp_dict) # Get meta data from NvDsAnalyticsFrameMeta l_user = frame_meta.frame_user_meta_list while l_user: try: user_meta = pyds.NvDsUserMeta.cast(l_user.data) if user_meta.base_meta.meta_type == pyds.nvds_get_user_meta_type( "NVIDIA.DSANALYTICSFRAME.USER_META"): user_meta_data = pyds.NvDsAnalyticsFrameMeta.cast( user_meta.user_meta_data) # if user_meta_data.objInROIcnt: print("Objs in ROI: {0}".format(user_meta_data.objInROIcnt)) if user_meta_data.objLCCumCnt: print("Linecrossing Cumulative: {0}".format( user_meta_data.objLCCumCnt)) # if user_meta_data.objLCCurrCnt: print("Linecrossing Current Frame: {0}".format(user_meta_data.objLCCurrCnt)) # if user_meta_data.ocStatus: print("Overcrowding status: {0}".format(user_meta_data.ocStatus)) except StopIteration: break try: l_user = l_user.next except StopIteration: break # Get frame rate through this probe fps_streams["stream{0}".format(frame_meta.pad_index)].get_fps() try: l_frame = l_frame.next except StopIteration: break return Gst.PadProbeReturn.OK