#include "../nodes/vp_file_src_node.h"
|
#include "../nodes/vp_rtsp_src_node.h"
|
#include "../nodes/vp_rtsp_ffmpeg_src_node.h"
|
#include "../nodes/vp_split_node.h"
|
#include "../nodes/infers/vp_trt_vehicle_detector.h"
|
#include "../nodes/infers/vp_trt_vehicle_plate_detector.h"
|
#include "../nodes/infers/vp_trt_vehicle_color_classifier.h"
|
#include "../nodes/infers/vp_yolo_detector_node.h"
|
|
#include "../nodes/osd/vp_osd_node.h"
|
#include "../nodes/vp_sync_node.h"
|
#include "../nodes/track/vp_sort_track_node.h"
|
#include "../nodes/ba/vp_ba_crossline_node.h"
|
#include "../nodes/osd/vp_ba_crossline_osd_node.h"
|
|
#include "../nodes/broker/vp_json_kafka_broker_node.h"
|
#include "../nodes/record/vp_record_node.h"
|
#include "../nodes/vp_screen_des_node.h"
|
#include "../nodes/vp_fake_des_node.h"
|
#include "../nodes/vp_placeholder_node.h"
|
|
#include "../utils/analysis_board/vp_analysis_board.h"
|
|
#include <iostream>
|
#include <fstream>
|
#include <vector>
|
#include <string>
|
#include <map>
|
#include <sstream>
|
|
// Function to read configuration from a file
|
std::vector<std::vector<std::string>> read_config_file(const std::string& file_path) {
|
std::vector<std::vector<std::string>> config_lines;
|
std::string line;
|
try {
|
std::ifstream infile(file_path);
|
while (std::getline(infile, line)) {
|
std::vector<std::string> params;
|
size_t start = 0;
|
size_t end = line.find(" ");
|
while (end != std::string::npos) {
|
params.push_back(line.substr(start, end - start));
|
start = end + 1;
|
end = line.find(" ", start);
|
}
|
params.push_back(line.substr(start, end)); // add the last parameter
|
config_lines.push_back(params);
|
}
|
} catch (const std::exception& e) {
|
std::cerr << "read config file ex: " << std::string(e.what()) << " <config_file>\n";
|
} catch (...) {
|
std::cerr << "read config file ex end1111\n";
|
}
|
return config_lines;
|
}
|
|
// Function to parse polygon coordinates from string
|
std::vector<vp_objects::vp_point> parse_polygon(const std::string& polygon_str, float resize_ratio) {
|
std::vector<vp_objects::vp_point> polygon;
|
std::stringstream ss(polygon_str);
|
std::string point_str;
|
while (std::getline(ss, point_str, ')')) {
|
size_t start = point_str.find('(');
|
if (start != std::string::npos) {
|
std::string coordinates = point_str.substr(start + 1);
|
size_t comma_pos = coordinates.find(',');
|
if (comma_pos != std::string::npos) {
|
int x = std::stoi(coordinates.substr(0, comma_pos));
|
int y = std::stoi(coordinates.substr(comma_pos + 1));
|
x = static_cast<int>(std::round(x * resize_ratio));
|
y = static_cast<int>(std::round(y * resize_ratio));
|
polygon.push_back(vp_objects::vp_point(x, y));
|
}
|
}
|
}
|
return polygon;
|
}
|
|
int main(int argc, char* argv[]) {
|
VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
|
VP_LOGGER_INIT();
|
// Read configuration file
|
if (argc < 2) {
|
std::cerr << "Usage: " << argv[0] << " <config_file>\n";
|
return -1;
|
}
|
|
try {
|
std::string config_file = argv[1];
|
auto configs = read_config_file(config_file);
|
VP_INFO(vp_utils::string_format("Launch a thread for each configuration [%s]", config_file));
|
|
// Correct type declarations
|
std::string kafka_server_point = "";
|
std::vector<std::string> rtsp_srcs;
|
std::vector<int> channel_indexs;
|
std::vector<int> skip_intervals;
|
std::vector<bool> use_gpus;
|
std::vector<float> resize_ratios;
|
|
// Use shared pointers for nodes
|
std::vector<std::shared_ptr<vp_nodes::vp_node>> rtsp_nodes;
|
// std::vector<std::shared_ptr<vp_nodes::vp_src_node>> rtsp_nodes;
|
// Des节点
|
std::vector<std::shared_ptr<vp_nodes::vp_des_node>> des_nodes;
|
|
// define a region in frame for every channel (value MUST in the scope of frame'size)
|
std::map<int, vp_objects::vp_line> lines = {};
|
|
for (const auto& config : configs) {
|
if (config.size() >= 5) {
|
float resize_ratio = std::stof(config[1]);
|
int skip_interval = std::stoi(config[3]);
|
int channel_index = std::stoi(config[4]);
|
bool usegpu = config.size() >= 6 && config[5] == "1";
|
|
rtsp_srcs.push_back(config[0]);
|
resize_ratios.push_back(resize_ratio);
|
kafka_server_point = config[2];
|
skip_intervals.push_back(skip_interval);
|
channel_indexs.push_back(channel_index);
|
use_gpus.push_back(usegpu);
|
|
// Read and parse the polygon coordinates
|
if (config.size() >= 7) {
|
std::string polygon_str = config[6]; // Assuming the polygon coordinates are in the 7th column
|
vp_objects::vp_point start(30, 140); // change to proper value 0,250
|
vp_objects::vp_point end(610, 110); // change to proper value 700,220
|
lines[channel_index] = vp_objects::vp_line(start, end);
|
} else {
|
vp_objects::vp_point start(30, 140); // change to proper value 0,250
|
vp_objects::vp_point end(610, 110); // change to proper value 700,220
|
lines[channel_index] = vp_objects::vp_line(start, end);
|
}
|
|
rtsp_nodes.push_back(std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>(
|
"rtsp_src_" + config[4], channel_index, config[0], resize_ratio, skip_interval, usegpu));
|
|
des_nodes.push_back(std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_" + config[4], channel_index));
|
|
} else {
|
std::cerr << "Invalid config line: ";
|
for (const auto& param : config) {
|
std::cerr << param << " ";
|
}
|
std::cerr << "\n";
|
}
|
}
|
|
// branch 0
|
auto vehicle_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("vehicle_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
|
|
auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
|
|
// vp_objects::vp_point start(30, 140); // change to proper value 0,250
|
// vp_objects::vp_point end(610, 110); // change to proper value 700,220
|
// std::map<int, vp_objects::vp_line> lines = {{channel_index, vp_objects::vp_line(start, end)}}; // channel0 -> line
|
auto ba_crossline = std::make_shared<vp_nodes::vp_ba_crossline_node>("ba_crossline", lines);
|
|
auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
|
auto osd = std::make_shared<vp_nodes::vp_ba_crossline_osd_node>("osd");
|
auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
|
auto split = std::make_shared<vp_nodes::vp_split_node>("split", true);
|
|
// for testing. USING fake_des node in production
|
auto fake_des_0 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_0", 0);
|
|
// construct pipeline
|
vehicle_detector->attach_to(rtsp_nodes);
|
tracker->attach_to({vehicle_detector});
|
ba_crossline->attach_to({tracker});
|
json_kafka_broker_0->attach_to({ba_crossline});
|
osd->attach_to({json_kafka_broker_0});
|
|
recorder->attach_to({osd});
|
split->attach_to({recorder});
|
|
for (size_t i = 0; i < des_nodes.size(); ++i) {
|
des_nodes[i]->attach_to({split});
|
}
|
|
for (auto node : rtsp_nodes) {
|
((vp_nodes::vp_src_node*)node.get())->start();
|
}
|
|
std::string wait;
|
std::getline(std::cin, wait);
|
|
for (auto node : rtsp_nodes) {
|
((vp_nodes::vp_src_node*)node.get())->detach_recursively();
|
}
|
|
} catch (const std::exception& e) {
|
std::cerr << "read config file ex: " << std::string(e.what()) << " <config_file>\n";
|
} catch (...) {
|
std::cerr << "read config file ex end\n";
|
}
|
|
return 0;
|
}
|