wangrong
2025-01-18 8b0e31121a9a29b92a41fc575138a2e9b4c12d8e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
 
 
#include "vp_plate_socket_broker_node.h"
 
 
namespace vp_nodes {
        
    vp_plate_socket_broker_node::vp_plate_socket_broker_node(std::string node_name,
                                                        std::string des_ip,
                                                        int des_port,
                                                        std::string plates_dir,
                                                        int min_crop_width,
                                                        int min_crop_height,
                                                        vp_broke_for broke_for, 
                                                        bool only_for_tracked,
                                                        int broking_cache_warn_threshold, 
                                                        int broking_cache_ignore_threshold):
                                                        vp_msg_broker_node(node_name, broke_for, broking_cache_warn_threshold, broking_cache_ignore_threshold),
                                                        des_ip(des_ip),
                                                        des_port(des_port),
                                                        plates_dir(plates_dir),
                                                        min_crop_width(min_crop_width),
                                                        min_crop_height(min_crop_height),
                                                        only_for_tracked(only_for_tracked) {
        // only for vp_frame_target                                                    
        assert(broke_for == vp_broke_for::NORMAL);
        udp_writer = kissnet::udp_socket(kissnet::endpoint(des_ip, des_port));
        VP_INFO(vp_utils::string_format("[%s] [message broker] set des_ip as `%s` and des_port as [%d]", node_name.c_str(), des_ip.c_str(), des_port));
        this->initialized();
    }
    
    vp_plate_socket_broker_node::~vp_plate_socket_broker_node() {
        deinitialized();
        stop_broking();
    }
 
    void vp_plate_socket_broker_node::format_msg(const std::shared_ptr<vp_objects::vp_frame_meta>& meta, std::string& msg) {
        /* format:
        line 0, <--
        line 1, 1st time
        line 2, 1st channel index, frame index
        line 3, 1st the cropped image's path
        line 4, 1st the whole image's path
        line 5, 1st plate color
        line 6, 1st plate text
        line 7, -->
        line 8, <--
        line 9, 2nd time
        line 10, 2nd channel index, frame index
        line 11, 2nd the cropped image's path
        line 12, 2nd the whole image's path
        line 13, 2nd plate color
        line 14, 2nd plate text
        line 15, -->
        line 16, ...
        */
        auto& broked_ids = all_broked_ids[meta->channel_index];
        auto& broked_texts = all_broked_texts[meta->channel_index];
        // remove 50 elements every 100 ids
        if (broked_ids.size() > 100) {
            broked_ids.erase(broked_ids.begin(), broked_ids.begin() + 50);
        }
        if (broked_texts.size() > 100) {
            broked_texts.erase(broked_texts.begin(), broked_texts.begin() + 50);
        }
 
        std::stringstream msg_stream;
        auto format_basic_info = [&](int channel_index, int frame_index) {
            msg_stream << vp_utils::time_format(NOW) << std::endl;           // line1
            msg_stream << channel_index << "," << frame_index << std::endl;  // line2
        };
        auto save_cropped_image = [&](cv::Mat& frame, cv::Rect rect, std::string name) {
            auto cropped = frame(rect);
            cv::imwrite(name, cropped);
            msg_stream << name << std::endl;  // line3
        };
        auto save_whole_image = [&](cv::Mat& frame, std::string name) {
            cv::imwrite(name, frame);
            msg_stream << name << std::endl;  // line4
        };
        auto format_plate = [&](const std::string& plate_color, const std::string& plate_text) {
            msg_stream << plate_color << std::endl;  // line5          
            msg_stream << plate_text << std::endl;   // line6
        };
        if (broke_for == vp_broke_for::NORMAL) {
            for (int i = 0; i < meta->targets.size(); i++) {
                auto& t = meta->targets[i];
                // only broke for tracked targets and have enough frames
                if ((only_for_tracked && t->track_id < 0) || (only_for_tracked && t->tracks.size() < min_tracked_frames)) {
                    continue;
                }
                
                // only broke 1 time for specific track id if it has been tracked, or broke many times
                if (t->track_id >= 0 && 
                    std::find(broked_ids.begin(), broked_ids.end(), t->track_id) != broked_ids.end()) {
                    broked_ids.push_back(t->track_id);
                    continue;
                }
 
                // size filter
                if (t->width < min_crop_width || t->height < min_crop_height) {
                    continue;
                }
 
                auto color_and_text = vp_utils::string_split(t->primary_label, '_');
                // make sure plate text and color detected
                if(color_and_text.size() != 2) {
                    continue;
                }
                auto& color = color_and_text[0];
                auto& text = color_and_text[1];
                // check for length, 7 or 3 + 6 or 3 + 7
                if (text.length() != 7 && text.length() != 9 && text.length() != 10) {
                    continue;
                }
 
                // only broke 1 time for specific plate text in small period
                if (std::find(broked_texts.begin(), broked_texts.end(), text) != broked_texts.end()) {
                    broked_texts.push_back(text);
                    continue;
                }
                
                // cache for texts
                broked_texts.push_back(text);
                // cache for ids
                if (t->track_id >= 0) {
                    broked_ids.push_back(t->track_id);
                }
 
                auto cropped_name = plates_dir + "/" + std::to_string(t->channel_index) + "_" + std::to_string(t->frame_index) + "_" + color + "_" + text  + "_cropped.jpg";
                auto whole_name = plates_dir + "/" + std::to_string(t->channel_index) + "_" + std::to_string(t->frame_index) + "_" + color + "_" + text  + "_whole.jpg";
                // start flag
                msg_stream << "<--" << std::endl;
                // basic info
                format_basic_info(meta->channel_index, meta->frame_index);
                // save small cropped image
                save_cropped_image(meta->frame, cv::Rect(t->x, t->y, t->width, t->height), cropped_name);
                // save whole image
                save_whole_image(meta->frame, whole_name);
                // format color and text
                format_plate(color, text);
                // end flag
                msg_stream << "-->";
                
                if (i != meta->targets.size() - 1) {
                    msg_stream << std::endl;  // not the last one
                }
            }
        }
        
        msg = msg_stream.str();   
    }
 
    void vp_plate_socket_broker_node::broke_msg(const std::string& msg) {
        // broke msg to socket by udp
        auto bytes_2_send = reinterpret_cast<const std::byte*>(msg.c_str());
        auto bytes_2_send_len = msg.size();
        udp_writer.send(bytes_2_send, bytes_2_send_len);
    }
}