mirror of
https://github.com/opencv/opencv.git
synced 2026-07-28 23:03:03 +04:00
Merge pull request #28752 from abhishek-gola:net_profiling
Added net profiling support #28752 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -545,6 +545,33 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
virtual void setProg(const std::vector<Ptr<Layer> >& newprog) = 0;
|
||||
};
|
||||
|
||||
/** @brief Single entry in a @ref PerfProfile.
|
||||
*
|
||||
* In DNN_PROFILE_DETAILED mode, @p label is "layer_name (type)" and @p count is 1.
|
||||
* In DNN_PROFILE_SUMMARY mode, @p label is the layer type and @p count is the
|
||||
* number of layers of that type that contributed to @p timeMs.
|
||||
*/
|
||||
struct CV_EXPORTS_W_SIMPLE PerfProfileEntry
|
||||
{
|
||||
CV_WRAP PerfProfileEntry() : timeMs(0.0), count(0) {}
|
||||
CV_PROP_RW String label;
|
||||
CV_PROP_RW double timeMs;
|
||||
CV_PROP_RW int count;
|
||||
};
|
||||
|
||||
/** @brief Self-describing snapshot of profiling data from one inference.
|
||||
*
|
||||
* Carries the @ref ProfilingMode it was captured in so it can be saved, kept across
|
||||
* runs (e.g. best-of-N by total time), and printed later via @ref Net::printPerfProfile
|
||||
* without needing access to the originating @ref Net.
|
||||
*/
|
||||
struct CV_EXPORTS_W_SIMPLE PerfProfile
|
||||
{
|
||||
CV_WRAP PerfProfile() : mode(DNN_PROFILE_NONE) {}
|
||||
CV_PROP_RW ProfilingMode mode;
|
||||
CV_PROP_RW std::vector<PerfProfileEntry> entries;
|
||||
};
|
||||
|
||||
/** @brief This class allows to create and manipulate comprehensive artificial neural networks.
|
||||
*
|
||||
* Neural network is presented as directed acyclic graph (DAG), where vertices are Layer instances,
|
||||
@@ -1027,6 +1054,21 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
*/
|
||||
CV_WRAP int64 getPerfProfile(CV_OUT std::vector<double>& timings);
|
||||
|
||||
/** @brief Returns profiling data captured during the last forward pass.
|
||||
*
|
||||
* Entries are sorted by time in descending order. Empty vectors are returned
|
||||
* if profiling is disabled (DNN_PROFILE_NONE).
|
||||
*/
|
||||
CV_WRAP void getPerfProfile(CV_OUT std::vector<std::string>& names, CV_OUT std::vector<std::string>& timems, CV_OUT std::vector<std::string>& counts) const;
|
||||
|
||||
/** @brief Prints the profile captured during the last forward pass in a formatted table using CV_LOG_INFO.
|
||||
*
|
||||
* In DNN_PROFILE_DETAILED mode, prints per-layer label, time, and percentage.
|
||||
* In DNN_PROFILE_SUMMARY mode, prints per-type count, time, and percentage.
|
||||
* Does nothing if profiling is disabled (DNN_PROFILE_NONE) or all timings are zero.
|
||||
*/
|
||||
CV_WRAP void printPerfProfile() const;
|
||||
|
||||
// Get the main model graph
|
||||
Ptr<Graph> getMainGraph() const;
|
||||
|
||||
|
||||
@@ -446,6 +446,20 @@ int64 Net::getPerfProfile(std::vector<double>& timings)
|
||||
return impl->getPerfProfile(timings);
|
||||
}
|
||||
|
||||
void Net::getPerfProfile(std::vector<std::string>& names,
|
||||
std::vector<std::string>& timems,
|
||||
std::vector<std::string>& counts) const
|
||||
{
|
||||
CV_Assert(impl);
|
||||
impl->getPerfProfile(names, timems, counts);
|
||||
}
|
||||
|
||||
void Net::printPerfProfile() const
|
||||
{
|
||||
CV_Assert(impl);
|
||||
impl->printPerfProfile();
|
||||
}
|
||||
|
||||
bool Net::isConstArg(Arg arg) const
|
||||
{
|
||||
return argKind(arg) == DNN_ARG_CONST;
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
|
||||
#include "net_impl.hpp"
|
||||
|
||||
#ifdef HAVE_ONNXRUNTIME
|
||||
#include <onnxruntime_cxx_api.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
@@ -2642,6 +2648,251 @@ int64 Net::Impl::getPerfProfile(std::vector<double>& timings) const
|
||||
return total;
|
||||
}
|
||||
|
||||
void Net::Impl::collectLayerInfo(std::vector<String>& names, std::vector<String>& types) const
|
||||
{
|
||||
if (mainGraph) {
|
||||
names.reserve(totalLayers);
|
||||
types.reserve(totalLayers);
|
||||
for (const Ptr<Graph>& graph : allgraphs) {
|
||||
const std::vector<Ptr<Layer>>& prog = graph->prog();
|
||||
for (const Ptr<Layer>& layer : prog) {
|
||||
names.push_back(layer ? layer->name : "null");
|
||||
types.push_back(layer ? layer->type : "null");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (MapIdToLayerData::const_iterator it = layers.begin(); it != layers.end(); ++it) {
|
||||
if (it->second.id) { // skip Data layer (id==0)
|
||||
names.push_back(it->second.name);
|
||||
types.push_back(it->second.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_ONNXRUNTIME
|
||||
static void parseOrtProfileJson(const std::string& text,
|
||||
std::map<std::string, std::pair<std::string, double>>& out_ms)
|
||||
{
|
||||
const std::string wrapped = "{\"events\":" + text + "}";
|
||||
FileStorage fs(wrapped, FileStorage::READ | FileStorage::MEMORY | FileStorage::FORMAT_JSON);
|
||||
if (!fs.isOpened()) {
|
||||
CV_LOG_WARNING(NULL, "DNN/ORT: failed to parse profile JSON");
|
||||
return;
|
||||
}
|
||||
|
||||
static const std::string KT = "_kernel_time";
|
||||
FileNode events = fs["events"];
|
||||
for (FileNodeIterator it = events.begin(); it != events.end(); ++it) {
|
||||
FileNode entry = *it;
|
||||
if (!entry.isMap()) continue;
|
||||
if ((std::string)entry["cat"] != "Node") continue;
|
||||
|
||||
const std::string name = (std::string)entry["name"];
|
||||
if (name.size() < KT.size() ||
|
||||
name.compare(name.size() - KT.size(), KT.size(), KT) != 0)
|
||||
continue;
|
||||
|
||||
FileNode args = entry["args"];
|
||||
if (args.empty()) continue;
|
||||
const std::string op = (std::string)args["op_name"];
|
||||
const double dur_us = (double)entry["dur"];
|
||||
if (op.empty() || dur_us <= 0) continue;
|
||||
|
||||
const std::string canonical = name.substr(0, name.size() - KT.size());
|
||||
auto& slot = out_ms[canonical];
|
||||
slot.first = op;
|
||||
slot.second += dur_us / 1000.0;
|
||||
}
|
||||
}
|
||||
|
||||
void Net::Impl::collectOrtProfileData() const
|
||||
{
|
||||
if (ort_profile_collected) return;
|
||||
ort_profile_collected = true;
|
||||
if (!ort_session || ort_profile_path_prefix.empty()) return;
|
||||
|
||||
// EndProfiling closes the file ORT has been writing to and returns its path.
|
||||
Ort::AllocatorWithDefaultOptions allocator;
|
||||
Ort::AllocatedStringPtr profile_path = ort_session->EndProfilingAllocated(allocator);
|
||||
if (!profile_path) {
|
||||
CV_LOG_WARNING(NULL, "DNN/ORT: EndProfiling did not return a path (prefix=" << ort_profile_path_prefix << ")");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the JSON entirely into memory, then parse it from the string.
|
||||
std::ifstream in(profile_path.get());
|
||||
if (!in.is_open()) {
|
||||
CV_LOG_WARNING(NULL, "DNN/ORT: failed to open profile JSON " << profile_path.get());
|
||||
return;
|
||||
}
|
||||
std::stringstream ss; ss << in.rdbuf();
|
||||
const std::string text = ss.str();
|
||||
|
||||
std::map<std::string, std::pair<std::string, double>> by_name;
|
||||
parseOrtProfileJson(text, by_name);
|
||||
|
||||
const int runs = ort_profile_runs > 0 ? ort_profile_runs : 1;
|
||||
ort_profile_data.clear();
|
||||
ort_profile_data.reserve(by_name.size());
|
||||
for (auto& kv : by_name) {
|
||||
const String name = kv.first;
|
||||
const String type = kv.second.first;
|
||||
const double ms_per_run = kv.second.second / runs;
|
||||
ort_profile_data.emplace_back(name, type, ms_per_run);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PerfProfile Net::Impl::getPerfProfile() const
|
||||
{
|
||||
PerfProfile result;
|
||||
result.mode = profilingMode;
|
||||
|
||||
if (profilingMode == DNN_PROFILE_NONE)
|
||||
return result;
|
||||
|
||||
#ifdef HAVE_ONNXRUNTIME
|
||||
if (useOrtEngine && ort_session) {
|
||||
collectOrtProfileData();
|
||||
if (profilingMode == DNN_PROFILE_DETAILED) {
|
||||
for (const auto& t : ort_profile_data) {
|
||||
if (std::get<2>(t) <= 0) continue;
|
||||
PerfProfileEntry e;
|
||||
e.label = std::get<0>(t) + " (" + std::get<1>(t) + ")";
|
||||
e.timeMs = std::get<2>(t);
|
||||
e.count = 1;
|
||||
result.entries.push_back(e);
|
||||
}
|
||||
} else if (profilingMode == DNN_PROFILE_SUMMARY) {
|
||||
std::map<String, double> typeTimings;
|
||||
std::map<String, int> typeCounts;
|
||||
for (const auto& t : ort_profile_data) {
|
||||
if (std::get<2>(t) <= 0) continue;
|
||||
typeTimings[std::get<1>(t)] += std::get<2>(t);
|
||||
typeCounts[std::get<1>(t)]++;
|
||||
}
|
||||
result.entries.reserve(typeTimings.size());
|
||||
for (auto it = typeTimings.begin(); it != typeTimings.end(); ++it) {
|
||||
PerfProfileEntry e;
|
||||
e.label = it->first;
|
||||
e.timeMs = it->second;
|
||||
e.count = typeCounts[it->first];
|
||||
result.entries.push_back(e);
|
||||
}
|
||||
}
|
||||
std::sort(result.entries.begin(), result.entries.end(),
|
||||
[](const PerfProfileEntry& a, const PerfProfileEntry& b) {
|
||||
return a.timeMs > b.timeMs;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<double> timings(layersTimings.begin() + 1, layersTimings.end());
|
||||
double tickFreq = getTickFrequency();
|
||||
|
||||
std::vector<String> names;
|
||||
std::vector<String> types;
|
||||
collectLayerInfo(names, types);
|
||||
|
||||
size_t n = std::min(timings.size(), names.size());
|
||||
|
||||
if (profilingMode == DNN_PROFILE_DETAILED) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (timings[i] > 0) {
|
||||
PerfProfileEntry e;
|
||||
e.label = names[i] + " (" + types[i] + ")";
|
||||
e.timeMs = timings[i] * 1000.0 / tickFreq;
|
||||
e.count = 1;
|
||||
result.entries.push_back(e);
|
||||
}
|
||||
}
|
||||
} else if (profilingMode == DNN_PROFILE_SUMMARY) {
|
||||
std::map<String, double> typeTimings;
|
||||
std::map<String, int> typeCounts;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (timings[i] > 0) {
|
||||
typeTimings[types[i]] += timings[i] * 1000.0 / tickFreq;
|
||||
typeCounts[types[i]]++;
|
||||
}
|
||||
}
|
||||
result.entries.reserve(typeTimings.size());
|
||||
for (auto it = typeTimings.begin(); it != typeTimings.end(); ++it) {
|
||||
PerfProfileEntry e;
|
||||
e.label = it->first;
|
||||
e.timeMs = it->second;
|
||||
e.count = typeCounts[it->first];
|
||||
result.entries.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(result.entries.begin(), result.entries.end(),
|
||||
[](const PerfProfileEntry& a, const PerfProfileEntry& b) {
|
||||
return a.timeMs > b.timeMs;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Net::Impl::getPerfProfile(std::vector<std::string>& names,
|
||||
std::vector<std::string>& timems,
|
||||
std::vector<std::string>& counts) const
|
||||
{
|
||||
PerfProfile profile = getPerfProfile();
|
||||
names.clear();
|
||||
timems.clear();
|
||||
counts.clear();
|
||||
names.reserve(profile.entries.size());
|
||||
timems.reserve(profile.entries.size());
|
||||
counts.reserve(profile.entries.size());
|
||||
for (const PerfProfileEntry& e : profile.entries) {
|
||||
names.push_back(e.label);
|
||||
timems.push_back(cv::format("%.3f", e.timeMs));
|
||||
counts.push_back(cv::format("%d", e.count));
|
||||
}
|
||||
}
|
||||
|
||||
void Net::Impl::printPerfProfile() const
|
||||
{
|
||||
PerfProfile profile = getPerfProfile();
|
||||
if (profile.mode == DNN_PROFILE_NONE)
|
||||
return;
|
||||
|
||||
double totalMs = 0.0;
|
||||
for (const PerfProfileEntry& e : profile.entries)
|
||||
totalMs += e.timeMs;
|
||||
if (totalMs <= 0.0)
|
||||
return;
|
||||
|
||||
if (profile.mode == DNN_PROFILE_DETAILED) {
|
||||
CV_LOG_INFO(NULL, "\n=== DNN Layer Profiling (Detailed) ===");
|
||||
CV_LOG_INFO(NULL, cv::format("%-5s %-60s %10s %8s", "ID", "Layer (Type)", "Time (ms)", " (%)"));
|
||||
CV_LOG_INFO(NULL, "-----------------------------------------------------------------------------------------------");
|
||||
for (size_t i = 0; i < profile.entries.size(); i++) {
|
||||
const PerfProfileEntry& e = profile.entries[i];
|
||||
double pct = e.timeMs * 100.0 / totalMs;
|
||||
CV_LOG_INFO(NULL, cv::format("%-5zu %-60s %10.3f %7.1f%%",
|
||||
i, e.label.c_str(), e.timeMs, pct));
|
||||
}
|
||||
CV_LOG_INFO(NULL, "-----------------------------------------------------------------------------------------------");
|
||||
CV_LOG_INFO(NULL, cv::format("%-5s %-60s %10.3f %7s", "", "TOTAL", totalMs, "100.0%"));
|
||||
CV_LOG_INFO(NULL, "");
|
||||
} else if (profile.mode == DNN_PROFILE_SUMMARY) {
|
||||
CV_LOG_INFO(NULL, "\n=== DNN Layer Profiling (Summary by Type) ===");
|
||||
CV_LOG_INFO(NULL, cv::format("%-25s %6s %10s %8s", "Layer Type", "Count", "Time (ms)", " (%)"));
|
||||
CV_LOG_INFO(NULL, "-----------------------------------------------------------");
|
||||
for (const PerfProfileEntry& e : profile.entries) {
|
||||
double pct = e.timeMs * 100.0 / totalMs;
|
||||
CV_LOG_INFO(NULL, cv::format("%-25s %6d %10.3f %7.1f%%",
|
||||
e.label.c_str(), e.count, e.timeMs, pct));
|
||||
}
|
||||
CV_LOG_INFO(NULL, "-----------------------------------------------------------");
|
||||
CV_LOG_INFO(NULL, cv::format("%-25s %6s %10.3f %7s", "TOTAL", "", totalMs, "100.0%"));
|
||||
CV_LOG_INFO(NULL, "");
|
||||
}
|
||||
}
|
||||
|
||||
void Net::Impl::getMemoryConsumption(
|
||||
const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<MatType>& netInputTypes,
|
||||
|
||||
@@ -254,12 +254,17 @@ struct Net::Impl : public detail::NetImplBase
|
||||
void finalizeOrt();
|
||||
void refreshOrtMainGraphOutputs();
|
||||
void applyStagedOrtInputs();
|
||||
void collectOrtProfileData() const;
|
||||
std::vector<std::pair<std::string, Mat>> ort_staged_inputs;
|
||||
std::shared_ptr<Ort::Env> ort_env;
|
||||
std::shared_ptr<Ort::Session> ort_session;
|
||||
std::shared_ptr<OrtNamesCache> ort_names_cache;
|
||||
bool useOrtEngine = false; // true only when user explicitly selected ENGINE_ORT
|
||||
bool ortNeedsReinit = false; // session needs (re)creation on next finalizeNet
|
||||
std::string ort_profile_path_prefix; // prefix passed to EnableProfiling
|
||||
mutable bool ort_profile_collected = false; // EndProfiling was already called once
|
||||
mutable int ort_profile_runs = 0; // number of session.Run calls since profiling started
|
||||
mutable std::vector<std::tuple<String, String, double>> ort_profile_data; // (name, type, ms_per_run)
|
||||
#endif
|
||||
|
||||
void allocateLayer(int lid, const LayersShapesMap& layersShapes);
|
||||
@@ -330,6 +335,10 @@ struct Net::Impl : public detail::NetImplBase
|
||||
std::vector<int>& layerIds, std::vector<size_t>& weights,
|
||||
std::vector<size_t>& blobs) /*const*/;
|
||||
int64 getPerfProfile(std::vector<double>& timings) const;
|
||||
void collectLayerInfo(std::vector<String>& names, std::vector<String>& types) const;
|
||||
PerfProfile getPerfProfile() const;
|
||||
void getPerfProfile(std::vector<std::string>& names, std::vector<std::string>& timems, std::vector<std::string>& counts) const;
|
||||
void printPerfProfile() const;
|
||||
|
||||
// TODO drop
|
||||
LayerPin getLatestLayerPin(const std::vector<LayerPin>& pins) const;
|
||||
|
||||
@@ -221,6 +221,7 @@ std::vector<Mat> Net::Impl::runOrtSession(std::vector<Mat> inputBlobs, const std
|
||||
Ort::RunOptions{nullptr},
|
||||
in_names.data(), input_tensors.data(), input_tensors.size(),
|
||||
out_names.data(), out_names.size());
|
||||
if (profilingMode != DNN_PROFILE_NONE) ort_profile_runs++;
|
||||
|
||||
CV_CheckEQ(output_tensors.size(), out_names.size(), "DNN/ORT: ORT returned unexpected number of outputs");
|
||||
|
||||
|
||||
@@ -88,6 +88,17 @@ void Net::Impl::finalizeOrt()
|
||||
}
|
||||
}
|
||||
|
||||
// If the user set DNN_PROFILE_*, turn on ORT's session profiler. The JSON
|
||||
// file is parsed lazily by collectOrtProfileData() inside getPerfProfile()/printPerfProfile().
|
||||
ort_profile_path_prefix.clear();
|
||||
ort_profile_collected = false;
|
||||
ort_profile_runs = 0;
|
||||
ort_profile_data.clear();
|
||||
if (profilingMode != DNN_PROFILE_NONE) {
|
||||
ort_profile_path_prefix = cv::tempfile("opencv_ort_profile_");
|
||||
opts.EnableProfiling(ort_profile_path_prefix.c_str());
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::wstring wpath(modelFileName.begin(), modelFileName.end());
|
||||
ort_session = std::make_shared<Ort::Session>(*ort_env, wpath.c_str(), opts);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
@@ -91,6 +92,8 @@ static bool readStringList( const string& filename, vector<string>& l )
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_INFO);
|
||||
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
if (!parser.has("@alias") || parser.has("help"))
|
||||
@@ -150,6 +153,7 @@ int main(int argc, char** argv)
|
||||
Net net = readNetFromONNX(model, engine);
|
||||
net.setPreferableBackend(getBackendID(backend));
|
||||
net.setPreferableTarget(getTargetID(target));
|
||||
net.setProfilingMode(DNN_PROFILE_SUMMARY);
|
||||
//! [Read and initialize network]
|
||||
|
||||
// Create a window
|
||||
@@ -229,6 +233,7 @@ int main(int argc, char** argv)
|
||||
timeRecorder.start();
|
||||
prob = net.forward();
|
||||
timeRecorder.stop();
|
||||
net.printPerfProfile();
|
||||
//! [Make forward pass]
|
||||
|
||||
//! [Get a class with a highest score]
|
||||
|
||||
@@ -72,6 +72,7 @@ def main(func_args=None):
|
||||
help()
|
||||
exit(1)
|
||||
|
||||
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_INFO)
|
||||
args.model = findModel(args.model, args.sha1)
|
||||
args.labels = findFile(args.labels)
|
||||
|
||||
@@ -88,6 +89,8 @@ def main(func_args=None):
|
||||
net = cv.dnn.readNetFromONNX(args.model, engine)
|
||||
net.setPreferableBackend(get_backend_id(args.backend))
|
||||
net.setPreferableTarget(get_target_id(args.target))
|
||||
if hasattr(cv.dnn, 'DNN_PROFILE_SUMMARY'):
|
||||
net.setProfilingMode(cv.dnn.DNN_PROFILE_SUMMARY)
|
||||
|
||||
winName = 'Deep learning image classification in OpenCV'
|
||||
cv.namedWindow(winName, cv.WINDOW_NORMAL)
|
||||
@@ -138,6 +141,7 @@ def main(func_args=None):
|
||||
t0 = cv.getTickCount()
|
||||
out = net.forward()
|
||||
t = (cv.getTickCount() - t0) / cv.getTickFrequency()
|
||||
net.printPerfProfile()
|
||||
|
||||
(h, w, _) = frame.shape
|
||||
roi_rows = min(300, h)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
@@ -161,6 +162,8 @@ private:
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_INFO);
|
||||
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
string zooFile = parser.get<String>("zoo");
|
||||
@@ -225,6 +228,7 @@ int main(int argc, char** argv)
|
||||
int backend = getBackendID(parser.get<String>("backend"));
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(getTargetID(parser.get<String>("target")));
|
||||
net.setProfilingMode(DNN_PROFILE_SUMMARY);
|
||||
//![read_net]
|
||||
|
||||
// Create a window
|
||||
@@ -302,6 +306,7 @@ int main(int argc, char** argv)
|
||||
//![forward]
|
||||
vector<Mat> outs;
|
||||
net.forward(outs, net.getUnconnectedOutLayersNames());
|
||||
net.printPerfProfile();
|
||||
predictionsQueue.push(outs);
|
||||
//![forward]
|
||||
}
|
||||
@@ -372,6 +377,7 @@ int main(int argc, char** argv)
|
||||
tickMeter.start();
|
||||
net.forward(outs, net.getUnconnectedOutLayersNames());
|
||||
tickMeter.stop();
|
||||
net.printPerfProfile();
|
||||
|
||||
classIds.clear();
|
||||
confidences.clear();
|
||||
|
||||
@@ -71,6 +71,7 @@ if args.alias is None or hasattr(args, 'help'):
|
||||
help()
|
||||
exit(1)
|
||||
|
||||
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_INFO)
|
||||
args.model = findModel(args.model, args.sha1)
|
||||
if args.config is not None:
|
||||
args.config = findModel(args.config, args.config_sha1)
|
||||
@@ -104,6 +105,8 @@ if args.backend != "default" or args.target != "cpu":
|
||||
net = cv.dnn.readNet(args.model, args.config, "", engine)
|
||||
net.setPreferableBackend(get_backend_id(args.backend))
|
||||
net.setPreferableTarget(get_target_id(args.target))
|
||||
if hasattr(cv.dnn, 'DNN_PROFILE_SUMMARY'):
|
||||
net.setProfilingMode(cv.dnn.DNN_PROFILE_SUMMARY)
|
||||
outNames = net.getUnconnectedOutLayersNames()
|
||||
|
||||
confThreshold = args.thr
|
||||
@@ -340,6 +343,7 @@ def processingThreadBody():
|
||||
futureOutputs.append(net.forwardAsync())
|
||||
else:
|
||||
outs = net.forward(outNames)
|
||||
net.printPerfProfile()
|
||||
predictionsQueue.put(copy.deepcopy(outs))
|
||||
|
||||
while futureOutputs and futureOutputs[0].wait_for(0):
|
||||
@@ -408,6 +412,7 @@ else:
|
||||
|
||||
net.setInput(blob)
|
||||
outs = net.forward(outNames)
|
||||
net.printPerfProfile()
|
||||
|
||||
boxes, classIds, confidences, indices = postprocess(frame, outs)
|
||||
drawPred(classIds, confidences, boxes, indices, (stdSize*max(frame.shape[:2]))/stdImgSize, (stdWeight*max(frame.shape[:2]))//stdImgSize)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
@@ -139,6 +140,8 @@ static void showLegend(FontFace fontFace)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_INFO);
|
||||
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
const string modelName = parser.get<String>("@alias");
|
||||
@@ -218,7 +221,8 @@ int main(int argc, char **argv)
|
||||
Net net = readNetFromONNX(model, engine);
|
||||
net.setPreferableBackend(getBackendID(backend));
|
||||
net.setPreferableTarget(getTargetID(target));
|
||||
//! [Read and initialize network]
|
||||
net.setProfilingMode(DNN_PROFILE_SUMMARY);
|
||||
//! [Read and initialize network]
|
||||
// Create a window
|
||||
static const string kWinName = "Deep learning semantic segmentation in OpenCV";
|
||||
namedWindow(kWinName, WINDOW_AUTOSIZE);
|
||||
@@ -263,6 +267,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
vector<Mat> output;
|
||||
net.forward(output, net.getUnconnectedOutLayersNames());
|
||||
net.printPerfProfile();
|
||||
|
||||
Mat pred = output[0].reshape(1, output[0].size[2]);
|
||||
pred.convertTo(pred, CV_8U, 255.0);
|
||||
@@ -284,6 +289,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
//! [Make forward pass]
|
||||
Mat score = net.forward();
|
||||
net.printPerfProfile();
|
||||
//! [Make forward pass]
|
||||
Mat segm;
|
||||
colorizeSegmentation(score, segm);
|
||||
|
||||
@@ -73,6 +73,7 @@ def main(func_args=None):
|
||||
help()
|
||||
exit(1)
|
||||
|
||||
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_INFO)
|
||||
args.model = findModel(args.model, args.sha1)
|
||||
if args.labels is not None:
|
||||
args.labels = findFile(args.labels)
|
||||
@@ -105,6 +106,8 @@ def main(func_args=None):
|
||||
net = cv.dnn.readNetFromONNX(args.model, engine)
|
||||
net.setPreferableBackend(get_backend_id(args.backend))
|
||||
net.setPreferableTarget(get_target_id(args.target))
|
||||
if hasattr(cv.dnn, 'DNN_PROFILE_SUMMARY'):
|
||||
net.setProfilingMode(cv.dnn.DNN_PROFILE_SUMMARY)
|
||||
|
||||
winName = 'Deep learning semantic segmentation in OpenCV'
|
||||
cv.namedWindow(winName, cv.WINDOW_AUTOSIZE)
|
||||
@@ -138,6 +141,7 @@ def main(func_args=None):
|
||||
t0 = cv.getTickCount()
|
||||
if args.alias == 'u2netp':
|
||||
output = net.forward(net.getUnconnectedOutLayersNames())
|
||||
net.printPerfProfile()
|
||||
pred = output[0][0, 0, :, :]
|
||||
mask = (pred * 255).astype(np.uint8)
|
||||
mask = cv.resize(mask, (frame.shape[1], frame.shape[0]), interpolation=cv.INTER_AREA)
|
||||
@@ -149,6 +153,7 @@ def main(func_args=None):
|
||||
frame = cv.addWeighted(frame, 0.25, foreground_overlay, 0.75, 0)
|
||||
else:
|
||||
score = net.forward()
|
||||
net.printPerfProfile()
|
||||
|
||||
numClasses = score.shape[1]
|
||||
height = score.shape[2]
|
||||
@@ -176,4 +181,4 @@ def main(func_args=None):
|
||||
cv.imshow(winName, frame)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user