How to Add Confidence Score for Each Attribute on a Custom Person Attribute Recognition Model Using Intel® DL Streamer?
Content Type: Troubleshooting | Article ID: 000101176 | Last Reviewed: 06/16/2025
Users are experiencing difficulties in adding confidence scores for each attribute in a custom person attribute recognition model using Intel® DL Streamer.
import numpy as np
# Full attribute list in EXACT model output order (verify with benchmark_app)
ATTRIBUTES_LIST = [
"accessoryHat", # 0
"hairLong", # 1
"hairShort", # 2
"upperBodyShortSleeve", # 3
"upperBodyBlack", # 4
"upperBodyBlue", # 5
"upperBodyBrown", # 6
"upperBodyGreen", # 7
"upperBodyGrey", # 8
"upperBodyOrange", # 9
"upperBodyPink", # 10
"upperBodyPurple", # 11
"upperBodyRed", # 12
"upperBodyWhite", # 13
"upperBodyYellow", # 14
"upperBodyLongSleeve", # 15
"lowerBodyShorts", # 16
"lowerBodyShortSkirt", # 17
"lowerBodyBlack", # 18
"lowerBodyBlue", # 19
"lowerBodyBrown", # 20
"lowerBodyGreen", # 21
"lowerBodyGrey", # 22
"lowerBodyOrange", # 23
"lowerBodyPink", # 24
"lowerBodyPurple", # 25
"lowerBodyRed", # 26
"lowerBodyWhite", # 27
"lowerBodyYellow", # 28
"lowerBodyLongSkirt", # 29
"footwearLeatherShoes", # 30
"footwearSandals", # 31
"footwearShoes", # 32
"footwearSneaker", # 33
"carryingBackpack", # 34
"carryingMessengerBag", # 35
"carryingLuggageCase", # 36
"carryingSuitcase", # 37
"personalLess30", # 38
"personalLess45", # 39
"personalLess60", # 40
"personalLarger60", # 41
"personalLess15", # 42
"personalMale", # 43
"personalFemale" # 44
]
# Configure your 9 attribute groups here
ATTRIBUTE_GROUPS = {
# Group 1: Head Attributes
"Head": {
"attributes": ["accessoryHat", "hairLong", "hairShort"],
"display_template": "Head: {attribute}",
"threshold": 0.4 # Lower threshold for head items
},
# Group 2: Upper Body Color
"UpperColor": {
"attributes": ["upperBodyBlack", "upperBodyBlue", "upperBodyBrown",
"upperBodyGreen", "upperBodyGrey", "upperBodyOrange",
"upperBodyPink", "upperBodyPurple", "upperBodyRed",
"upperBodyWhite", "upperBodyYellow"],
"display_template": "Upper: {attribute}",
"threshold": 0.5
},
# Group 3: Upper Body Style
"UpperStyle": {
"attributes": ["upperBodyShortSleeve", "upperBodyLongSleeve"],
"display_template": "Sleeve: {attribute}",
"threshold": 0.5,
"mutually_exclusive": True # Only one can be true
},
# Group 4: Lower Body Color
"LowerColor": {
"attributes": ["lowerBodyBlack", "lowerBodyBlue", "lowerBodyBrown",
"lowerBodyGreen", "lowerBodyGrey", "lowerBodyOrange",
"lowerBodyPink", "lowerBodyPurple", "lowerBodyRed",
"lowerBodyWhite", "lowerBodyYellow"],
"display_template": "Lower: {attribute}",
"threshold": 0.5
},
# Group 5: Lower Body Style
"LowerStyle": {
"attributes": ["lowerBodyShorts", "lowerBodyShortSkirt", "lowerBodyLongSkirt"],
"display_template": "Bottom: {attribute}",
"threshold": 0.5,
"mutually_exclusive": True
},
# Group 6: Footwear
"Footwear": {
"attributes": ["footwearLeatherShoes", "footwearSandals",
"footwearShoes", "footwearSneaker"],
"display_template": "Shoes: {attribute}",
"threshold": 0.5
},
# Group 7: Carrying Items
"Carrying": {
"attributes": ["carryingBackpack", "carryingMessengerBag",
"carryingLuggageCase", "carryingSuitcase"],
"display_template": "Bag: {attribute}",
"threshold": 0.4 # Lower threshold for rare items
},
# Group 8: Age Group
"Age": {
"attributes": ["personalLess15", "personalLess30",
"personalLess45", "personalLess60", "personalLarger60"],
"display_template": "Age: {attribute}",
"threshold": 0.5,
"mutually_exclusive": True
},
# Group 9: Gender
"Gender": {
"attributes": ["personalMale", "personalFemale"],
"display_template": "Gender: {attribute}",
"threshold": 0.7, # Higher threshold for gender
"mutually_exclusive": True
}
}
def process_frame(frame):
for roi in frame.regions():
# 1. Extract raw predictions
attr_predictions = {}
for tensor in roi.tensors():
if tensor.format() == "ANY":
data = tensor.data()
if len(data) == len(ATTRIBUTES_LIST):
for i, confidence in enumerate(data):
attr_predictions[ATTRIBUTES_LIST[i]] = float(confidence)
# 2. Process each group
results = []
for group_name, config in ATTRIBUTE_GROUPS.items():
best_attr = None
max_conf = 0
for attribute in config["attributes"]:
conf = attr_predictions.get(attribute, 0)
# Skip if mutually exclusive and we already have a high-confidence result
if config.get("mutually_exclusive", False) and best_attr and max_conf > config["threshold"]:
continue
if conf > max_conf and conf > config["threshold"]:
max_conf = conf
best_attr = attribute
if best_attr:
display_text = config["display_template"].format(attribute=best_attr)
results.append((display_text, max_conf))
# 3. Update ROI labels (shows all groups with detected attributes)
if results:
# Combine all results into one label for cleaner display
combined_label = " | ".join([text for text, _ in results])
roi.set_label(combined_label, min([conf for _, conf in results]))
return True
# For debugging (enable in development)
DEBUG_MODE = False
if DEBUG_MODE:
def debug_print_predictions(predictions):
print("\nRaw Predictions:")
for attr, conf in predictions.items():
if conf > 0.3: # Only show attributes with >30% confidence
print(f"{attr}: {conf:.2f}")
# Add this inside process_frame after getting attr_predictions
debug_print_predictions(attr_predictions)
gst-launch-1.0 \ filesrc location=video.mp4 ! decodebin ! videoconvert ! \ gvadetect model=person_vehicle.xml device=CPU ! queue ! \ gvainference model=attribute_model.xml device=CPU inference-region=roi ! queue ! \ gvapython module=attribute_grouper.py ! \ gvawatermark ! videoconvert ! autovideosink sync=false