forked from dsutanto/bytetrack-counter-cpp
Add motion detection before object detection
This commit is contained in:
1 parent
bed242d26c
commit
511d892d3c
6 files changed
+38
-6
No files matched your search
Binary file not shown.
+2
-2
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
namespace version {
|
namespace version {
|
||||||
|
|
||||||
const std::string GIT_COMMIT = "87277f75";
|
const std::string GIT_COMMIT = "bed242d2";
|
||||||
const std::string GIT_BRANCH = "main";
|
const std::string GIT_BRANCH = "main";
|
||||||
const std::string GIT_TAG = "";
|
const std::string GIT_TAG = "";
|
||||||
const std::string BUILD_DATE = "2026-07-06";
|
const std::string BUILD_DATE = "2026-07-06";
|
||||||
const std::string BUILD_TIME = "18:03:38";
|
const std::string BUILD_TIME = "22:54:19";
|
||||||
const int BUILD_YEAR = 2026;
|
const int BUILD_YEAR = 2026;
|
||||||
const bool BUILD_RKNN = 1;
|
const bool BUILD_RKNN = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,13 @@ EXPORT_CSV=true
|
|||||||
CROSS_CSV=/opt/batch-counter/batch_crossings.csv
|
CROSS_CSV=/opt/batch-counter/batch_crossings.csv
|
||||||
|
|
||||||
# --- Rate / performance ---
|
# --- Rate / performance ---
|
||||||
|
# Enable motion detection pre-filter: skip inference on frames with no movement
|
||||||
|
# (true/false, default: false). When enabled, frames below MOTION_THRESHOLD are
|
||||||
|
# skipped, saving NPU/CPU load.
|
||||||
|
MOTION_DETECTION_ENABLED=false
|
||||||
|
# Mean absolute pixel difference threshold (0–255) to consider a frame as having
|
||||||
|
# motion. Lower = more sensitive. Default 5.0.
|
||||||
|
MOTION_THRESHOLD=5.0
|
||||||
# Sliding window in seconds for computing the crossing rate (objects/minute)
|
# Sliding window in seconds for computing the crossing rate (objects/minute)
|
||||||
RATE_WINDOW_SEC=60
|
RATE_WINDOW_SEC=60
|
||||||
# Number of frames to discard at startup to let the stream buffer stabilise
|
# Number of frames to discard at startup to let the stream buffer stabilise
|
||||||
|
|||||||
@@ -119,6 +119,11 @@ void AppConfig::load_from_env(const char* env_path) {
|
|||||||
if (!ecsv.empty()) export_csv = (ecsv == "true");
|
if (!ecsv.empty()) export_csv = (ecsv == "true");
|
||||||
cross_csv = get_env("CROSS_CSV", output_dir + "/batch_crossings.csv");
|
cross_csv = get_env("CROSS_CSV", output_dir + "/batch_crossings.csv");
|
||||||
|
|
||||||
|
auto mde_s = get_env("MOTION_DETECTION_ENABLED");
|
||||||
|
motion_detection_enabled = (mde_s == "true");
|
||||||
|
auto mt_s = get_env("MOTION_THRESHOLD");
|
||||||
|
if (!mt_s.empty()) motion_threshold = std::stof(mt_s);
|
||||||
|
|
||||||
auto wf_s = get_env("WARMUP_FRAMES");
|
auto wf_s = get_env("WARMUP_FRAMES");
|
||||||
if (!wf_s.empty()) warmup_frames = std::stoi(wf_s);
|
if (!wf_s.empty()) warmup_frames = std::stoi(wf_s);
|
||||||
auto rd_s = get_env("RECONNECT_DELAY_SEC");
|
auto rd_s = get_env("RECONNECT_DELAY_SEC");
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ struct AppConfig {
|
|||||||
bool export_csv = true;
|
bool export_csv = true;
|
||||||
std::string cross_csv;
|
std::string cross_csv;
|
||||||
|
|
||||||
|
bool motion_detection_enabled = false;
|
||||||
|
float motion_threshold = 5.0f;
|
||||||
int warmup_frames = 30;
|
int warmup_frames = 30;
|
||||||
int reconnect_delay_sec = 3;
|
int reconnect_delay_sec = 3;
|
||||||
int max_reconnect_attempts = 0;
|
int max_reconnect_attempts = 0;
|
||||||
|
|||||||
+22
-4
@@ -217,6 +217,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
std::unordered_map<int, TrackedInfo> ayam_tracked;
|
std::unordered_map<int, TrackedInfo> ayam_tracked;
|
||||||
std::unordered_map<int, TrackedInfo> talenan_tracked;
|
std::unordered_map<int, TrackedInfo> talenan_tracked;
|
||||||
|
cv::Mat prev_gray;
|
||||||
|
|
||||||
while (!shutdown_requested) {
|
while (!shutdown_requested) {
|
||||||
cv::Mat frame;
|
cv::Mat frame;
|
||||||
@@ -257,10 +258,27 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
bool ayam_crossed_frame = false, batch_closed_frame = false, batch_started_frame = false;
|
bool ayam_crossed_frame = false, batch_closed_frame = false, batch_started_frame = false;
|
||||||
|
|
||||||
auto inf_start = std::chrono::steady_clock::now();
|
bool skip_inference = false;
|
||||||
std::vector<Detection> detections = model(frame);
|
if (g_config.motion_detection_enabled) {
|
||||||
float inf_ms = std::chrono::duration<float, std::milli>(
|
cv::Mat gray;
|
||||||
std::chrono::steady_clock::now() - inf_start).count();
|
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
|
||||||
|
if (!prev_gray.empty()) {
|
||||||
|
cv::Mat diff;
|
||||||
|
cv::absdiff(gray, prev_gray, diff);
|
||||||
|
double mean_diff = cv::mean(diff)[0];
|
||||||
|
skip_inference = (mean_diff < g_config.motion_threshold);
|
||||||
|
}
|
||||||
|
prev_gray = gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Detection> detections;
|
||||||
|
float inf_ms = 0.0f;
|
||||||
|
if (!skip_inference) {
|
||||||
|
auto inf_start = std::chrono::steady_clock::now();
|
||||||
|
detections = model(frame);
|
||||||
|
inf_ms = std::chrono::duration<float, std::milli>(
|
||||||
|
std::chrono::steady_clock::now() - inf_start).count();
|
||||||
|
}
|
||||||
inf_ema = inf_ema * 0.9f + inf_ms * 0.1f;
|
inf_ema = inf_ema * 0.9f + inf_ms * 0.1f;
|
||||||
|
|
||||||
if (!detections.empty()) {
|
if (!detections.empty()) {
|
||||||
|
|||||||
Reference in new issue
Block a user