wangrong
2025-03-19 291afb9c81aae1d15d9e3edcea618d0a2e1fc5a6
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
 
#include <opencv2/imgproc.hpp>
#include "vp_osd_node_v2.h"
#include "../../utils/vp_utils.h"
 
 
namespace vp_nodes {
    
    vp_osd_node_v2::vp_osd_node_v2(std::string node_name, std::string font):vp_node(node_name) {
        if (!font.empty()) {
            ft2 = cv::freetype::createFreeType2();
            ft2->loadFontData(font, 0);   
        }     
        this->initialized();  
    }
    
    vp_osd_node_v2::~vp_osd_node_v2() {
        deinitialized();
    }
 
    std::shared_ptr<vp_objects::vp_meta> vp_osd_node_v2::handle_frame_meta(std::shared_ptr<vp_objects::vp_frame_meta> meta) {
        // operations on osd_frame
        if (meta->osd_frame.empty()) {
            // add a gap at the bottom of osd frame
            meta->osd_frame = cv::Mat(meta->frame.rows + gap_height + padding * 2, meta->frame.cols, meta->frame.type(), cv::Scalar(128, 128, 128));
            
            // initialize by copying frame to osd frame
            auto roi = meta->osd_frame(cv::Rect(0, 0, meta->frame.cols, meta->frame.rows));
            meta->frame.copyTo(roi);
        }
        auto& canvas = meta->osd_frame;
 
        auto base_left = padding;
        // scan targets
        for (int i = 0; i < meta->targets.size(); i++) {
            auto& target = meta->targets[i];
 
            // scan sub targets
            for (int j = 0; j < target->sub_targets.size(); j++) {
                auto& sub_target = target->sub_targets[j];
                cv::rectangle(canvas, cv::Rect(sub_target->x, sub_target->y, sub_target->width, sub_target->height), cv::Scalar(255, 255, 255), 2);
 
                auto roi = canvas(cv::Rect(base_left, meta->osd_frame.rows - padding - gap_height, gap_height, gap_height));
                // white background
                roi = cv::Scalar(255, 255, 255);
 
                auto ori = canvas(cv::Rect(sub_target->x, sub_target->y, sub_target->width, sub_target->height));                
                cv::Mat tmp = ori.clone();
                int offset_w = 0, offset_h = 0;
                if (tmp.rows > tmp.cols) {
                    cv::resize(tmp, tmp, cv::Size(int(float(gap_height) / tmp.rows * tmp.cols) , gap_height));
                    offset_w = (gap_height - tmp.cols) / 2;
                    offset_h = 0;
                }
                else {
                    cv::resize(tmp, tmp, cv::Size(gap_height, int(float(gap_height) / tmp.cols * tmp.rows)));
                    offset_h = (gap_height - tmp.rows) / 2;
                    offset_w = 0;
                }
 
                // copy sub target to the bottom of screen
                roi = canvas(cv::Rect(base_left + offset_w, meta->osd_frame.rows - padding - gap_height + offset_h, tmp.cols, tmp.rows));
                tmp.copyTo(roi);
 
                // line from target to sub target
                cv::line(canvas, cv::Point(target->x + target->width / 2, target->y + target->height), cv::Point(base_left + gap_height / 2, meta->osd_frame.rows - padding - gap_height), cv::Scalar(255, 0, 0), 3, cv::LINE_AA);
 
                // label of sub target
                auto sub_label = vp_utils::string_split(sub_target->label, '_');
                
                // !!!
                // for plate sub target (color_text)
                if (sub_label.size() == 2) {
                    assert(ft2 != nullptr);
                    ft2->putText(canvas, sub_label[1], cv::Point(base_left + 10, meta->osd_frame.rows - padding - 5), 36, cv::Scalar(0), cv::FILLED, cv::LINE_AA, true);
                }
                base_left += gap_height + padding;                
            }
 
            // target
            auto labels_to_display = target->primary_label;
            for (auto& label : target->secondary_labels) {
                labels_to_display += "/" + label;
            }
            
            cv::rectangle(canvas, cv::Rect(target->x, target->y, target->width, target->height), cv::Scalar(255, 255, 0), 3);
            if (ft2 != nullptr) {
                ft2->putText(canvas, labels_to_display, cv::Point(target->x, target->y), 25, cv::Scalar(255, 0, 255), cv::FILLED, cv::LINE_AA, true);
            }
            else {               
                cv::putText(canvas, labels_to_display, cv::Point(target->x, target->y), 1, 1, cv::Scalar(255, 0, 255));
            }
        }
        return meta;
    }
}