| | |
| | | // for vp_frame_target only
|
| | | for (auto& target : meta->targets) {
|
| | | auto len = target->tracks.size();
|
| | | if (target->primary_label != target->class_label_of_car) {
|
| | | continue;
|
| | | }
|
| | | std::vector<int> involve_targets;
|
| | | if (len > 1 && target->track_id >= 0) {
|
| | | // check the last 2 points in tracks
|
| | |
| | | // `true and false` or `false and true`
|
| | | // means target passed the line in current frame
|
| | | if (check1 ^ check2) {
|
| | | total_crossline++;
|
| | | involve_targets.push_back(target->track_id);
|
| | |
|
| | | // not empty need fill ba result back to frame meta
|
| | | if (involve_targets.size() > 0) {
|
| | | bool is_entering = p1.y > p2.y;
|
| | | total_crossline += (is_entering ? 1 : -1); |
| | | // send record image and record video signal, recording actions would occur if record nodes exist in pipeline
|
| | | std::string image_file_name_without_ext = ""; // empty means no recording image
|
| | | std::string video_file_name_without_ext = ""; // empty means no recording video
|
| | |
| | | meta->frame_index,
|
| | | involve_targets,
|
| | | involve_region,
|
| | | "cross_line", // meaningful label
|
| | | is_entering ? "cross_line_in" : "cross_line_out", // meaningful label
|
| | | image_file_name_without_ext,
|
| | | video_file_name_without_ext);
|
| | | // fill back to frame meta
|
| | |
| | |
|
| | | // for vp_frame_target only
|
| | | std::vector<int> hit_traget_ids;
|
| | | for (auto& target : meta->targets) {
|
| | | auto len = target->tracks.size();
|
| | | auto loc = target->get_rect().track_point();
|
| | |
|
| | | // target has been tracked AND tracked enough frames
|
| | | if (len < check_interval_frames || target->track_id < 0) {
|
| | | continue;
|
| | | }
|
| | | // if target inside of stop region or not
|
| | | if (!point_in_poly(loc, jam_region)) {
|
| | | continue;
|
| | | }
|
| | |
|
| | | auto pre_loc = target->tracks[len - check_interval_frames].track_point();
|
| | | if (pre_loc.distance_with(loc) <= check_max_distance) {
|
| | | stop_checking_status[target->track_id]++;
|
| | | hit_traget_ids.push_back(target->track_id);
|
| | | for (auto &target : meta->targets) {
|
| | | if (target->primary_label != target->class_label_of_person) {
|
| | | auto len = target->tracks.size();
|
| | | auto loc = target->get_rect().track_point();
|
| | | // target has been tracked AND tracked enough frames
|
| | | if (len < check_interval_frames || target->track_id < 0) {
|
| | | continue;
|
| | | }
|
| | | // if target inside of stop region or not
|
| | | if (!point_in_poly(loc, jam_region)) {
|
| | | continue;
|
| | | }
|
| | | auto pre_loc = target->tracks[len - check_interval_frames].track_point();
|
| | | if (pre_loc.distance_with(loc) <= check_max_distance) {
|
| | | stop_checking_status[target->track_id]++;
|
| | | hit_traget_ids.push_back(target->track_id);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | bool point_in_poly(vp_objects::vp_point p, std::vector<vp_objects::vp_point> region);
|
| | |
|
| | | // jam checking logic parameters which may be configed by constructor passed in by user
|
| | | const int check_interval_frames = 20;
|
| | | const int check_min_hit_frames = 25 * 2; // 25 fps * 2 seconds
|
| | | const int check_max_distance = 8;
|
| | | const int check_min_stops = 8;
|
| | | const int check_notify_interval = 10; // interval time (seconds) to notify (ensure not frequently)
|
| | | const int check_interval_frames = 70;
|
| | | const int check_min_hit_frames = 20 * 60 /3; // 25 fps * 2 seconds
|
| | | const int check_max_distance = 10; //The closer the camera, the larger the pixel distance.
|
| | | const int check_min_stops = 2;
|
| | | const int check_notify_interval = 30; // interval time (seconds) to notify (ensure not frequently)
|
| | | protected:
|
| | | virtual std::shared_ptr<vp_objects::vp_meta> handle_frame_meta(std::shared_ptr<vp_objects::vp_frame_meta> meta) override;
|
| | | public:
|
| | |
| | | // for vp_frame_target only
|
| | | std::vector<int> hit_traget_ids;
|
| | | for (auto& target : meta->targets) {
|
| | | auto len = target->tracks.size();
|
| | | auto loc = target->get_rect().track_point();
|
| | | if (target->primary_label == target->class_label_of_car)
|
| | | {
|
| | | auto len = target->tracks.size();
|
| | | auto loc = target->get_rect().track_point();
|
| | |
|
| | | // target has been tracked AND tracked enough frames
|
| | | if (len < check_interval_frames || target->track_id < 0) {
|
| | | continue;
|
| | | }
|
| | | // if target inside of stop region or not
|
| | | if (!point_in_poly(loc, stop_region)) {
|
| | | continue;
|
| | | }
|
| | | // target has been tracked AND tracked enough frames
|
| | | if (len < check_interval_frames || target->track_id < 0) {
|
| | | continue;
|
| | | }
|
| | | // if target inside of stop region or not
|
| | | if (!point_in_poly(loc, stop_region)) {
|
| | | continue;
|
| | | }
|
| | |
|
| | | auto pre_loc = target->tracks[len - check_interval_frames].track_point();
|
| | | if (pre_loc.distance_with(loc) <= check_max_distance) {
|
| | | stop_checking_status[target->track_id]++;
|
| | | hit_traget_ids.push_back(target->track_id);
|
| | | auto pre_loc = target->tracks[len - check_interval_frames].track_point();
|
| | | if (pre_loc.distance_with(loc) <= check_max_distance) {
|
| | | stop_checking_status[target->track_id]++;
|
| | | hit_traget_ids.push_back(target->track_id);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | bool point_in_poly(vp_objects::vp_point p, std::vector<vp_objects::vp_point> region);
|
| | |
|
| | | // stop checking logic parameters which may be configed by constructor passed in by user
|
| | | const int check_interval_frames = 20;
|
| | | const int check_min_hit_frames = 25 * 2; // 25 fps * 2 seconds
|
| | | const int check_max_distance = 5;
|
| | | const int check_interval_frames = 70;
|
| | | const int check_min_hit_frames = 20/3 * 60; // 25 fps * 2 seconds
|
| | | const int check_max_distance = 15; //The closer the camera, the larger the pixel distance.
|
| | | protected:
|
| | | virtual std::shared_ptr<vp_objects::vp_meta> handle_frame_meta(std::shared_ptr<vp_objects::vp_frame_meta> meta) override;
|
| | | public:
|
| New file |
| | |
| | |
|
| | |
|
| | | #include "vp_ba_stop_node.h"
|
| | |
|
| | | namespace vp_nodes {
|
| | | |
| | | vp_ba_stop_node::vp_ba_stop_node(std::string node_name, |
| | | std::map<int, std::vector<vp_objects::vp_point>> stop_regions,
|
| | | bool need_record_image,
|
| | | bool need_record_video):
|
| | | vp_node(node_name), all_stop_regions(stop_regions), need_record_image(need_record_image), need_record_video(need_record_video) {
|
| | | VP_INFO(vp_utils::string_format("[%s] %s", node_name.c_str(), to_string().c_str()));
|
| | | this->initialized();
|
| | | }
|
| | | |
| | | vp_ba_stop_node::~vp_ba_stop_node() {
|
| | | deinitialized();
|
| | | }
|
| | |
|
| | | std::string vp_ba_stop_node::to_string() {
|
| | | /*
|
| | | * return vertexs of all stop regions
|
| | | * [channel0: x1,y1 x2,y2 ...][channel1: x1,y1 x2,y2 ...]...
|
| | | */
|
| | | std::stringstream ss;
|
| | | for(auto& r: all_stop_regions) {
|
| | | ss << "[channel" << r.first << ":";
|
| | | for(auto& p: r.second) {
|
| | | ss << " " << p.x << "," << p.y;
|
| | | }
|
| | | ss << "]";
|
| | | }
|
| | | return ss.str();
|
| | | }
|
| | |
|
| | | bool vp_ba_stop_node::point_in_poly(vp_objects::vp_point p, std::vector<vp_objects::vp_point> region) {
|
| | | int i, j, c = 0;
|
| | | int nvert = region.size();
|
| | |
|
| | | for (i = 0, j = nvert-1; i < nvert; j = i++) {
|
| | | if (((region[i].y > p.y) != (region[j].y > p.y)) &&
|
| | | (p.x < (region[j].x - region[i].x) * (p.y - region[i].y) |
| | | / (region[j].y - region[i].y) + region[i].x))
|
| | | c = !c;
|
| | | }
|
| | | return c;
|
| | | }
|
| | |
|
| | | std::shared_ptr<vp_objects::vp_meta> vp_ba_stop_node::handle_frame_meta(std::shared_ptr<vp_objects::vp_frame_meta> meta) {
|
| | | // if need applied on current channel or not
|
| | | if (all_stop_regions.count(meta->channel_index) == 0) {
|
| | | return meta;
|
| | | }
|
| | | |
| | | // for current channel
|
| | | auto& stop_region = all_stop_regions[meta->channel_index];
|
| | | auto& stop_checking_status = all_stop_checking_status[meta->channel_index];
|
| | |
|
| | | // for vp_frame_target only
|
| | | std::vector<int> hit_traget_ids;
|
| | | for (auto& target : meta->targets) {
|
| | | auto rect = target->get_rect();
|
| | | // VP_INFO(vp_utils::string_format("Target ID: %d, %d, %d, %d, %d, %s ", |
| | | // target->track_id, rect.x, rect.y, rect.width, rect.height, target->primary_label)); |
| | |
|
| | | if (target->primary_label == target->class_label_of_car)
|
| | | { |
| | | auto len = target->tracks.size();
|
| | | auto loc = target->get_rect().track_point();
|
| | |
|
| | | // target has been tracked AND tracked enough frames
|
| | | if (len < check_interval_frames || target->track_id < 0) {
|
| | | continue;
|
| | | }
|
| | | // if target inside of stop region or not
|
| | | if (!point_in_poly(loc, stop_region)) {
|
| | | continue;
|
| | | }
|
| | | |
| | | VP_INFO(vp_utils::string_format("Target ID: %d, %d, %d, %d, %d, %s ", |
| | | target->track_id, rect.x, rect.y, rect.width, rect.height, target->primary_label)); |
| | |
|
| | | auto pre_loc = target->tracks[len - check_interval_frames].track_point();
|
| | | if (pre_loc.distance_with(loc) <= check_max_distance) {
|
| | | stop_checking_status[target->track_id]++;
|
| | | hit_traget_ids.push_back(target->track_id);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | for (auto i = stop_checking_status.begin(); i != stop_checking_status.end();) {
|
| | | if (std::find(hit_traget_ids.begin(), hit_traget_ids.end(), i->first) == hit_traget_ids.end()) {
|
| | | // statisfy unstop condition
|
| | | if (i->second >= check_min_hit_frames) {
|
| | | std::vector<int> involve_targets;
|
| | | involve_targets.push_back(i->first);
|
| | |
|
| | | // send record image and record video signal, recording actions would occur if record nodes exist in pipeline
|
| | | std::string image_file_name_without_ext = ""; // empty means no recording image
|
| | | std::string video_file_name_without_ext = ""; // empty means no recording video
|
| | |
|
| | | // send image record control meta
|
| | | if (need_record_image) {
|
| | | image_file_name_without_ext = vp_utils::time_format(NOW, "unstop_image__<year><mon><day><hour><min><sec><mili>");
|
| | | auto image_record_control_meta = std::make_shared<vp_objects::vp_image_record_control_meta>(meta->channel_index, image_file_name_without_ext, true);
|
| | | pendding_meta(image_record_control_meta);
|
| | | }
|
| | | // send video record control meta
|
| | | if (need_record_video) {
|
| | | video_file_name_without_ext = vp_utils::time_format(NOW, "unstop_video__<year><mon><day><hour><min><sec><mili>"); |
| | | auto video_record_control_meta = std::make_shared<vp_objects::vp_video_record_control_meta>(meta->channel_index, video_file_name_without_ext);
|
| | | pendding_meta(video_record_control_meta);
|
| | | }
|
| | |
|
| | | std::vector<vp_objects::vp_point> involve_region = stop_region;
|
| | | auto ba_result = std::make_shared<vp_objects::vp_ba_result>(vp_objects::vp_ba_type::UNSTOP, |
| | | meta->channel_index, |
| | | meta->frame_index, |
| | | involve_targets, |
| | | involve_region,
|
| | | "unstop", // meaningful label
|
| | | image_file_name_without_ext, |
| | | video_file_name_without_ext);
|
| | | // fill back to frame meta
|
| | | meta->ba_results.push_back(ba_result);
|
| | | // info log
|
| | | VP_INFO(vp_utils::string_format("[%s] [channel %d] has found target unstop", node_name.c_str(), meta->channel_index));
|
| | | if (need_record_image || need_record_video) {
|
| | | VP_INFO(vp_utils::string_format("[%s] [channel %d] image & video record file names are: [%s & %s]", node_name.c_str(), meta->channel_index, image_file_name_without_ext.c_str(), video_file_name_without_ext.c_str()));
|
| | | }
|
| | | }
|
| | | |
| | | // remove since it not satisfy stop condition
|
| | | i = stop_checking_status.erase(i);
|
| | | continue;
|
| | | }
|
| | |
|
| | | // equal means first time to satisfy stop condition
|
| | | if (i->second == check_min_hit_frames) {
|
| | | std::vector<int> involve_targets;
|
| | | involve_targets.push_back(i->first);
|
| | |
|
| | | // send record image and record video signal, recording actions would occur if record nodes exist in pipeline
|
| | | std::string image_file_name_without_ext = ""; // empty means no recording image
|
| | | std::string video_file_name_without_ext = ""; // empty means no recording video
|
| | |
|
| | | // send image record control meta
|
| | | if (need_record_image) {
|
| | | image_file_name_without_ext = vp_utils::time_format(NOW, "stop_image__<year><mon><day><hour><min><sec><mili>");
|
| | | auto image_record_control_meta = std::make_shared<vp_objects::vp_image_record_control_meta>(meta->channel_index, image_file_name_without_ext, true);
|
| | | pendding_meta(image_record_control_meta);
|
| | | }
|
| | | // send video record control meta
|
| | | if (need_record_video) {
|
| | | video_file_name_without_ext = vp_utils::time_format(NOW, "stop_video__<year><mon><day><hour><min><sec><mili>"); |
| | | auto video_record_control_meta = std::make_shared<vp_objects::vp_video_record_control_meta>(meta->channel_index, video_file_name_without_ext);
|
| | | pendding_meta(video_record_control_meta);
|
| | | }
|
| | |
|
| | | std::vector<vp_objects::vp_point> involve_region = stop_region;
|
| | | auto ba_result = std::make_shared<vp_objects::vp_ba_result>(vp_objects::vp_ba_type::STOP, |
| | | meta->channel_index, |
| | | meta->frame_index, |
| | | involve_targets, |
| | | involve_region,
|
| | | "stop", // meaningful label
|
| | | image_file_name_without_ext, |
| | | video_file_name_without_ext);
|
| | | // fill back to frame meta
|
| | | meta->ba_results.push_back(ba_result);
|
| | | // info log
|
| | | VP_INFO(vp_utils::string_format("[%s] [channel %d] has found target stop", node_name.c_str(), meta->channel_index));
|
| | | if (need_record_image || need_record_video) {
|
| | | VP_INFO(vp_utils::string_format("[%s] [channel %d] image & video record file names are: [%s & %s]", node_name.c_str(), meta->channel_index, image_file_name_without_ext.c_str(), video_file_name_without_ext.c_str()));
|
| | | }
|
| | | }
|
| | | i++;
|
| | | }
|
| | | |
| | | return meta;
|
| | | }
|
| | | } |
| New file |
| | |
| | | #pragma once
|
| | |
|
| | | #include <map>
|
| | | #include "../vp_node.h"
|
| | | #include "../../objects/shapes/vp_point.h"
|
| | | #include "../../objects/shapes/vp_line.h"
|
| | | #include "../../objects/vp_image_record_control_meta.h"
|
| | | #include "../../objects/vp_video_record_control_meta.h"
|
| | |
|
| | | namespace vp_nodes {
|
| | | // behaviour analysis node for stop (support multi channels)
|
| | | class vp_ba_stop_node: public vp_node |
| | | {
|
| | | private:
|
| | | // channel -> vertexs of region, 1 channel supports only 1 region at most (can be 0, which means no stop check on this channel)
|
| | | std::map<int, std::vector<vp_objects::vp_point>> all_stop_regions;
|
| | |
|
| | | // channel -> status of targets (id -> num of hit frames)
|
| | | std::map<int, std::map<int, int>> all_stop_checking_status;
|
| | | std::ofstream record_file; // File stream for recording |
| | |
|
| | | // record params
|
| | | bool need_record_image;
|
| | | bool need_record_video;
|
| | |
|
| | | // check if point inside of polygon
|
| | | bool point_in_poly(vp_objects::vp_point p, std::vector<vp_objects::vp_point> region);
|
| | |
|
| | | // stop checking logic parameters which may be configed by constructor passed in by user
|
| | | const int check_interval_frames = 70;
|
| | | const int check_min_hit_frames = 20/3 * 60; // 25 fps * 2 seconds
|
| | | const int check_max_distance = 15; //The closer the camera, the larger the pixel distance
|
| | | |
| | | void open_record_file();
|
| | | void close_record_file(); |
| | | protected:
|
| | | virtual std::shared_ptr<vp_objects::vp_meta> handle_frame_meta(std::shared_ptr<vp_objects::vp_frame_meta> meta) override;
|
| | | public:
|
| | | vp_ba_stop_node(std::string node_name, |
| | | std::map<int, std::vector<vp_objects::vp_point>> stop_regions,
|
| | | bool need_record_image = true,
|
| | | bool need_record_video = true);
|
| | | ~vp_ba_stop_node();
|
| | | std::string to_string() override;
|
| | | };
|
| | | } |
| | |
| | | int input_height = 416,
|
| | | int batch_size = 1,
|
| | | int class_id_offset = 0,
|
| | | float score_threshold = 0.5,
|
| | | float score_threshold = 0.7,
|
| | | float confidence_threshold = 0.5,
|
| | | float nms_threshold = 0.5,
|
| | | float scale = 1 / 255.0,
|
| | |
| | | // track_id
|
| | | auto id = std::to_string(i->track_id);
|
| | | auto labels_to_display = i->primary_label;
|
| | | auto primary_score_ = std::to_string(i->primary_score);
|
| | |
|
| | | // tracked
|
| | | if (i->track_id != -1) {
|
| | |
| | | }
|
| | |
|
| | | for (auto& label : i->secondary_labels) {
|
| | | labels_to_display += "|" + label;
|
| | | labels_to_display += "|" + label + "|" + primary_score_;
|
| | | }
|
| | |
|
| | | // draw tracks if size>=2
|
| | |
| | |
|
| | | #include <fstream>
|
| | | #include <iostream>
|
| | |
|
| | | #include "vp_infer_node.h"
|
| | |
|
| | |
| | | // try to load network from file,
|
| | | // failing means maybe it has a custom implementation for model loading in derived class such as using other backends other than opencv::dnn.
|
| | | try {
|
| | | std::cout << "Model path: " << model_path << std::endl;
|
| | | std::cout << "Model config path: " << model_config_path << std::endl;
|
| | | net = cv::dnn::readNet(model_path, model_config_path);
|
| | | #ifdef VP_WITH_CUDA
|
| | | net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
|
| | |
| | | result += buffer;
|
| | | }
|
| | | pclose(pipe);
|
| | | VP_INFO(vp_utils::string_format("FFPROBE RESULT:%s ", result));
|
| | | VP_INFO(vp_utils::string_format("FFPROBE RESULT:%s url: %s", result, rtsp_url.c_str()));
|
| | |
|
| | | // Parse the output (expected format: width,height,r_frame_rate)
|
| | | std::stringstream ss(result);
|
| | |
| | | {
|
| | | return rtsp_url;
|
| | | }
|
| | | }
|
| | | } |
| | |
| | | public:
|
| | | // default person label
|
| | | std::string class_label_of_person = "person";
|
| | | // default car label
|
| | | std::string class_label_of_car = "car";
|
| | | // default trush label
|
| | | std::string class_label_of_trush = "trush"; |
| | | // x of top left
|
| | | int x;
|
| | | // y of top left
|
| | |
| | | message(FATAL_ERROR "can ONLY be called by parent CMakeLists.txt.")
|
| | | endif()
|
| | |
|
| | | # 查找 pkg-config 包
|
| | | find_package(PkgConfig REQUIRED)
|
| | |
|
| | | # 使用 pkg-config 查找 GStreamer 和 gstreamer-rtsp-server
|
| | | pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
|
| | | pkg_check_modules(GSTREAMER_RTSP_SERVER REQUIRED gstreamer-rtsp-server-1.0)
|
| | |
|
| | | # 将 GStreamer 和 RTSP 头文件路径添加到 include 目录中
|
| | | include_directories(${GSTREAMER_INCLUDE_DIRS} ${GSTREAMER_RTSP_SERVER_INCLUDE_DIRS})
|
| | |
|
| | | # 将库路径添加到链接目录
|
| | | link_directories(${GSTREAMER_LIBRARY_DIRS} ${GSTREAMER_RTSP_SERVER_LIBRARY_DIRS})
|
| | |
|
| | | # 通过 pkg-config 提供的 flags,设置编译和链接的 flags
|
| | | add_definitions(${GSTREAMER_DEFINITIONS} ${GSTREAMER_RTSP_SERVER_DEFINITIONS})
|
| | |
|
| | | # 在编译时链接 GStreamer 和 RTSP 相关的库
|
| | | #target_link_libraries(your_target_name |
| | | # ${GSTREAMER_LIBRARIES} |
| | | # ${GSTREAMER_RTSP_SERVER_LIBRARIES}
|
| | | #)
|
| | |
|
| | |
|
| | | message("start build for simple samples...")
|
| | | # save all exe to 'build/bin'
|
| | | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
| | |
| | |
|
| | | add_executable(from_argv_ba_jam_rtsp_m "from_argv_ba_jam_rtsp_m.cpp")
|
| | | target_link_libraries(from_argv_ba_jam_rtsp_m ${PROJECT_NAME})
|
| | |
|
| | | |
| | | add_executable(from_argv_ba_jam_rtsp_mr "from_argv_ba_jam_rtsp_mr.cpp")
|
| | | target_link_libraries(from_argv_ba_jam_rtsp_mr ${PROJECT_NAME})
|
| | |
|
| | | add_executable(from_argv_ba_stop "from_argv_ba_stop.cpp")
|
| | | target_link_libraries(from_argv_ba_stop ${PROJECT_NAME})
|
| | |
| | | return -1;
|
| | | }
|
| | |
|
| | | // create nodes
|
| | | auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
|
| | | // create nodes bool cycle = true, std::string gst_decoder_name = "avdec_h264", int skip_interval = 0
|
| | | auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio, true, "avdec_h264",3);
|
| | | //auto file_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_1", 1, "./vp_data/test_video/falldown.mp4", 0.5);
|
| | | //auto split = std::make_shared<vp_nodes::vp_split_node>("split", false, true); // split by deep-copy not by channel!
|
| | |
|
| | |
| | |
|
| | | auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
|
| | |
|
| | | // define a region in frame for every channel (value MUST in the scope of frame'size)
|
| | | // define a region in frame for every channel (value MUST in the scope of frame'size) (224,74),(346,64),(486,342),(9,342) vp_point(450, 100), vp_objects::vp_point(792, 80), vp_objects::vp_point(1100, 684), vp_objects::vp_point(18, 682)
|
| | | std::map<int, std::vector<vp_objects::vp_point>> regions = {
|
| | | {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(20, 30), vp_objects::vp_point(600, 40), vp_objects::vp_point(600, 300), vp_objects::vp_point(10, 300)}}, // channel0 -> region
|
| | | {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(20, 30), vp_objects::vp_point(1000, 40), vp_objects::vp_point(1000, 600), vp_objects::vp_point(10, 600)}} // channel1 -> region
|
| | | };
|
| | | {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(int(616*resize_ratio), int(13*resize_ratio)), |
| | | vp_objects::vp_point(int(670*resize_ratio), int(11*resize_ratio)), |
| | | vp_objects::vp_point(int(1100*resize_ratio), int(684*resize_ratio)), |
| | | vp_objects::vp_point(int(18*resize_ratio), int(610*resize_ratio))}}, // channel0 -> region
|
| | | };
|
| | | auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
|
| | | auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
|
| | |
|
| | |
| | | vp_objects::vp_point right_end(10, 10); // change to proper value
|
| | | std::map<int, std::vector<vp_objects::vp_point>> left_lines = {{0, {left_start, left_end}}}; // channel0 -> point vector
|
| | | std::map<int, std::vector<vp_objects::vp_point>> right_lines = {{0, {right_start, right_end}}}; // channel0 -> point vector
|
| | | int half_screen_width = 384;
|
| | | int half_screen_width = 640;
|
| | | auto ba_wrong_direction = std::make_shared<vp_nodes::vp_ba_wrong_direction_node>("vp_ba_wrong_direction_node", left_lines,right_lines,half_screen_width,true,true);
|
| | |
|
| | | int min_gathering_count = 2;
|
| | |
| | | auto ba_report_detect = std::make_shared<vp_nodes::vp_ba_report_detect_node>("ba_report_detect_node","fire_smoke",std::vector<int>{1000,1001,1002}, true,true);
|
| | |
|
| | |
|
| | | auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", "192.168.0.85:9092", "vp_ba_vehicle", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", "172.18.0.247:9092", "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0");
|
| | | auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
|
| | |
|
| | |
| | | file_src_0->start();
|
| | |
|
| | | // for debug purpose
|
| | | vp_utils::vp_analysis_board board({file_src_0});
|
| | | board.display(1, false);
|
| | | // vp_utils::vp_analysis_board board({file_src_0});
|
| | | // board.display(1, false);
|
| | |
|
| | | std::string wait;
|
| | | std::getline(std::cin, wait);
|
| | |
| | |
|
| | |
|
| | | // create nodes
|
| | | auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
|
| | | //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
|
| | | auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_1", 0, video_path, resize_ratio, 3, false); |
| | | auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_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");
|
| | |
|
| | | // define a line in frame for every channel (value MUST in the scope of frame'size)
|
| | | vp_objects::vp_point start(0, 250); // change to proper value
|
| | | vp_objects::vp_point end(700, 220); // change to proper value
|
| | | 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 = {{0, 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", "192.168.130.228:9092", "vp_ba_crossline", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", "172.18.0.247:9092", "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto osd = std::make_shared<vp_nodes::vp_ba_crossline_osd_node>("osd");
|
| | | auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
|
| | |
|
| New file |
| | |
| | | #include "../nodes/vp_file_src_node.h"
|
| | | #include "../nodes/infers/vp_yolo_detector_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/vp_screen_des_node.h"
|
| | | #include "../nodes/vp_rtmp_des_node.h"
|
| | | #include "../nodes/broker/vp_json_kafka_broker_node.h"
|
| | |
|
| | | #include "../utils/analysis_board/vp_analysis_board.h"
|
| | |
|
| | | /*
|
| | | * ## ba crossline sample ##
|
| | | * behaviour analysis for crossline.
|
| | | */
|
| | |
|
| | | int main(int argc, char* argv[]) {
|
| | | VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
|
| | | VP_LOGGER_INIT();
|
| | |
|
| | | std::vector<std::string> args(argv + 1, argv + argc);
|
| | | // 默认的命令行参数
|
| | | std::string video_path = "./vp_data/test_video/vehicle_count.mp4";
|
| | |
|
| | | float resize_ratio = 0.4;
|
| | |
|
| | | // 如果提供了第一个和第二个参数,则覆盖默认的路径
|
| | | if (args.size() >= 1) {
|
| | | video_path = args[0];
|
| | | if (args.size() >= 2){
|
| | | resize_ratio = std::stof(args[1]);
|
| | | }
|
| | | } else {
|
| | | std::cout << "Usage: " << argv[0] << " <video_path> [resize_ratio]\n";
|
| | | std::cout << "Example: " << argv[0] << " ./vp_data/test_video/vehicle_count.mp4 0.4\n";
|
| | | return -1;
|
| | | }
|
| | |
|
| | |
|
| | | // create nodes
|
| | | auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
|
| | | auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_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");
|
| | | |
| | | // define a line in frame for every channel (value MUST in the scope of frame'size)
|
| | | vp_objects::vp_point start(0, 250); // change to proper value
|
| | | vp_objects::vp_point end(700, 220); // change to proper value
|
| | | std::map<int, vp_objects::vp_line> lines = {{0, 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", "192.168.130.228:9092", "vp_ba_crossline", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto osd = std::make_shared<vp_nodes::vp_ba_crossline_osd_node>("osd");
|
| | | auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
|
| | | |
| | | // construct pipeline
|
| | | yolo_detector->attach_to({file_src_0});
|
| | | tracker->attach_to({yolo_detector});
|
| | | ba_crossline->attach_to({tracker});
|
| | | json_kafka_broker_0->attach_to({ba_crossline});
|
| | | osd->attach_to({json_kafka_broker_0});
|
| | | screen_des_0->attach_to({osd});
|
| | |
|
| | | file_src_0->start();
|
| | |
|
| | | // for debug purpose
|
| | | vp_utils::vp_analysis_board board({file_src_0});
|
| | | board.display(1, false);
|
| | |
|
| | | std::string wait;
|
| | | std::getline(std::cin, wait);
|
| | | file_src_0->detach_recursively();
|
| | | } |
| | |
| | | #include "../nodes/vp_file_src_node.h"
|
| | | #include "../nodes/vp_rtsp_src_node.h"
|
| | |
|
| | | #include "../nodes/vp_rtsp_ffmpeg_src_node.h"
|
| | | #include "../nodes/infers/vp_yolo_detector_node.h"
|
| | | #include "../nodes/track/vp_sort_track_node.h"
|
| | | #include "../nodes/ba/vp_ba_crossline_node.h"
|
| | |
| | | #include "../nodes/vp_screen_des_node.h"
|
| | | #include "../nodes/vp_rtmp_des_node.h"
|
| | | #include "../nodes/broker/vp_json_kafka_broker_node.h"
|
| | | #include "../nodes/vp_file_des_node.h"
|
| | |
|
| | | #include "../utils/analysis_board/vp_analysis_board.h"
|
| | |
|
| | |
| | |
|
| | | std::vector<std::string> args(argv + 1, argv + argc);
|
| | | // 默认的命令行参数
|
| | | std::string rtsp_path = "rtsp://192.168.1.24:8554/demo";
|
| | | std::string kafka_server_point = "192.168.130.228:9092";
|
| | | std::string video_path = "./vp_data/test_video/vehicle_count.mp4";
|
| | |
|
| | | float resize_ratio = 0.4;
|
| | |
|
| | | int channel_index = 0;
|
| | | int skip_interval = 4;
|
| | | // 如果提供了第一个和第二个参数,则覆盖默认的路径
|
| | | if (args.size() >= 3) {
|
| | | rtsp_path = args[0];
|
| | | if (args.size() >= 4) {
|
| | | video_path = args[0];
|
| | | resize_ratio = std::stof(args[1]);
|
| | | kafka_server_point = args[2];
|
| | | |
| | | channel_index = std::stof(args[2]);
|
| | | skip_interval = std::stof(args[3]);
|
| | | } else {
|
| | | std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point>\n";
|
| | | std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.130.228:9092\n";
|
| | | std::cout << "Usage: " << argv[0] << " <video_path> [resize_ratio]\n";
|
| | | std::cout << "Example: " << argv[0] << " ./vp_data/test_video/vehicle_count.mp4 0.4\n";
|
| | | return -1;
|
| | | }
|
| | |
|
| | |
|
| | | // create nodes
|
| | | //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
|
| | | auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264"); |
| | | auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_"+channel_index, channel_index, video_path, resize_ratio, skip_interval, false); |
| | | auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_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");
|
| | |
|
| | | // define a line in frame for every channel (value MUST in the scope of frame'size)
|
| | | 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 = {{0, vp_objects::vp_line(start, end)}}; // channel0 -> line
|
| | | 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_crossline", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_"+channel_index, "172.18.0.247:9092", "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto osd = std::make_shared<vp_nodes::vp_ba_crossline_osd_node>("osd");
|
| | | auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
|
| | | auto file_des_node_0 = std::make_shared<vp_nodes::vp_file_des_node>("file_des_0", 0, "out-a-osd", "out-a-osd", 1);
|
| | | auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", channel_index);
|
| | |
|
| | | // construct pipeline
|
| | | yolo_detector->attach_to({rtsp_src_1});
|
| | | yolo_detector->attach_to({file_src_0});
|
| | | tracker->attach_to({yolo_detector});
|
| | | ba_crossline->attach_to({tracker});
|
| | | json_kafka_broker_0->attach_to({ba_crossline});
|
| | | osd->attach_to({json_kafka_broker_0});
|
| | | screen_des_0->attach_to({osd});
|
| | | file_des_node_0->attach_to({osd});
|
| | |
|
| | | rtsp_src_1->start();
|
| | | file_src_0->start();
|
| | |
|
| | | // for debug purpose
|
| | | vp_utils::vp_analysis_board board({rtsp_src_1});
|
| | | vp_utils::vp_analysis_board board({file_src_0});
|
| | | board.display(1, false);
|
| | |
|
| | | std::string wait;
|
| | | std::getline(std::cin, wait);
|
| | | rtsp_src_1->detach_recursively();
|
| | | file_src_0->detach_recursively();
|
| | | } |
| New file |
| | |
| | | #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;
|
| | | } |
| | |
| | | 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));
|
| | | //des_nodes.push_back(std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_" + config[4], channel_index));
|
| | | des_nodes.push_back(std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_" + config[4], channel_index));
|
| | |
|
| | | } else {
|
| | | std::cerr << "Invalid config line: ";
|
| | |
| | | auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
|
| | | 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);
|
| | |
| | | }
|
| | |
|
| | | // for debug purpose
|
| | | // vp_utils::vp_analysis_board board(rtsp_nodes);
|
| | | // board.display(1, false);
|
| | | vp_utils::vp_analysis_board board(rtsp_nodes);
|
| | | board.display(1, true);
|
| | |
|
| | | std::string wait;
|
| | | std::getline(std::cin, wait);
|
| New file |
| | |
| | | #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_jam_node.h"
|
| | | #include "../nodes/ba/vp_ba_stop_node.h"
|
| | |
|
| | | #include "../nodes/osd/vp_ba_stop_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, std::vector<vp_objects::vp_point>> regions = {};
|
| | |
|
| | | 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
|
| | | regions[channel_index] = parse_polygon(polygon_str,resize_ratio);
|
| | | } else {
|
| | | // Default region if polygon is not provided
|
| | | regions[channel_index] = std::vector<vp_objects::vp_point>{
|
| | | vp_objects::vp_point(280, 30),
|
| | | vp_objects::vp_point(340, 30),
|
| | | vp_objects::vp_point(600, 330),
|
| | | vp_objects::vp_point(30, 350)
|
| | | };
|
| | | }
|
| | |
|
| | | 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 trt_vehicle_plate_detector = std::make_shared<vp_nodes::vp_trt_vehicle_plate_detector>("vehicle_plate_detector", "./vp_data/models/trt/plate/vehicle_plate_box_detection.trt", "./vp_data/models/trt/plate/vehicle_plate_text_recognition.trt");
|
| | | auto trt_vehicle_color_classifier = std::make_shared<vp_nodes::vp_trt_vehicle_color_classifier>("color_cls", "./vp_data/models/trt/vehicle/vehicle_color_detection.trt", std::vector<int>{0, 1, 2});
|
| | |
|
| | | auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
|
| | |
|
| | | auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
|
| | | auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
|
| | |
|
| | | 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_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
|
| | | 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);
|
| | | trt_vehicle_plate_detector->attach_to({vehicle_detector});
|
| | | trt_vehicle_color_classifier->attach_to({trt_vehicle_plate_detector});
|
| | | tracker->attach_to({trt_vehicle_color_classifier});
|
| | | ba_jam->attach_to({tracker});
|
| | | ba_stop->attach_to({ba_jam});
|
| | | json_kafka_broker_0->attach_to({ba_stop});
|
| | | osd_0->attach_to({json_kafka_broker_0});
|
| | |
|
| | | recorder->attach_to({osd_0});
|
| | | 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;
|
| | | } |
| New file |
| | |
| | | #include <iostream>
|
| | | #include <fstream>
|
| | | #include <sstream>
|
| | | #include <vector>
|
| | | #include <regex>
|
| | | #include <cmath>
|
| | | #include <limits>
|
| | |
|
| | | using namespace std;
|
| | |
|
| | | // 定义一个结构体来保存每一行的值
|
| | | struct TargetData {
|
| | | int id;
|
| | | double x, y, width, height;
|
| | | };
|
| | |
|
| | | // 读取日志文件并提取目标数据
|
| | | vector<TargetData> readLogFile(const string& filepath) {
|
| | | vector<TargetData> data;
|
| | | ifstream file(filepath);
|
| | | string line;
|
| | |
|
| | | // 正则表达式来匹配Target ID后的五个值
|
| | | regex targetRegex("Target ID: (-?\\d+),\\s*(-?\\d+),\\s*(-?\\d+),\\s*(-?\\d+),\\s*(-?\\d+)");
|
| | |
|
| | | while (getline(file, line)) {
|
| | | smatch matches;
|
| | | if (regex_search(line, matches, targetRegex)) {
|
| | | TargetData target;
|
| | | target.id = stoi(matches[1].str());
|
| | | target.x = stod(matches[2].str());
|
| | | target.y = stod(matches[3].str());
|
| | | target.width = stod(matches[4].str());
|
| | | target.height = stod(matches[5].str());
|
| | |
|
| | | data.push_back(target);
|
| | | }
|
| | | }
|
| | | return data;
|
| | | }
|
| | |
|
| | | // 清洗数据,去掉横坐标小于100或大于600的数据,以及极端值
|
| | | void cleanData(vector<TargetData>& data, double n) {
|
| | | // 计算平均值
|
| | | double sum = 0;
|
| | | for (const auto& target : data) {
|
| | | sum += target.width;
|
| | | }
|
| | | double mean = sum / data.size();
|
| | |
|
| | | // 计算标准差
|
| | | double variance = 0;
|
| | | for (const auto& target : data) {
|
| | | variance += pow(target.width - mean, 2);
|
| | | }
|
| | | double stddev = sqrt(variance / data.size());
|
| | |
|
| | | // 根据误差系数范围n清洗数据
|
| | | vector<TargetData> cleanedData;
|
| | | for (const auto& target : data) {
|
| | | // 添加条件,去掉横坐标小于100或大于600的数据
|
| | | if (target.x >= 100 && target.x <= 600 &&
|
| | | abs(target.width - mean) <= n * stddev) {
|
| | | cleanedData.push_back(target);
|
| | | }
|
| | | }
|
| | |
|
| | | data = cleanedData;
|
| | | }
|
| | |
|
| | | // 用最小二乘法来计算线性回归的参数 (width = a * y + b)
|
| | | void fitLinearModel(const vector<TargetData>& data, double& a, double& b) {
|
| | | int n = data.size();
|
| | | double sum_y = 0, sum_width = 0, sum_yy = 0, sum_yw = 0;
|
| | |
|
| | | // 计算所需的累加和
|
| | | for (const auto& target : data) {
|
| | | sum_y += target.y;
|
| | | sum_width += target.width;
|
| | | sum_yy += target.y * target.y;
|
| | | sum_yw += target.y * target.width;
|
| | | }
|
| | |
|
| | | // 计算线性回归的系数 a 和 b
|
| | | double denominator = n * sum_yy - sum_y * sum_y;
|
| | | if (denominator == 0) {
|
| | | a = 0;
|
| | | b = 0;
|
| | | return;
|
| | | }
|
| | |
|
| | | a = (n * sum_yw - sum_y * sum_width) / denominator;
|
| | | b = (sum_yy * sum_width - sum_y * sum_yw) / denominator;
|
| | | }
|
| | |
|
| | | // 输出拟合结果
|
| | | void printFitEquation(double a, double b) {
|
| | | cout << "拟合结果: width = " << a << " * y + " << b << endl;
|
| | | }
|
| | |
|
| | | // 打印data中的所有数据
|
| | | void printData(const vector<TargetData>& data) {
|
| | | for (const auto& target : data) {
|
| | | cout << "ID: " << target.id |
| | | << ", x: " << target.x |
| | | << ", y: " << target.y |
| | | << ", width: " << target.width |
| | | << ", height: " << target.height << endl;
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | int main(int argc, char* argv[]) {
|
| | | if (argc < 3) {
|
| | | cout << "使用方法: " << argv[0] << " <日志文件路径> <误差系数范围>" << endl;
|
| | | return 1;
|
| | | }
|
| | |
|
| | | string logFilePath = argv[1];
|
| | | double n = stod(argv[2]); // 误差系数范围
|
| | |
|
| | | // 读取日志文件中的目标数据
|
| | | vector<TargetData> data = readLogFile(logFilePath);
|
| | |
|
| | | // 数据清洗
|
| | | cleanData(data, n);
|
| | |
|
| | | // 打印清洗后的数据
|
| | | cout << "\n清洗后的数据:" << endl;
|
| | | printData(data);
|
| | |
|
| | | // 使用最小二乘法拟合数据
|
| | | double a, b;
|
| | | fitLinearModel(data, a, b);
|
| | |
|
| | | // 输出拟合的函数公式
|
| | | printFitEquation(a, b);
|
| | |
|
| | | return 0;
|
| | | } |
| New file |
| | |
| | | #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_jam_node.h"
|
| | | #include "../nodes/ba/vp_ba_stop_node.h"
|
| | |
|
| | | #include "../nodes/osd/vp_ba_stop_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, std::vector<vp_objects::vp_point>> regions = {};
|
| | |
|
| | | 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
|
| | | regions[channel_index] = parse_polygon(polygon_str,resize_ratio);
|
| | | } else {
|
| | | // Default region if polygon is not provided
|
| | | regions[channel_index] = std::vector<vp_objects::vp_point>{
|
| | | vp_objects::vp_point(280, 30),
|
| | | vp_objects::vp_point(340, 30),
|
| | | vp_objects::vp_point(600, 330),
|
| | | vp_objects::vp_point(30, 350)
|
| | | };
|
| | | }
|
| | |
|
| | | 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");
|
| | |
|
| | | auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
|
| | |
|
| | | auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_tracker", vp_nodes::vp_broke_for::BARESULT);
|
| | | auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
|
| | | 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_stop->attach_to({tracker});
|
| | | json_kafka_broker_0->attach_to({ba_stop});
|
| | | osd_0->attach_to({json_kafka_broker_0});
|
| | |
|
| | | recorder->attach_to({osd_0});
|
| | | 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;
|
| | | } |