Latest Leveling with python Fix!

This commit is contained in:
proitlab committed 2026-07-06 03:50:58 +07:00
1 parent 5483837769
commit 9ca1f2914e
11 files changed
+561 -172

No files matched your search

+82 -34
View File
@@ -50,6 +50,35 @@ static void warmup_stream(cv::VideoCapture& cap, int n) {
std::cout << "Stream ready!" << std::endl;
}
static bool connect_stream(cv::VideoCapture& cap, int& w, int& h, double& fps) {
bool is_live = g_config.source.substr(0, 7) == "rtsp://" ||
g_config.source.substr(0, 7) == "http://";
int attempts = 0;
while (!shutdown_requested) {
cap = open_capture(g_config.source);
if (cap.isOpened()) break;
attempts++;
if (g_config.max_reconnect_attempts > 0 && attempts >= g_config.max_reconnect_attempts) {
std::cerr << "Cannot open source after " << attempts
<< " attempts: " << g_config.source << std::endl;
return false;
}
std::cout << "Cannot open source, retry in " << g_config.reconnect_delay_sec
<< "s..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(g_config.reconnect_delay_sec));
}
if (shutdown_requested) return false;
if (is_live && g_config.warmup_frames > 0)
warmup_stream(cap, g_config.warmup_frames);
w = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
h = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
fps = cap.get(cv::CAP_PROP_FPS);
if (fps <= 1) fps = g_config.output_fps;
return true;
}
struct TrackedInfo {
float cx;
std::chrono::steady_clock::time_point ts;
@@ -75,11 +104,23 @@ int main(int argc, char* argv[]) {
std::cout << "Starting ByteTrack Counter (C++)" << std::endl;
std::cout << "Camera: " << g_config.camera_name << std::endl;
std::cout << "Source: " << g_config.source << std::endl;
std::cout << "Model: " << g_config.model_path << std::endl;
std::cout << "Model: " << g_config.model_path << " | imgsz=" << g_config.imgsz
<< " | core_mask=" << g_config.core_mask << std::endl;
std::cout << "DB: " << g_config.db_path << std::endl;
std::cout << "State: " << g_config.state_file << std::endl;
std::cout << "ByteTrack Index 0: high_thresh=" << g_config.track_high_thresh_0
<< " low_thresh=" << g_config.track_low_thresh_0
<< " match_thresh=" << g_config.track_match_thresh_0
<< " buffer=" << g_config.track_buffer_0
<< " min_hits=" << g_config.track_min_hits_0 << std::endl;
std::cout << "ByteTrack Index 1: high_thresh=" << g_config.track_high_thresh_1
<< " low_thresh=" << g_config.track_low_thresh_1
<< " match_thresh=" << g_config.track_match_thresh_1
<< " buffer=" << g_config.track_buffer_1
<< " min_hits=" << g_config.track_min_hits_1 << std::endl;
int class_ayam = 0;
int class_talenan = 1;
int class_ayam = g_config.ayam_class_id;
int class_talenan = g_config.talenan_class_id;
auto logger = [](const std::string& msg) {
std::cout << "[" << now_str() << "] " << msg << std::endl;
@@ -105,12 +146,12 @@ int main(int argc, char* argv[]) {
g_config.imgsz, g_config.conf, 0.45f,
g_config.num_classes, 0, g_config.score_sigmoid);
ByteTracker ayam_tracker(g_config.track_high_thresh, g_config.track_low_thresh,
g_config.track_match_thresh, g_config.track_buffer,
g_config.track_min_hits);
ByteTracker talenan_tracker(g_config.track_high_thresh, g_config.track_low_thresh,
g_config.track_match_thresh, g_config.track_buffer,
g_config.track_min_hits);
ByteTracker ayam_tracker(g_config.track_high_thresh_0, g_config.track_low_thresh_0,
g_config.track_match_thresh_0, g_config.track_buffer_0,
g_config.track_min_hits_0);
ByteTracker talenan_tracker(g_config.track_high_thresh_1, g_config.track_low_thresh_1,
g_config.track_match_thresh_1, g_config.track_buffer_1,
g_config.track_min_hits_1);
std::unordered_set<int> ayam_line_crossed;
std::unordered_set<int> talenan_line_crossed;
@@ -119,27 +160,27 @@ int main(int argc, char* argv[]) {
std::unordered_map<int, int> talenan_cross_flash;
int line_pulse = 0, count_pulse = 0, batch_pulse = 0;
std::vector<Popup> popups;
std::deque<std::chrono::steady_clock::time_point> crossing_times;
auto session_start = std::chrono::steady_clock::now();
int frame_idx = 0;
float inf_ema = 0.0f;
cv::VideoCapture cap = open_capture(g_config.source);
std::string model_name = g_config.model_path;
auto slash = model_name.find_last_of("/\\");
if (slash != std::string::npos) model_name = model_name.substr(slash + 1);
cv::VideoCapture cap;
int w, h;
double fps_prop;
if (!connect_stream(cap, w, h, fps_prop)) {
store.shutdown();
return shutdown_requested ? 0 : 1;
}
bool is_live = g_config.source.substr(0, 7) == "rtsp://" ||
g_config.source.substr(0, 7) == "http://";
if (!cap.isOpened()) {
std::cerr << "Cannot open source: " << g_config.source << std::endl;
store.shutdown();
return 1;
}
if (is_live && g_config.warmup_frames > 0)
warmup_stream(cap, g_config.warmup_frames);
int w = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
double fps_prop = cap.get(cv::CAP_PROP_FPS);
if (fps_prop <= 1) fps_prop = g_config.output_fps;
int line_x = resolve_line_x(w, g_config.line_x, g_config.line_x_frac);
std::cout << "RKNN+ByteTrack counter | " << w << "x" << h << " @ "
@@ -161,21 +202,22 @@ int main(int argc, char* argv[]) {
<< "), reconnecting..." << std::endl;
cap.release();
std::this_thread::sleep_for(std::chrono::seconds(g_config.reconnect_delay_sec));
cap = open_capture(g_config.source);
if (!cap.isOpened()) break;
w = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
h = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
if (!connect_stream(cap, w, h, fps_prop)) break;
line_x = resolve_line_x(w, g_config.line_x, g_config.line_x_frac);
continue;
}
auto elapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(
auto elapsed_sec = std::chrono::duration<double>(
std::chrono::steady_clock::now() - session_start).count();
auto mono = std::chrono::steady_clock::now();
bool ayam_crossed_frame = false, batch_closed_frame = false, batch_started_frame = false;
auto inf_start = std::chrono::steady_clock::now();
std::vector<Detection> detections = model(frame);
float 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;
if (!detections.empty()) {
std::vector<Eigen::Vector4f> ayam_boxes, talenan_boxes;
@@ -317,6 +359,7 @@ int main(int argc, char* argv[]) {
}
ayam_crossed_frame = true;
if (started_new) batch_started_frame = true;
crossing_times.push_back(mono);
ayam_cross_flash[tid] = g_config.cross_flash_frames;
popups.push_back({
static_cast<int>(cx) - 12,
@@ -379,15 +422,19 @@ int main(int argc, char* argv[]) {
int batch_num = store.current_batch_number();
int batch_count = store.current_batch_count();
int display_total = store.display_total();
double elapsed = static_cast<double>(elapsed_sec);
double rate = elapsed > 0 ? (display_total / elapsed * 60.0) : 0.0;
while (!crossing_times.empty() &&
std::chrono::duration<double>(mono - crossing_times.front()).count() > g_config.rate_window_sec)
crossing_times.pop_front();
double rate = crossing_times.empty() ? 0.0 :
(crossing_times.size() / static_cast<double>(g_config.rate_window_sec) * 60.0);
draw_elegant_counting_line(frame, line_x, h, line_pulse);
draw_hero_count(frame, line_x, h, batch_count, count_pulse);
draw_hud(frame, w, batch_num, batch_count, display_total,
elapsed, rate, g_config.camera_name, now_str());
elapsed_sec, rate);
draw_batch_banner(frame, w, batch_num, batch_pulse);
draw_footer(frame, w, h, frame_idx, is_live ? "LIVE-RKNN-BT" : "FILE-RKNN-BT");
draw_footer(frame, w, h, frame_idx, is_live ? "LIVE" : "FILE", inf_ema, model_name);
popups = draw_popups(frame, popups, frame_idx);
// Flash decay
@@ -418,9 +465,10 @@ int main(int argc, char* argv[]) {
frame_idx++;
if (frame_idx % g_config.flush_every_n_frames == 0) {
std::cout << "[" << now_str() << "] Frame " << frame_idx
<< " | Batch " << batch_num << ": " << batch_count
<< " | Batch " << (batch_num ? std::to_string(batch_num) : "-")
<< ": " << (batch_num ? std::to_string(batch_count) : "-")
<< " | Total: " << display_total
<< " | Uptime " << (elapsed / 3600.0) << "h" << std::endl;
<< " | Uptime " << (elapsed_sec / 3600.0) << "h" << std::endl;
}
prune_stale_tracks(ayam_tracked, g_config.tracked_prune_sec);