File: utils.hpp

package info (click to toggle)
opencv 4.10.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 282,092 kB
  • sloc: cpp: 1,178,079; xml: 682,621; python: 49,092; lisp: 31,150; java: 25,469; ansic: 11,039; javascript: 6,085; sh: 1,214; cs: 601; perl: 494; objc: 210; makefile: 173
file content (144 lines) | stat: -rw-r--r-- 4,123 bytes parent folder | download
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
#ifndef OPENCV_GAPI_PIPELINE_MODELING_TOOL_UTILS_HPP
#define OPENCV_GAPI_PIPELINE_MODELING_TOOL_UTILS_HPP

#include <map>

#include <opencv2/core.hpp>

#if defined(_WIN32)
#include <windows.h>
#endif

// FIXME: It's better to place it somewhere in common.hpp
struct OutputDescr {
    std::vector<int> dims;
    int              precision;
};

namespace utils {

using double_ms_t = std::chrono::duration<double, std::milli>;

inline void createNDMat(cv::Mat& mat, const std::vector<int>& dims, int depth) {
    GAPI_Assert(!dims.empty());
    mat.create(dims, depth);
    if (dims.size() == 1) {
        //FIXME: Well-known 1D mat WA
        mat.dims = 1;
    }
}

inline void generateRandom(cv::Mat& out) {
    switch (out.depth()) {
        case CV_8U:
            cv::randu(out, 0, 255);
            break;
        case CV_32F:
            cv::randu(out, 0.f, 1.f);
            break;
        case CV_16F: {
            std::vector<int> dims;
            for (int i = 0; i < out.size.dims(); ++i) {
                dims.push_back(out.size[i]);
            }
            cv::Mat fp32_mat;
            createNDMat(fp32_mat, dims, CV_32F);
            cv::randu(fp32_mat, 0.f, 1.f);
            fp32_mat.convertTo(out, out.type());
            break;
        }
        default:
            throw std::logic_error("Unsupported preprocessing depth");
    }
}

inline void sleep(std::chrono::microseconds delay) {
#if defined(_WIN32)
    // FIXME: Wrap it to RAII and instance only once.
    HANDLE timer = CreateWaitableTimer(NULL, true, NULL);
    if (!timer) {
        throw std::logic_error("Failed to create timer");
    }

    LARGE_INTEGER li;
    using ns_t = std::chrono::nanoseconds;
    using ns_100_t = std::chrono::duration<ns_t::rep,
                                           std::ratio_multiply<std::ratio<100>, ns_t::period>>;
    // NB: QuadPart takes portions of 100 nanoseconds.
    li.QuadPart = -std::chrono::duration_cast<ns_100_t>(delay).count();

    if(!SetWaitableTimer(timer, &li, 0, NULL, NULL, false)){
        CloseHandle(timer);
        throw std::logic_error("Failed to set timer");
    }
    if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0) {
        CloseHandle(timer);
        throw std::logic_error("Failed to wait timer");
    }
    CloseHandle(timer);
#else
    std::this_thread::sleep_for(delay);
#endif
}

template <typename duration_t>
typename duration_t::rep measure(std::function<void()> f) {
    using namespace std::chrono;
    auto start = high_resolution_clock::now();
    f();
    return duration_cast<duration_t>(
            high_resolution_clock::now() - start).count();
}

template <typename duration_t>
typename duration_t::rep timestamp() {
    using namespace std::chrono;
    auto now = high_resolution_clock::now();
    return duration_cast<duration_t>(now.time_since_epoch()).count();
}

inline void busyWait(std::chrono::microseconds delay) {
    auto start_ts     = timestamp<std::chrono::microseconds>();
    auto end_ts       = start_ts;
    auto time_to_wait = delay.count();

    while (end_ts - start_ts < time_to_wait) {
        end_ts = timestamp<std::chrono::microseconds>();
    }
}

template <typename K, typename V>
void mergeMapWith(std::map<K, V>& target, const std::map<K, V>& second) {
    for (auto&& item : second) {
        auto it = target.find(item.first);
        if (it != target.end()) {
            throw std::logic_error("Error: key: " + it->first + " is already in target map");
        }
        target.insert(item);
    }
}

template <typename T>
double avg(const std::vector<T>& vec) {
    return std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
}

template <typename T>
T max(const std::vector<T>& vec) {
    return *std::max_element(vec.begin(), vec.end());
}

template <typename T>
T min(const std::vector<T>& vec) {
    return *std::min_element(vec.begin(), vec.end());
}

template <typename T>
int64_t ms_to_mcs(T ms) {
    using namespace std::chrono;
    return duration_cast<microseconds>(duration<T, std::milli>(ms)).count();
}

} // namespace utils

#endif // OPENCV_GAPI_PIPELINE_MODELING_TOOL_UTILS_HPP