feat(detect): add debounce for alert/collision and tune default thresholds
- stdc_post_process.c: add consecutive frame counters for left/right alert (5 frames) and collision_risk (3 frames) to suppress single-frame noise - raise alert threshold defaults to 0.20 across all classes; tree_alert raised to 0.30 (trees are common background, prone to false positives) - grass_roi default raised from 0.75 to 0.80 - remove per-frame verbose log from stdc_post_process.c (consolidated into app_header_init.c) - app_header_init.c: add STDC-VIO / STDC-COL / STDC-ALT tuning logs showing actual%/threshold% side-by-side for field calibration - ini/host_stream.ini, kp_firmware.c: sync fallback defaults to match
This commit is contained in:
parent
b2321fcdca
commit
936e547dc3
@ -127,6 +127,6 @@ thr_bunker_col = 200 # bunker ratio → collision
|
||||
thr_pond_col = 200 # pond ratio → collision
|
||||
thr_person_alt = 200 # person ratio in side ROI → alert
|
||||
thr_car_alt = 200 # car ratio → alert
|
||||
thr_tree_alt = 200 # tree ratio → alert
|
||||
thr_tree_alt = 300 # tree ratio → alert (higher: trees are common background)
|
||||
thr_bunker_alt = 200 # bunker ratio → alert
|
||||
thr_pond_alt = 200 # pond ratio → alert
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "kdp2_inf_app_yolo.h"
|
||||
//#include "demo_customize_inf_single_model.h"
|
||||
#include "stdc_app.h"
|
||||
#include "stdc_post_process.h"
|
||||
#include "kdp2_host_stream.h"
|
||||
#include "event_recorder.h"
|
||||
#include "can_bus.h"
|
||||
@ -549,6 +550,47 @@ int app_header_recv_inference(uint32_t buf_addr, bool *bl_run_next_inference)
|
||||
printf("[STDC] ON GRASS: %.1fs%s\n",ana->grass_duration_sec,ana->grass_warning ? " *** GRASS WARNING ***" : "");
|
||||
else
|
||||
printf("[STDC] ON ROAD\n");
|
||||
|
||||
/* 3. ROI threshold tuning log (value%/threshold%) */
|
||||
/* [VIO] Grass / violation ROI */
|
||||
printf("[STDC-VIO] f=%u grass_roi=%.1f%%/%.0f%% time=%.1fs moving=%d diff=%.2f"
|
||||
" | ON_GRASS=%d GRASS_WARN=%d\n",
|
||||
ana->frame_count,
|
||||
ana->grass_roi_ratio * 100.0f, g_thr_grass_roi * 100.0f,
|
||||
ana->grass_duration_sec,
|
||||
ana->is_moving, ana->motion_diff,
|
||||
ana->on_grass, ana->grass_warning);
|
||||
|
||||
/* [COL] Collision ROI — forward trapezoid */
|
||||
printf("[STDC-COL] person=%.1f%%/%.0f%% car=%.1f%%/%.0f%% tree=%.1f%%/%.0f%%"
|
||||
" bunker=%.1f%%/%.0f%% pond=%.1f%%/%.0f%%"
|
||||
" | COLLISION=%d\n",
|
||||
ana->col_person_ratio * 100.0f, g_thr_person_collision * 100.0f,
|
||||
ana->col_car_ratio * 100.0f, g_thr_car_collision * 100.0f,
|
||||
ana->col_tree_ratio * 100.0f, g_thr_tree_collision * 100.0f,
|
||||
ana->col_bunker_ratio * 100.0f, g_thr_bunker_collision * 100.0f,
|
||||
ana->col_pond_ratio * 100.0f, g_thr_pond_collision * 100.0f,
|
||||
ana->collision_risk);
|
||||
|
||||
/* [ALT] Left / Right alert ROI */
|
||||
printf("[STDC-ALT] L: person=%.1f%%/%.0f%% car=%.1f%%/%.0f%% tree=%.1f%%/%.0f%%"
|
||||
" pond=%.1f%%/%.0f%% bunker=%.1f%%/%.0f%%"
|
||||
" | ALERT=%d[%s]\n",
|
||||
ana->left_person_ratio * 100.0f, g_thr_person_alert * 100.0f,
|
||||
ana->left_car_ratio * 100.0f, g_thr_car_alert * 100.0f,
|
||||
ana->left_tree_ratio * 100.0f, g_thr_tree_alert * 100.0f,
|
||||
ana->left_pond_ratio * 100.0f, g_thr_pond_alert * 100.0f,
|
||||
ana->left_bunker_ratio * 100.0f, g_thr_bunker_alert * 100.0f,
|
||||
ana->left_alert, ana->left_alert ? ana->left_type : "-");
|
||||
printf("[STDC-ALT] R: person=%.1f%%/%.0f%% car=%.1f%%/%.0f%% tree=%.1f%%/%.0f%%"
|
||||
" pond=%.1f%%/%.0f%% bunker=%.1f%%/%.0f%%"
|
||||
" | ALERT=%d[%s]\n",
|
||||
ana->right_person_ratio * 100.0f, g_thr_person_alert * 100.0f,
|
||||
ana->right_car_ratio * 100.0f, g_thr_car_alert * 100.0f,
|
||||
ana->right_tree_ratio * 100.0f, g_thr_tree_alert * 100.0f,
|
||||
ana->right_pond_ratio * 100.0f, g_thr_pond_alert * 100.0f,
|
||||
ana->right_bunker_ratio * 100.0f, g_thr_bunker_alert * 100.0f,
|
||||
ana->right_alert, ana->right_alert ? ana->right_type : "-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,11 +334,11 @@ int loadConfig(HOST_STREAM_INIT_OPT_T* pHostStreamInit)
|
||||
g_thr_tree_collision = iniparser_getint(ini, "detect:thr_tree_col", 200) / 1000.0f;
|
||||
g_thr_bunker_collision = iniparser_getint(ini, "detect:thr_bunker_col", 200) / 1000.0f;
|
||||
g_thr_pond_collision = iniparser_getint(ini, "detect:thr_pond_col", 200) / 1000.0f;
|
||||
g_thr_person_alert = iniparser_getint(ini, "detect:thr_person_alt", 100) / 1000.0f;
|
||||
g_thr_car_alert = iniparser_getint(ini, "detect:thr_car_alt", 100) / 1000.0f;
|
||||
g_thr_tree_alert = iniparser_getint(ini, "detect:thr_tree_alt", 200) / 1000.0f;
|
||||
g_thr_bunker_alert = iniparser_getint(ini, "detect:thr_bunker_alt", 100) / 1000.0f;
|
||||
g_thr_pond_alert = iniparser_getint(ini, "detect:thr_pond_alt", 100) / 1000.0f;
|
||||
g_thr_person_alert = iniparser_getint(ini, "detect:thr_person_alt", 200) / 1000.0f;
|
||||
g_thr_car_alert = iniparser_getint(ini, "detect:thr_car_alt", 200) / 1000.0f;
|
||||
g_thr_tree_alert = iniparser_getint(ini, "detect:thr_tree_alt", 300) / 1000.0f;
|
||||
g_thr_bunker_alert = iniparser_getint(ini, "detect:thr_bunker_alt", 200) / 1000.0f;
|
||||
g_thr_pond_alert = iniparser_getint(ini, "detect:thr_pond_alt", 200) / 1000.0f;
|
||||
printf("[FW] detect thresholds: grass=%.3f p_col=%.3f c_col=%.3f t_col=%.3f"
|
||||
" p_alt=%.3f c_alt=%.3f\n",
|
||||
g_thr_grass_roi, g_thr_person_collision, g_thr_car_collision,
|
||||
|
||||
@ -7,27 +7,29 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "kp_struct.h"
|
||||
#include "ncpu_gen_struct.h"
|
||||
#include "demo_post_utils.h"
|
||||
#include "stdc_post_process.h"
|
||||
|
||||
extern unsigned int g_verbose_log;
|
||||
|
||||
/* Detection thresholds — runtime tunable via BLE SET / INI [detect] section */
|
||||
float g_thr_grass_roi = 0.75f;
|
||||
float g_thr_person_collision = 0.10f;
|
||||
float g_thr_grass_roi = 0.80f;
|
||||
float g_thr_person_collision = 0.20f;
|
||||
float g_thr_car_collision = 0.20f;
|
||||
float g_thr_tree_collision = 0.20f;
|
||||
float g_thr_bunker_collision = 0.20f;
|
||||
float g_thr_pond_collision = 0.20f;
|
||||
float g_thr_person_alert = 0.10f;
|
||||
float g_thr_car_alert = 0.10f;
|
||||
float g_thr_tree_alert = 0.20f;
|
||||
float g_thr_bunker_alert = 0.10f;
|
||||
float g_thr_pond_alert = 0.10f;
|
||||
float g_thr_person_alert = 0.20f;
|
||||
float g_thr_car_alert = 0.20f;
|
||||
float g_thr_tree_alert = 0.30f;
|
||||
float g_thr_bunker_alert = 0.20f;
|
||||
float g_thr_pond_alert = 0.20f;
|
||||
|
||||
/* Consecutive frames required before left/right alert fires (debounce) */
|
||||
#define ALERT_DEBOUNCE_FRAMES 5
|
||||
/* Consecutive frames required before collision_risk fires (shorter: safety signal) */
|
||||
#define COLLISION_DEBOUNCE_FRAMES 3
|
||||
|
||||
typedef struct {
|
||||
uint8_t *prev_roi_luma;
|
||||
@ -35,6 +37,9 @@ typedef struct {
|
||||
uint32_t prev_roi_count;
|
||||
uint32_t frame_count;
|
||||
uint32_t consecutive_grass_frames;
|
||||
uint32_t consecutive_left_frames; /* debounce counter for left alert */
|
||||
uint32_t consecutive_right_frames; /* debounce counter for right alert */
|
||||
uint32_t consecutive_collision_frames; /* debounce counter for collision_risk */
|
||||
float prev_tree_roi_ratio;
|
||||
} stdc_runtime_state_t;
|
||||
|
||||
@ -260,10 +265,13 @@ int stdc_post_process(int model_id, struct kdp_image_s *image_p)
|
||||
ana->right_pond_ratio = (float)right_count[STDC_CLASS_POND] * inv_right;
|
||||
ana->right_bunker_ratio = (float)right_count[STDC_CLASS_BUNKER] * inv_right;
|
||||
|
||||
/* Left alert: highest-ratio class that exceeds its collision threshold */
|
||||
ana->left_alert = 0;
|
||||
ana->left_type[0] = '\0';
|
||||
/* Left alert: highest-ratio class that exceeds threshold.
|
||||
* Debounced: must exceed threshold for ALERT_DEBOUNCE_FRAMES consecutive
|
||||
* frames before ana->left_alert fires. left_type always tracks current
|
||||
* dominant class so it is correct when the debounce finally triggers. */
|
||||
{
|
||||
int raw_alert = 0;
|
||||
ana->left_type[0] = '\0';
|
||||
struct { float ratio; float thr; const char *name; } lc[] = {
|
||||
{ ana->left_person_ratio, g_thr_person_alert, "person" },
|
||||
{ ana->left_car_ratio, g_thr_car_alert, "vehicle" },
|
||||
@ -274,19 +282,24 @@ int stdc_post_process(int model_id, struct kdp_image_s *image_p)
|
||||
float best = 0.0f;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (lc[i].ratio >= lc[i].thr) {
|
||||
ana->left_alert = 1;
|
||||
raw_alert = 1;
|
||||
if (lc[i].ratio > best) {
|
||||
best = lc[i].ratio;
|
||||
snprintf(ana->left_type, sizeof(ana->left_type), "%s", lc[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (raw_alert)
|
||||
g_stdc_state.consecutive_left_frames++;
|
||||
else
|
||||
g_stdc_state.consecutive_left_frames = 0;
|
||||
ana->left_alert = (g_stdc_state.consecutive_left_frames >= ALERT_DEBOUNCE_FRAMES) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Right alert: same logic */
|
||||
ana->right_alert = 0;
|
||||
ana->right_type[0] = '\0';
|
||||
/* Right alert: same logic with debounce */
|
||||
{
|
||||
int raw_alert = 0;
|
||||
ana->right_type[0] = '\0';
|
||||
struct { float ratio; float thr; const char *name; } rc[] = {
|
||||
{ ana->right_person_ratio, g_thr_person_alert, "person" },
|
||||
{ ana->right_car_ratio, g_thr_car_alert, "vehicle" },
|
||||
@ -297,13 +310,18 @@ int stdc_post_process(int model_id, struct kdp_image_s *image_p)
|
||||
float best = 0.0f;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (rc[i].ratio >= rc[i].thr) {
|
||||
ana->right_alert = 1;
|
||||
raw_alert = 1;
|
||||
if (rc[i].ratio > best) {
|
||||
best = rc[i].ratio;
|
||||
snprintf(ana->right_type, sizeof(ana->right_type), "%s", rc[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (raw_alert)
|
||||
g_stdc_state.consecutive_right_frames++;
|
||||
else
|
||||
g_stdc_state.consecutive_right_frames = 0;
|
||||
ana->right_alert = (g_stdc_state.consecutive_right_frames >= ALERT_DEBOUNCE_FRAMES) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------
|
||||
@ -325,34 +343,18 @@ int stdc_post_process(int model_id, struct kdp_image_s *image_p)
|
||||
ana->tree_dense = (ana->class_ratio[STDC_CLASS_TREE] > THR_TREE_DENSE) ? 1 : 0;
|
||||
ana->tree_approaching = (ana->tree_roi_growth > STDC_TREE_GROWTH_THR) ? 1 : 0;
|
||||
|
||||
ana->collision_risk = 0;
|
||||
if (ana->col_person_ratio >= g_thr_person_collision) ana->collision_risk = 1;
|
||||
if (ana->col_car_ratio >= g_thr_car_collision) ana->collision_risk = 1;
|
||||
if (ana->col_tree_ratio >= g_thr_tree_collision) ana->collision_risk = 1;
|
||||
if (ana->col_bunker_ratio >= g_thr_bunker_collision) ana->collision_risk = 1;
|
||||
if (ana->col_pond_ratio >= g_thr_pond_collision) ana->collision_risk = 1;
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* 4. Log summary (throttled to 1Hz, verbose_log only)
|
||||
* ------------------------------------------------------- */
|
||||
if (g_verbose_log) {
|
||||
static struct timeval s_last_post_log = {0, 0};
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
long elapsed_us = (now.tv_sec - s_last_post_log.tv_sec) * 1000000L
|
||||
+ (now.tv_usec - s_last_post_log.tv_usec);
|
||||
if (elapsed_us >= 1000000L) {
|
||||
s_last_post_log = now;
|
||||
printf("[STDC] frame=%u moving=%d diff=%.2f grass_roi=%.1f%% grass_time=%.1fs grass_warn=%d "
|
||||
"person=%.1f%% car=%.1f%% tree=%.1f%% tree_growth=%.1f%% collision=%d\n",
|
||||
ana->frame_count, ana->is_moving, ana->motion_diff,
|
||||
ana->grass_roi_ratio * 100.0f, ana->grass_duration_sec, ana->grass_warning,
|
||||
ana->class_ratio[STDC_CLASS_PERSON] * 100.0f,
|
||||
ana->class_ratio[STDC_CLASS_CAR] * 100.0f,
|
||||
ana->class_ratio[STDC_CLASS_TREE] * 100.0f,
|
||||
ana->tree_roi_growth * 100.0f,
|
||||
ana->collision_risk);
|
||||
}
|
||||
{
|
||||
int raw_collision = 0;
|
||||
if (ana->col_person_ratio >= g_thr_person_collision) raw_collision = 1;
|
||||
if (ana->col_car_ratio >= g_thr_car_collision) raw_collision = 1;
|
||||
if (ana->col_tree_ratio >= g_thr_tree_collision) raw_collision = 1;
|
||||
if (ana->col_bunker_ratio >= g_thr_bunker_collision) raw_collision = 1;
|
||||
if (ana->col_pond_ratio >= g_thr_pond_collision) raw_collision = 1;
|
||||
if (raw_collision)
|
||||
g_stdc_state.consecutive_collision_frames++;
|
||||
else
|
||||
g_stdc_state.consecutive_collision_frames = 0;
|
||||
ana->collision_risk = (g_stdc_state.consecutive_collision_frames >= COLLISION_DEBOUNCE_FRAMES) ? 1 : 0;
|
||||
}
|
||||
|
||||
return KP_SUCCESS;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user