mirror of
https://github.com/opencv/opencv.git
synced 2026-09-25 04:09:57 +03:00
Merge pull request #28912 from Prasadayus:Darknet-cleanup
Darknet cleanup
This commit is contained in:
@@ -508,7 +508,7 @@ set(dnn_plugin_srcs ${dnn_srcs} ${dnn_int_hdrs})
|
||||
ocv_list_filterout_ex(dnn_plugin_srcs
|
||||
"/src/dnn.cpp$|/src/dnn_utils.cpp$|/src/dnn_read.cpp$|/src/registry.cpp$|/src/backend.cpp$"
|
||||
# importers
|
||||
"/src/(caffe|darknet|onnx|tensorflow)/"
|
||||
"/src/(caffe|onnx|tensorflow)/"
|
||||
# executors
|
||||
"/src/(cuda|cuda4dnn|ocl4dnn|vkcom|webnn)/"
|
||||
)
|
||||
|
||||
@@ -1081,31 +1081,6 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
ENGINE_ORT=4 //!< Try to use ONNX Runtime wrapper (ONNX only, requires build with WITH_ONNXRUNTIME=ON).
|
||||
};
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://pjreddie.com/darknet/">Darknet</a> model files.
|
||||
* @param cfgFile path to the .cfg file with text description of the network architecture.
|
||||
* @param darknetModel path to the .weights file with learned network.
|
||||
* @returns Network object that ready to do forward, throw an exception in failure cases.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromDarknet(CV_WRAP_FILE_PATH const String &cfgFile, CV_WRAP_FILE_PATH const String &darknetModel = String());
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://pjreddie.com/darknet/">Darknet</a> model files.
|
||||
* @param bufferCfg A buffer contains a content of .cfg file with text description of the network architecture.
|
||||
* @param bufferModel A buffer contains a content of .weights file with learned network.
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromDarknet(const std::vector<uchar>& bufferCfg,
|
||||
const std::vector<uchar>& bufferModel = std::vector<uchar>());
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://pjreddie.com/darknet/">Darknet</a> model files.
|
||||
* @param bufferCfg A buffer contains a content of .cfg file with text description of the network architecture.
|
||||
* @param lenCfg Number of bytes to read from bufferCfg
|
||||
* @param bufferModel A buffer contains a content of .weights file with learned network.
|
||||
* @param lenModel Number of bytes to read from bufferModel
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS Net readNetFromDarknet(const char *bufferCfg, size_t lenCfg,
|
||||
const char *bufferModel = NULL, size_t lenModel = 0);
|
||||
|
||||
/** @brief Reads a network model stored in <a href="http://caffe.berkeleyvision.org">Caffe</a> framework's format.
|
||||
* @param prototxt path to the .prototxt file with text description of the network architecture.
|
||||
* @param caffeModel path to the .caffemodel file with learned network.
|
||||
@@ -1219,14 +1194,12 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* extensions are expected for models from different frameworks:
|
||||
* * `*.caffemodel` (Caffe, http://caffe.berkeleyvision.org/)
|
||||
* * `*.pb` (TensorFlow, https://www.tensorflow.org/)
|
||||
* * `*.weights` (Darknet, https://pjreddie.com/darknet/)
|
||||
* * `*.bin` | `*.onnx` (OpenVINO, https://software.intel.com/openvino-toolkit)
|
||||
* * `*.onnx` (ONNX, https://onnx.ai/)
|
||||
* @param[in] config Text file contains network configuration. It could be a
|
||||
* file with the following extensions:
|
||||
* * `*.prototxt` (Caffe, http://caffe.berkeleyvision.org/)
|
||||
* * `*.pbtxt` (TensorFlow, https://www.tensorflow.org/)
|
||||
* * `*.cfg` (Darknet, https://pjreddie.com/darknet/)
|
||||
* * `*.xml` (OpenVINO, https://software.intel.com/openvino-toolkit)
|
||||
* @param[in] framework Explicit framework name tag to determine a format.
|
||||
* @param[in] engine select DNN engine to be used. With auto selection the new engine is used first and falls back to classic.
|
||||
@@ -1235,9 +1208,8 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* @returns Net object.
|
||||
*
|
||||
* This function automatically detects an origin framework of trained model
|
||||
* and calls an appropriate function such @ref readNetFromCaffe, @ref readNetFromTensorflow
|
||||
* or @ref readNetFromDarknet. An order of @p model and @p config
|
||||
* arguments does not matter.
|
||||
* and calls an appropriate function such @ref readNetFromCaffe, @ref readNetFromTensorflow.
|
||||
* An order of @p model and @p config arguments does not matter.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNet(CV_WRAP_FILE_PATH const String& model,
|
||||
CV_WRAP_FILE_PATH const String& config = "",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"whitelist":
|
||||
{
|
||||
"dnn_Net": ["setInput", "forward", "setPreferableBackend","getUnconnectedOutLayersNames"],
|
||||
"": ["readNetFromCaffe", "readNetFromTensorflow", "readNetFromTorch", "readNetFromDarknet",
|
||||
"": ["readNetFromCaffe", "readNetFromTensorflow", "readNetFromTorch",
|
||||
"readNetFromONNX", "readNetFromTFLite", "readNet", "blobFromImage"]
|
||||
},
|
||||
"namespace_prefix_override":
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
"Dnn": {
|
||||
"(Net*)readNetFromCaffe:(NSString*)prototxt caffeModel:(NSString*)caffeModel engine:(int)engine" : { "readNetFromCaffe" : {"name" : "readNetFromCaffeFile"} },
|
||||
"(Net*)readNetFromCaffe:(ByteVector*)bufferProto bufferModel:(ByteVector*)bufferModel engine:(int)engine" : { "readNetFromCaffe" : {"name" : "readNetFromCaffeBuffer"} },
|
||||
"(Net*)readNetFromDarknet:(NSString*)cfgFile darknetModel:(NSString*)darknetModel" : { "readNetFromDarknet" : {"name" : "readNetFromDarknetFile"} },
|
||||
"(Net*)readNetFromDarknet:(ByteVector*)bufferCfg bufferModel:(ByteVector*)bufferModel" : { "readNetFromDarknet" : {"name" : "readNetFromDarknetBuffer"} },
|
||||
"(Net*)readNetFromONNX:(NSString*)onnxFile engine:(int)engine" : { "readNetFromONNX" : {"name" : "readNetFromONNXFile"} },
|
||||
"(Net*)readNetFromONNX:(ByteVector*)buffer engine:(int)engine" : { "readNetFromONNX" : {"name" : "readNetFromONNXBuffer"} },
|
||||
"(Net*)readNetFromTensorflow:(NSString*)model config:(NSString*)config engine:(int)engine extraOutputs:(NSArray<NSString*>*)extraOutputs" : { "readNetFromTensorflow" : {"name" : "readNetFromTensorflowFile"} },
|
||||
|
||||
@@ -212,8 +212,9 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
||||
#endif
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
cv::resize(sample, sample, Size(640, 640));
|
||||
Mat inp = blobFromImage(sample, 1.0 / 255.0, Size(), Scalar(), true);
|
||||
processNet("dnn/yolov3.weights", "dnn/yolov3.cfg", inp);
|
||||
processNet("dnn/yolov3.onnx", "", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv4)
|
||||
@@ -231,8 +232,9 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
|
||||
#endif
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
cv::resize(sample, sample, Size(608, 608));
|
||||
Mat inp = blobFromImage(sample, 1.0 / 255.0, Size(), Scalar(), true);
|
||||
processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", inp);
|
||||
processNet("dnn/yolov4.onnx", "", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
|
||||
@@ -243,7 +245,7 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
|
||||
#endif
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0 / 255.0, Size(), Scalar(), true);
|
||||
processNet("dnn/yolov4-tiny-2020-12.weights", "dnn/yolov4-tiny-2020-12.cfg", inp);
|
||||
processNet("dnn/yolov4-tiny.onnx", "", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv5) {
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
// (3-clause BSD License)
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the names of the copyright holders nor the names of the contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "../precomp.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "darknet_io.hpp"
|
||||
|
||||
#include <opencv2/core/utils/fp_control_utils.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class DarknetImporter
|
||||
{
|
||||
FPDenormalsIgnoreHintScope fp_denormals_ignore_scope;
|
||||
|
||||
darknet::NetParameter net;
|
||||
|
||||
public:
|
||||
|
||||
DarknetImporter() {}
|
||||
|
||||
DarknetImporter(std::istream &cfgStream, std::istream &darknetModelStream)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
ReadNetParamsFromCfgStreamOrDie(cfgStream, &net);
|
||||
ReadNetParamsFromBinaryStreamOrDie(darknetModelStream, &net);
|
||||
}
|
||||
|
||||
DarknetImporter(std::istream &cfgStream)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
ReadNetParamsFromCfgStreamOrDie(cfgStream, &net);
|
||||
}
|
||||
|
||||
struct BlobNote
|
||||
{
|
||||
BlobNote(const std::string &_name, int _layerId, int _outNum) :
|
||||
name(_name), layerId(_layerId), outNum(_outNum) {}
|
||||
|
||||
std::string name;
|
||||
int layerId, outNum;
|
||||
};
|
||||
|
||||
std::vector<BlobNote> addedBlobs;
|
||||
std::map<String, int> layerCounter;
|
||||
|
||||
void populateNet(Net dstNet)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
int layersSize = net.layer_size();
|
||||
layerCounter.clear();
|
||||
addedBlobs.clear();
|
||||
addedBlobs.reserve(layersSize + 1);
|
||||
|
||||
//setup input layer names
|
||||
{
|
||||
std::vector<String> netInputs(net.input_size());
|
||||
for (int inNum = 0; inNum < net.input_size(); inNum++)
|
||||
{
|
||||
addedBlobs.push_back(BlobNote(net.input(inNum), 0, inNum));
|
||||
netInputs[inNum] = net.input(inNum);
|
||||
}
|
||||
dstNet.setInputsNames(netInputs);
|
||||
}
|
||||
|
||||
for (int li = 0; li < layersSize; li++)
|
||||
{
|
||||
const darknet::LayerParameter &layer = net.layer(li);
|
||||
String name = layer.name();
|
||||
String type = layer.type();
|
||||
LayerParams layerParams = layer.getLayerParams();
|
||||
|
||||
int repetitions = layerCounter[name]++;
|
||||
if (repetitions)
|
||||
name += cv::format("_%d", repetitions);
|
||||
|
||||
int id = dstNet.addLayer(name, type, layerParams);
|
||||
|
||||
// iterate many bottoms layers (for example for: route -1, -4)
|
||||
for (int inNum = 0; inNum < layer.bottom_size(); inNum++)
|
||||
addInput(layer.bottom(inNum), id, inNum, dstNet, layer.name());
|
||||
|
||||
for (int outNum = 0; outNum < layer.top_size(); outNum++)
|
||||
addOutput(layer, id, outNum);
|
||||
}
|
||||
|
||||
addedBlobs.clear();
|
||||
}
|
||||
|
||||
void addOutput(const darknet::LayerParameter &layer, int layerId, int outNum)
|
||||
{
|
||||
const std::string &name = layer.top(outNum);
|
||||
|
||||
bool haveDups = false;
|
||||
for (int idx = (int)addedBlobs.size() - 1; idx >= 0; idx--)
|
||||
{
|
||||
if (addedBlobs[idx].name == name)
|
||||
{
|
||||
haveDups = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (haveDups)
|
||||
{
|
||||
bool isInplace = layer.bottom_size() > outNum && layer.bottom(outNum) == name;
|
||||
if (!isInplace)
|
||||
CV_Error(Error::StsBadArg, "Duplicate blobs produced by multiple sources");
|
||||
}
|
||||
|
||||
addedBlobs.push_back(BlobNote(name, layerId, outNum));
|
||||
}
|
||||
|
||||
void addInput(const std::string &name, int layerId, int inNum, Net &dstNet, std::string nn)
|
||||
{
|
||||
int idx;
|
||||
for (idx = (int)addedBlobs.size() - 1; idx >= 0; idx--)
|
||||
{
|
||||
if (addedBlobs[idx].name == name)
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
CV_Error(Error::StsObjectNotFound, "Can't find output blob \"" + name + "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
dstNet.connect(addedBlobs[idx].layerId, addedBlobs[idx].outNum, layerId, inNum);
|
||||
}
|
||||
};
|
||||
|
||||
static Net readNetFromDarknet(std::istream &cfgFile, std::istream &darknetModel)
|
||||
{
|
||||
Net net;
|
||||
DarknetImporter darknetImporter(cfgFile, darknetModel);
|
||||
darknetImporter.populateNet(net);
|
||||
return net;
|
||||
}
|
||||
|
||||
static Net readNetFromDarknet(std::istream &cfgFile)
|
||||
{
|
||||
Net net;
|
||||
DarknetImporter darknetImporter(cfgFile);
|
||||
darknetImporter.populateNet(net);
|
||||
return net;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Net readNetFromDarknet(const String &cfgFile, const String &darknetModel /*= String()*/)
|
||||
{
|
||||
std::ifstream cfgStream(cfgFile.c_str());
|
||||
if (!cfgStream.is_open())
|
||||
{
|
||||
CV_Error(cv::Error::StsParseError, "Failed to open NetParameter file: " + std::string(cfgFile));
|
||||
}
|
||||
if (darknetModel != String())
|
||||
{
|
||||
std::ifstream darknetModelStream(darknetModel.c_str(), std::ios::binary);
|
||||
if (!darknetModelStream.is_open())
|
||||
{
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter file: " + std::string(darknetModel));
|
||||
}
|
||||
return readNetFromDarknet(cfgStream, darknetModelStream);
|
||||
}
|
||||
else
|
||||
return readNetFromDarknet(cfgStream);
|
||||
}
|
||||
|
||||
struct BufferStream : public std::streambuf
|
||||
{
|
||||
BufferStream(const char* s, std::size_t n)
|
||||
{
|
||||
char* ptr = const_cast<char*>(s);
|
||||
setg(ptr, ptr, ptr + n);
|
||||
}
|
||||
};
|
||||
|
||||
Net readNetFromDarknet(const char *bufferCfg, size_t lenCfg, const char *bufferModel, size_t lenModel)
|
||||
{
|
||||
BufferStream cfgBufferStream(bufferCfg, lenCfg);
|
||||
std::istream cfgStream(&cfgBufferStream);
|
||||
if (lenModel)
|
||||
{
|
||||
BufferStream weightsBufferStream(bufferModel, lenModel);
|
||||
std::istream weightsStream(&weightsBufferStream);
|
||||
return readNetFromDarknet(cfgStream, weightsStream);
|
||||
}
|
||||
else
|
||||
return readNetFromDarknet(cfgStream);
|
||||
}
|
||||
|
||||
Net readNetFromDarknet(const std::vector<uchar>& bufferCfg, const std::vector<uchar>& bufferModel)
|
||||
{
|
||||
const char* bufferCfgPtr = reinterpret_cast<const char*>(&bufferCfg[0]);
|
||||
const char* bufferModelPtr = bufferModel.empty() ? NULL :
|
||||
reinterpret_cast<const char*>(&bufferModel[0]);
|
||||
return readNetFromDarknet(bufferCfgPtr, bufferCfg.size(),
|
||||
bufferModelPtr, bufferModel.size());
|
||||
}
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace
|
||||
@@ -1,1107 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
// (3-clause BSD License)
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the names of the copyright holders nor the names of the contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//MIT License
|
||||
//
|
||||
//Copyright (c) 2017 Joseph Redmon
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "../precomp.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "darknet_io.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
namespace darknet {
|
||||
|
||||
template<typename T>
|
||||
T getParam(const std::map<std::string, std::string> ¶ms, const std::string param_name, T init_val)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator it = params.find(param_name);
|
||||
if (it != params.end()) {
|
||||
std::stringstream ss(it->second);
|
||||
ss >> init_val;
|
||||
}
|
||||
return init_val;
|
||||
}
|
||||
|
||||
static const std::string kFirstLayerName = "data";
|
||||
|
||||
class setLayersParams {
|
||||
|
||||
NetParameter *net;
|
||||
int layer_id;
|
||||
std::string last_layer;
|
||||
std::vector<std::string> fused_layer_names;
|
||||
|
||||
public:
|
||||
setLayersParams(NetParameter *_net) :
|
||||
net(_net), layer_id(0), last_layer(kFirstLayerName)
|
||||
{}
|
||||
|
||||
void setLayerBlobs(int i, std::vector<cv::Mat> blobs)
|
||||
{
|
||||
cv::dnn::LayerParams ¶ms = net->layers[i].layerParams;
|
||||
params.blobs = blobs;
|
||||
}
|
||||
|
||||
void setBatchNorm()
|
||||
{
|
||||
cv::dnn::LayerParams bn_param;
|
||||
|
||||
bn_param.name = "BatchNorm-name";
|
||||
bn_param.type = "BatchNorm";
|
||||
bn_param.set<bool>("has_weight", true);
|
||||
bn_param.set<bool>("has_bias", true);
|
||||
bn_param.set<float>("eps", 1E-6); // .000001f in Darknet Yolo
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("bn_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = bn_param.type;
|
||||
lp.layerParams = bn_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
}
|
||||
|
||||
cv::dnn::LayerParams getParamConvolution(int kernel, int pad,
|
||||
int stride, int filters_num)
|
||||
{
|
||||
cv::dnn::LayerParams params;
|
||||
params.name = "Convolution-name";
|
||||
params.type = "Convolution";
|
||||
|
||||
params.set<int>("kernel_size", kernel);
|
||||
params.set<int>("pad", pad);
|
||||
params.set<int>("stride", stride);
|
||||
|
||||
params.set<bool>("bias_term", false); // true only if(BatchNorm == false)
|
||||
params.set<int>("num_output", filters_num);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
void setConvolution(int kernel, int pad, int stride,
|
||||
int filters_num, int channels_num, int groups, int use_batch_normalize)
|
||||
{
|
||||
cv::dnn::LayerParams conv_param =
|
||||
getParamConvolution(kernel, pad, stride, filters_num);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("conv_%d", layer_id);
|
||||
|
||||
// use BIAS in any case
|
||||
if (!use_batch_normalize) {
|
||||
conv_param.set<bool>("bias_term", true);
|
||||
}
|
||||
|
||||
conv_param.set<int>("group", groups);
|
||||
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = conv_param.type;
|
||||
lp.layerParams = conv_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
if (use_batch_normalize)
|
||||
setBatchNorm();
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
cv::dnn::LayerParams getParamFullyConnected(int output)
|
||||
{
|
||||
cv::dnn::LayerParams params;
|
||||
params.name = "FullyConnected-name";
|
||||
params.type = "InnerProduct";
|
||||
|
||||
params.set<bool>("bias_term", false); // true only if(BatchNorm == false)
|
||||
params.set<int>("num_output", output);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
void setFullyConnected(int output, int use_batch_normalize)
|
||||
{
|
||||
cv::dnn::LayerParams fullyconnected_param =
|
||||
getParamFullyConnected(output);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("fullyConnected_%d", layer_id);
|
||||
|
||||
// use BIAS in any case
|
||||
if (!use_batch_normalize) {
|
||||
fullyconnected_param.set<bool>("bias_term", true);
|
||||
}
|
||||
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = fullyconnected_param.type;
|
||||
lp.layerParams = fullyconnected_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
if (use_batch_normalize)
|
||||
setBatchNorm();
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setActivation(String type)
|
||||
{
|
||||
cv::dnn::LayerParams activation_param;
|
||||
if (type == "relu")
|
||||
{
|
||||
activation_param.type = "ReLU";
|
||||
}
|
||||
else if (type == "leaky")
|
||||
{
|
||||
activation_param.set<float>("negative_slope", 0.1f);
|
||||
activation_param.type = "ReLU";
|
||||
}
|
||||
else if (type == "swish" || type == "silu") // swish is an extension of silu.
|
||||
{
|
||||
activation_param.type = "Swish";
|
||||
}
|
||||
else if (type == "mish")
|
||||
{
|
||||
activation_param.type = "Mish";
|
||||
}
|
||||
else if (type == "logistic")
|
||||
{
|
||||
activation_param.type = "Sigmoid";
|
||||
}
|
||||
else if (type == "tanh")
|
||||
{
|
||||
activation_param.type = "TanH";
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(cv::Error::StsParseError, "Unsupported activation: " + type);
|
||||
}
|
||||
|
||||
std::string layer_name = cv::format("%s_%d", type.c_str(), layer_id);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = activation_param.type;
|
||||
lp.layerParams = activation_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
fused_layer_names.back() = last_layer;
|
||||
}
|
||||
|
||||
void setMaxpool(int kernel, int pad, int stride)
|
||||
{
|
||||
cv::dnn::LayerParams maxpool_param;
|
||||
maxpool_param.set<cv::String>("pool", "max");
|
||||
maxpool_param.set<int>("kernel_size", kernel);
|
||||
maxpool_param.set<int>("pad_l", floor((float)pad / 2));
|
||||
maxpool_param.set<int>("pad_r", ceil((float)pad / 2));
|
||||
maxpool_param.set<int>("pad_t", floor((float)pad / 2));
|
||||
maxpool_param.set<int>("pad_b", ceil((float)pad / 2));
|
||||
maxpool_param.set<bool>("ceil_mode", false);
|
||||
maxpool_param.set<int>("stride", stride);
|
||||
maxpool_param.name = "Pooling-name";
|
||||
maxpool_param.type = "Pooling";
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("pool_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = maxpool_param.type;
|
||||
lp.layerParams = maxpool_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setAvgpool()
|
||||
{
|
||||
cv::dnn::LayerParams avgpool_param;
|
||||
avgpool_param.set<cv::String>("pool", "ave");
|
||||
avgpool_param.set<bool>("global_pooling", true);
|
||||
avgpool_param.name = "Pooling-name";
|
||||
avgpool_param.type = "Pooling";
|
||||
darknet::LayerParameter lp;
|
||||
|
||||
std::string layer_name = cv::format("avgpool_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = avgpool_param.type;
|
||||
lp.layerParams = avgpool_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setCrop(int crop_height, int crop_width, int inp_height, int inp_width, bool noadjust)
|
||||
{
|
||||
cv::dnn::LayerParams crop_param;
|
||||
crop_param.name = "CropLayer-name";
|
||||
std::vector<int> begin = {0, 0, (inp_height - crop_height) / 2, (inp_width - crop_width) / 2};
|
||||
std::vector<int> sizes = {-1, -1, crop_height, crop_width};
|
||||
crop_param.set("begin", DictValue::arrayInt(&begin[0], begin.size()));
|
||||
crop_param.set("size", DictValue::arrayInt(&sizes[0], sizes.size()));
|
||||
crop_param.type = "Slice";
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("crop_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = crop_param.type;
|
||||
lp.layerParams = crop_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
layer_id++;
|
||||
|
||||
if (!noadjust)
|
||||
{
|
||||
cv::dnn::LayerParams params;
|
||||
params.set("bias_term", true);
|
||||
params.blobs = {
|
||||
Mat(1, 1, CV_32F, Scalar(2)),
|
||||
Mat(1, 1, CV_32F, Scalar(-1))
|
||||
};
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("adjust_crop_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = "Scale";
|
||||
lp.layerParams = params;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
layer_id++;
|
||||
}
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setSoftmax()
|
||||
{
|
||||
cv::dnn::LayerParams softmax_param;
|
||||
softmax_param.name = "Softmax-name";
|
||||
softmax_param.type = "Softmax";
|
||||
// set default axis to 1
|
||||
if(!softmax_param.has("axis"))
|
||||
softmax_param.set("axis", 1);
|
||||
darknet::LayerParameter lp;
|
||||
|
||||
std::string layer_name = cv::format("softmax_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = softmax_param.type;
|
||||
lp.layerParams = softmax_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setConcat(int number_of_inputs, int *input_indexes)
|
||||
{
|
||||
cv::dnn::LayerParams concat_param;
|
||||
concat_param.name = "Concat-name";
|
||||
concat_param.type = "Concat";
|
||||
concat_param.set<int>("axis", 1); // channels are in axis = 1
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
|
||||
std::string layer_name = cv::format("concat_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = concat_param.type;
|
||||
lp.layerParams = concat_param;
|
||||
for (int i = 0; i < number_of_inputs; ++i)
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(input_indexes[i]));
|
||||
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setIdentity(int bottom_index)
|
||||
{
|
||||
cv::dnn::LayerParams identity_param;
|
||||
identity_param.name = "Identity-name";
|
||||
identity_param.type = "Identity";
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
|
||||
std::string layer_name = cv::format("identity_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = identity_param.type;
|
||||
lp.layerParams = identity_param;
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(bottom_index));
|
||||
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setSlice(int input_index, int split_size, int group_id)
|
||||
{
|
||||
int begin[] = {0, split_size * group_id, 0, 0};
|
||||
cv::dnn::DictValue paramBegin = cv::dnn::DictValue::arrayInt(begin, 4);
|
||||
|
||||
int end[] = {INT_MAX, begin[1] + split_size, INT_MAX, INT_MAX};
|
||||
cv::dnn::DictValue paramEnd = cv::dnn::DictValue::arrayInt(end, 4);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
lp.layer_name = cv::format("slice_%d", layer_id);
|
||||
lp.layer_type = "Slice";
|
||||
lp.layerParams.set("begin", paramBegin);
|
||||
lp.layerParams.set("end", paramEnd);
|
||||
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(input_index));
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
last_layer = lp.layer_name;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setReorg(int stride)
|
||||
{
|
||||
cv::dnn::LayerParams reorg_params;
|
||||
reorg_params.name = "Reorg-name";
|
||||
reorg_params.type = "Reorg";
|
||||
reorg_params.set<int>("reorg_stride", stride);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("reorg_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = reorg_params.type;
|
||||
lp.layerParams = reorg_params;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setPermute(bool isDarknetLayer = true)
|
||||
{
|
||||
cv::dnn::LayerParams permute_params;
|
||||
permute_params.name = "Permute-name";
|
||||
permute_params.type = "Permute";
|
||||
int permute[] = { 0, 2, 3, 1 };
|
||||
cv::dnn::DictValue paramOrder = cv::dnn::DictValue::arrayInt(permute, 4);
|
||||
|
||||
permute_params.set("order", paramOrder);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("permute_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = permute_params.type;
|
||||
lp.layerParams = permute_params;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
if (isDarknetLayer)
|
||||
{
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
}
|
||||
|
||||
void setRegion(float thresh, int coords, int classes, int anchors, int classfix, int softmax, int softmax_tree, float *biasData)
|
||||
{
|
||||
cv::dnn::LayerParams region_param;
|
||||
region_param.name = "Region-name";
|
||||
region_param.type = "Region";
|
||||
|
||||
region_param.set<float>("thresh", thresh);
|
||||
region_param.set<int>("coords", coords);
|
||||
region_param.set<int>("classes", classes);
|
||||
region_param.set<int>("anchors", anchors);
|
||||
region_param.set<int>("classfix", classfix);
|
||||
region_param.set<bool>("softmax_tree", softmax_tree);
|
||||
region_param.set<bool>("softmax", softmax);
|
||||
|
||||
cv::Mat biasData_mat = cv::Mat(1, anchors * 2, CV_32F, biasData).clone();
|
||||
region_param.blobs.push_back(biasData_mat);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = "detection_out";
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = region_param.type;
|
||||
lp.layerParams = region_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setYolo(int classes, const std::vector<int>& mask, const std::vector<float>& anchors, float thresh, float nms_threshold, float scale_x_y, int new_coords)
|
||||
{
|
||||
cv::dnn::LayerParams region_param;
|
||||
region_param.name = "Region-name";
|
||||
region_param.type = "Region";
|
||||
|
||||
const int numAnchors = mask.size();
|
||||
|
||||
region_param.set<int>("classes", classes);
|
||||
region_param.set<int>("anchors", numAnchors);
|
||||
region_param.set<bool>("logistic", true);
|
||||
region_param.set<float>("thresh", thresh);
|
||||
region_param.set<float>("nms_threshold", nms_threshold);
|
||||
region_param.set<float>("scale_x_y", scale_x_y);
|
||||
region_param.set<int>("new_coords", new_coords);
|
||||
|
||||
std::vector<float> usedAnchors(numAnchors * 2);
|
||||
for (int i = 0; i < numAnchors; ++i)
|
||||
{
|
||||
usedAnchors[i * 2] = anchors[mask[i] * 2];
|
||||
usedAnchors[i * 2 + 1] = anchors[mask[i] * 2 + 1];
|
||||
}
|
||||
|
||||
cv::Mat biasData_mat = cv::Mat(1, numAnchors * 2, CV_32F, &usedAnchors[0]).clone();
|
||||
region_param.blobs.push_back(biasData_mat);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("yolo_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = region_param.type;
|
||||
lp.layerParams = region_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
lp.bottom_indexes.push_back(kFirstLayerName);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setShortcut(int from, float alpha)
|
||||
{
|
||||
cv::dnn::LayerParams shortcut_param;
|
||||
shortcut_param.name = "Shortcut-name";
|
||||
shortcut_param.type = "Eltwise";
|
||||
|
||||
if (alpha != 1)
|
||||
{
|
||||
std::vector<float> coeffs(2, 1);
|
||||
coeffs[0] = alpha;
|
||||
shortcut_param.set("coeff", DictValue::arrayReal<float*>(&coeffs[0], coeffs.size()));
|
||||
}
|
||||
|
||||
shortcut_param.set<std::string>("op", "sum");
|
||||
shortcut_param.set<std::string>("output_channels_mode", "input_0_truncate");
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("shortcut_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = shortcut_param.type;
|
||||
lp.layerParams = shortcut_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(from));
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setScaleChannels(int from)
|
||||
{
|
||||
cv::dnn::LayerParams shortcut_param;
|
||||
shortcut_param.type = "Scale";
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("scale_channels_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = shortcut_param.type;
|
||||
lp.layerParams = shortcut_param;
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(from));
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setSAM(int from)
|
||||
{
|
||||
cv::dnn::LayerParams eltwise_param;
|
||||
eltwise_param.name = "SAM-name";
|
||||
eltwise_param.type = "Eltwise";
|
||||
|
||||
eltwise_param.set<std::string>("operation", "prod");
|
||||
eltwise_param.set<std::string>("output_channels_mode", "same");
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("sam_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = eltwise_param.type;
|
||||
lp.layerParams = eltwise_param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(from));
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setUpsample(int scaleFactor)
|
||||
{
|
||||
cv::dnn::LayerParams param;
|
||||
param.name = "Upsample-name";
|
||||
param.type = "Resize";
|
||||
|
||||
param.set<int>("zoom_factor", scaleFactor);
|
||||
param.set<String>("interpolation", "nearest");
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
std::string layer_name = cv::format("upsample_%d", layer_id);
|
||||
lp.layer_name = layer_name;
|
||||
lp.layer_type = param.type;
|
||||
lp.layerParams = param;
|
||||
lp.bottom_indexes.push_back(last_layer);
|
||||
last_layer = layer_name;
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
};
|
||||
|
||||
std::string escapeString(const std::string &src)
|
||||
{
|
||||
std::string dst;
|
||||
for (size_t i = 0; i < src.size(); ++i)
|
||||
if (src[i] > ' ' && src[i] <= 'z')
|
||||
dst += src[i];
|
||||
return dst;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> getNumbers(const std::string &src)
|
||||
{
|
||||
std::vector<T> dst;
|
||||
std::stringstream ss(src);
|
||||
|
||||
for (std::string str; std::getline(ss, str, ',');) {
|
||||
std::stringstream line(str);
|
||||
T val;
|
||||
line >> val;
|
||||
dst.push_back(val);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool ReadDarknetFromCfgStream(std::istream &ifile, NetParameter *net)
|
||||
{
|
||||
bool read_net = false;
|
||||
int layers_counter = -1;
|
||||
for (std::string line; std::getline(ifile, line);) {
|
||||
line = escapeString(line);
|
||||
if (line.empty()) continue;
|
||||
switch (line[0]) {
|
||||
case '\0': break;
|
||||
case '#': break;
|
||||
case ';': break;
|
||||
case '[':
|
||||
if (line == "[net]") {
|
||||
read_net = true;
|
||||
}
|
||||
else {
|
||||
// read section
|
||||
read_net = false;
|
||||
++layers_counter;
|
||||
const size_t layer_type_size = line.find(']') - 1;
|
||||
CV_Assert(layer_type_size < line.size());
|
||||
std::string layer_type = line.substr(1, layer_type_size);
|
||||
net->layers_cfg[layers_counter]["layer_type"] = layer_type;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// read entry
|
||||
const size_t separator_index = line.find('=');
|
||||
CV_Assert(separator_index < line.size());
|
||||
if (separator_index != std::string::npos) {
|
||||
std::string name = line.substr(0, separator_index);
|
||||
std::string value = line.substr(separator_index + 1, line.size() - (separator_index + 1));
|
||||
name = escapeString(name);
|
||||
value = escapeString(value);
|
||||
if (name.empty() || value.empty()) continue;
|
||||
if (read_net)
|
||||
net->net_cfg[name] = value;
|
||||
else
|
||||
net->layers_cfg[layers_counter][name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string anchors = net->layers_cfg[net->layers_cfg.size() - 1]["anchors"];
|
||||
std::vector<float> vec = getNumbers<float>(anchors);
|
||||
std::map<std::string, std::string> &net_params = net->net_cfg;
|
||||
net->width = getParam(net_params, "width", 416);
|
||||
net->height = getParam(net_params, "height", 416);
|
||||
net->channels = getParam(net_params, "channels", 3);
|
||||
CV_Assert(net->width > 0 && net->height > 0 && net->channels > 0);
|
||||
|
||||
MatShape tensor_shape(3);
|
||||
tensor_shape[0] = net->channels;
|
||||
tensor_shape[1] = net->height;
|
||||
tensor_shape[2] = net->width;
|
||||
net->out_channels_vec.resize(net->layers_cfg.size());
|
||||
|
||||
layers_counter = -1;
|
||||
|
||||
setLayersParams setParams(net);
|
||||
|
||||
typedef std::map<int, std::map<std::string, std::string> >::iterator it_type;
|
||||
for (it_type i = net->layers_cfg.begin(); i != net->layers_cfg.end(); ++i) {
|
||||
++layers_counter;
|
||||
std::map<std::string, std::string> &layer_params = i->second;
|
||||
std::string layer_type = layer_params["layer_type"];
|
||||
|
||||
if (layer_type == "convolutional")
|
||||
{
|
||||
int kernel_size = getParam<int>(layer_params, "size", -1);
|
||||
int pad = getParam<int>(layer_params, "pad", 0);
|
||||
int padding = getParam<int>(layer_params, "padding", 0);
|
||||
int stride = getParam<int>(layer_params, "stride", 1);
|
||||
int filters = getParam<int>(layer_params, "filters", -1);
|
||||
int groups = getParam<int>(layer_params, "groups", 1);
|
||||
bool batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
||||
int flipped = getParam<int>(layer_params, "flipped", 0);
|
||||
if (flipped == 1)
|
||||
CV_Error(cv::Error::StsNotImplemented, "Transpose the convolutional weights is not implemented");
|
||||
|
||||
if (pad)
|
||||
padding = kernel_size / 2;
|
||||
|
||||
// Cannot divide 0
|
||||
CV_Assert(stride > 0);
|
||||
CV_Assert(kernel_size > 0 && filters > 0);
|
||||
CV_Assert(tensor_shape[0] > 0);
|
||||
CV_Assert(tensor_shape[0] % groups == 0);
|
||||
|
||||
setParams.setConvolution(kernel_size, padding, stride, filters, tensor_shape[0],
|
||||
groups, batch_normalize);
|
||||
|
||||
tensor_shape[0] = filters;
|
||||
tensor_shape[1] = (tensor_shape[1] - kernel_size + 2 * padding) / stride + 1;
|
||||
tensor_shape[2] = (tensor_shape[2] - kernel_size + 2 * padding) / stride + 1;
|
||||
}
|
||||
else if (layer_type == "connected")
|
||||
{
|
||||
int output = getParam<int>(layer_params, "output", 1);
|
||||
bool batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
||||
|
||||
CV_Assert(output > 0);
|
||||
|
||||
setParams.setFullyConnected(output, batch_normalize);
|
||||
|
||||
if(layers_counter && tensor_shape[1] > 1)
|
||||
net->out_channels_vec[layers_counter-1] = total(tensor_shape);
|
||||
|
||||
tensor_shape[0] = output;
|
||||
tensor_shape[1] = 1;
|
||||
tensor_shape[2] = 1;
|
||||
}
|
||||
else if (layer_type == "maxpool")
|
||||
{
|
||||
int kernel_size = getParam<int>(layer_params, "size", 2);
|
||||
int stride = getParam<int>(layer_params, "stride", 2);
|
||||
int padding = getParam<int>(layer_params, "padding", kernel_size - 1);
|
||||
// Cannot divide 0
|
||||
CV_Assert(stride > 0);
|
||||
|
||||
setParams.setMaxpool(kernel_size, padding, stride);
|
||||
|
||||
tensor_shape[1] = (tensor_shape[1] - kernel_size + padding) / stride + 1;
|
||||
tensor_shape[2] = (tensor_shape[2] - kernel_size + padding) / stride + 1;
|
||||
}
|
||||
else if (layer_type == "avgpool")
|
||||
{
|
||||
setParams.setAvgpool();
|
||||
tensor_shape[1] = 1;
|
||||
tensor_shape[2] = 1;
|
||||
}
|
||||
else if (layer_type == "crop")
|
||||
{
|
||||
int crop_height = getParam<int>(layer_params, "crop_height", 0);
|
||||
int crop_width = getParam<int>(layer_params, "crop_width", 0);
|
||||
bool noadjust = getParam<int>(layer_params, "noadjust", false);
|
||||
CV_CheckGT(crop_height, 0, "");
|
||||
CV_CheckGT(crop_width, 0, "");
|
||||
|
||||
setParams.setCrop(crop_height, crop_width, tensor_shape[1], tensor_shape[2], noadjust);
|
||||
|
||||
tensor_shape[1] = crop_height;
|
||||
tensor_shape[2] = crop_width;
|
||||
}
|
||||
else if (layer_type == "softmax")
|
||||
{
|
||||
int groups = getParam<int>(layer_params, "groups", 1);
|
||||
if (groups != 1)
|
||||
CV_Error(Error::StsNotImplemented, "Softmax from Darknet with groups != 1");
|
||||
setParams.setSoftmax();
|
||||
}
|
||||
else if (layer_type == "route")
|
||||
{
|
||||
std::string bottom_layers = getParam<std::string>(layer_params, "layers", "");
|
||||
CV_Assert(!bottom_layers.empty());
|
||||
int groups = getParam<int>(layer_params, "groups", 1);
|
||||
std::vector<int> layers_vec = getNumbers<int>(bottom_layers);
|
||||
|
||||
tensor_shape[0] = 0;
|
||||
for (size_t k = 0; k < layers_vec.size(); ++k) {
|
||||
layers_vec[k] = layers_vec[k] >= 0 ? layers_vec[k] : (layers_vec[k] + layers_counter);
|
||||
tensor_shape[0] += net->out_channels_vec[layers_vec[k]];
|
||||
}
|
||||
|
||||
if (groups > 1)
|
||||
{
|
||||
int group_id = getParam<int>(layer_params, "group_id", 0);
|
||||
tensor_shape[0] /= groups;
|
||||
int split_size = tensor_shape[0] / layers_vec.size();
|
||||
for (size_t k = 0; k < layers_vec.size(); ++k)
|
||||
setParams.setSlice(layers_vec[k], split_size, group_id);
|
||||
|
||||
if (layers_vec.size() > 1)
|
||||
{
|
||||
// layer ids in layers_vec - inputs of Slice layers
|
||||
// after adding offset to layers_vec: layer ids - outputs of Slice layers
|
||||
for (size_t k = 0; k < layers_vec.size(); ++k)
|
||||
layers_vec[k] += layers_vec.size();
|
||||
|
||||
setParams.setConcat(layers_vec.size(), layers_vec.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (layers_vec.size() == 1)
|
||||
setParams.setIdentity(layers_vec.at(0));
|
||||
else
|
||||
setParams.setConcat(layers_vec.size(), layers_vec.data());
|
||||
}
|
||||
}
|
||||
else if (layer_type == "dropout" || layer_type == "cost")
|
||||
{
|
||||
setParams.setIdentity(layers_counter-1);
|
||||
}
|
||||
else if (layer_type == "reorg")
|
||||
{
|
||||
int stride = getParam<int>(layer_params, "stride", 2);
|
||||
// Cannot divide 0
|
||||
CV_Assert(stride > 0);
|
||||
tensor_shape[0] = tensor_shape[0] * (stride * stride);
|
||||
tensor_shape[1] = tensor_shape[1] / stride;
|
||||
tensor_shape[2] = tensor_shape[2] / stride;
|
||||
|
||||
setParams.setReorg(stride);
|
||||
}
|
||||
else if (layer_type == "region")
|
||||
{
|
||||
float thresh = getParam<float>(layer_params, "thresh", 0.001);
|
||||
int coords = getParam<int>(layer_params, "coords", 4);
|
||||
int classes = getParam<int>(layer_params, "classes", -1);
|
||||
int num_of_anchors = getParam<int>(layer_params, "num", -1);
|
||||
int classfix = getParam<int>(layer_params, "classfix", 0);
|
||||
bool softmax = (getParam<int>(layer_params, "softmax", 0) == 1);
|
||||
bool softmax_tree = (getParam<std::string>(layer_params, "tree", "").size() > 0);
|
||||
|
||||
std::string anchors_values = getParam<std::string>(layer_params, "anchors", std::string());
|
||||
CV_Assert(!anchors_values.empty());
|
||||
std::vector<float> anchors_vec = getNumbers<float>(anchors_values);
|
||||
|
||||
CV_Assert(classes > 0 && num_of_anchors > 0 && (num_of_anchors * 2) == anchors_vec.size());
|
||||
|
||||
setParams.setPermute(false);
|
||||
setParams.setRegion(thresh, coords, classes, num_of_anchors, classfix, softmax, softmax_tree, anchors_vec.data());
|
||||
}
|
||||
else if (layer_type == "shortcut")
|
||||
{
|
||||
std::string bottom_layer = getParam<std::string>(layer_params, "from", "");
|
||||
float alpha = getParam<float>(layer_params, "alpha", 1);
|
||||
float beta = getParam<float>(layer_params, "beta", 0);
|
||||
if (beta != 0)
|
||||
CV_Error(Error::StsNotImplemented, "Non-zero beta");
|
||||
CV_Assert(!bottom_layer.empty());
|
||||
int from = std::atoi(bottom_layer.c_str());
|
||||
|
||||
from = from < 0 ? from + layers_counter : from;
|
||||
setParams.setShortcut(from, alpha);
|
||||
}
|
||||
else if (layer_type == "scale_channels")
|
||||
{
|
||||
std::string bottom_layer = getParam<std::string>(layer_params, "from", "");
|
||||
CV_Assert(!bottom_layer.empty());
|
||||
int from = std::atoi(bottom_layer.c_str());
|
||||
from = from < 0 ? from + layers_counter : from;
|
||||
setParams.setScaleChannels(from);
|
||||
}
|
||||
else if (layer_type == "sam")
|
||||
{
|
||||
std::string bottom_layer = getParam<std::string>(layer_params, "from", "");
|
||||
CV_Assert(!bottom_layer.empty());
|
||||
int from = std::atoi(bottom_layer.c_str());
|
||||
from = from < 0 ? from + layers_counter : from;
|
||||
setParams.setSAM(from);
|
||||
}
|
||||
else if (layer_type == "upsample")
|
||||
{
|
||||
int scaleFactor = getParam<int>(layer_params, "stride", 1);
|
||||
setParams.setUpsample(scaleFactor);
|
||||
tensor_shape[1] = tensor_shape[1] * scaleFactor;
|
||||
tensor_shape[2] = tensor_shape[2] * scaleFactor;
|
||||
}
|
||||
else if (layer_type == "yolo")
|
||||
{
|
||||
int classes = getParam<int>(layer_params, "classes", -1);
|
||||
int num_of_anchors = getParam<int>(layer_params, "num", -1);
|
||||
float thresh = getParam<float>(layer_params, "thresh", 0.2);
|
||||
float nms_threshold = getParam<float>(layer_params, "nms_threshold", 0.0);
|
||||
float scale_x_y = getParam<float>(layer_params, "scale_x_y", 1.0);
|
||||
int new_coords = getParam<int>(layer_params, "new_coords", 0);
|
||||
|
||||
std::string anchors_values = getParam<std::string>(layer_params, "anchors", std::string());
|
||||
CV_Assert(!anchors_values.empty());
|
||||
std::vector<float> anchors_vec = getNumbers<float>(anchors_values);
|
||||
|
||||
std::string mask_values = getParam<std::string>(layer_params, "mask", std::string());
|
||||
CV_Assert(!mask_values.empty());
|
||||
std::vector<int> mask_vec = getNumbers<int>(mask_values);
|
||||
|
||||
CV_Assert(classes > 0 && num_of_anchors > 0 && (num_of_anchors * 2) == anchors_vec.size());
|
||||
|
||||
setParams.setPermute(false);
|
||||
setParams.setYolo(classes, mask_vec, anchors_vec, thresh, nms_threshold, scale_x_y, new_coords);
|
||||
}
|
||||
else {
|
||||
CV_Error(cv::Error::StsParseError, "Unknown layer type: " + layer_type);
|
||||
}
|
||||
|
||||
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
|
||||
if (activation != "linear")
|
||||
setParams.setActivation(activation);
|
||||
|
||||
net->out_channels_vec[layers_counter] = tensor_shape[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadDarknetFromWeightsStream(std::istream &ifile, NetParameter *net)
|
||||
{
|
||||
int32_t major_ver, minor_ver, revision;
|
||||
ifile.read(reinterpret_cast<char *>(&major_ver), sizeof(int32_t));
|
||||
ifile.read(reinterpret_cast<char *>(&minor_ver), sizeof(int32_t));
|
||||
ifile.read(reinterpret_cast<char *>(&revision), sizeof(int32_t));
|
||||
|
||||
uint64_t seen;
|
||||
if ((major_ver * 10 + minor_ver) >= 2) {
|
||||
ifile.read(reinterpret_cast<char *>(&seen), sizeof(uint64_t));
|
||||
}
|
||||
else {
|
||||
int32_t iseen = 0;
|
||||
ifile.read(reinterpret_cast<char *>(&iseen), sizeof(int32_t));
|
||||
seen = iseen;
|
||||
}
|
||||
bool transpose = (major_ver > 1000) || (minor_ver > 1000);
|
||||
if(transpose)
|
||||
CV_Error(cv::Error::StsNotImplemented, "Transpose the weights (except for convolutional) is not implemented");
|
||||
|
||||
MatShape tensor_shape(3);
|
||||
tensor_shape[0] = net->channels;
|
||||
tensor_shape[1] = net->height;
|
||||
tensor_shape[2] = net->width;
|
||||
int cv_layers_counter = -1;
|
||||
int darknet_layers_counter = -1;
|
||||
|
||||
setLayersParams setParams(net);
|
||||
|
||||
typedef std::map<int, std::map<std::string, std::string> >::iterator it_type;
|
||||
for (it_type i = net->layers_cfg.begin(); i != net->layers_cfg.end(); ++i) {
|
||||
++darknet_layers_counter;
|
||||
++cv_layers_counter;
|
||||
std::map<std::string, std::string> &layer_params = i->second;
|
||||
std::string layer_type = layer_params["layer_type"];
|
||||
|
||||
if (layer_type == "convolutional" || layer_type == "connected")
|
||||
{
|
||||
int filters;
|
||||
bool use_batch_normalize;
|
||||
cv::Mat weightsBlob;
|
||||
if(layer_type == "convolutional")
|
||||
{
|
||||
int kernel_size = getParam<int>(layer_params, "size", -1);
|
||||
filters = getParam<int>(layer_params, "filters", -1);
|
||||
int groups = getParam<int>(layer_params, "groups", 1);
|
||||
use_batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
||||
|
||||
CV_Assert(kernel_size > 0 && filters > 0);
|
||||
CV_Assert(tensor_shape[0] > 0);
|
||||
CV_Assert(tensor_shape[0] % groups == 0);
|
||||
|
||||
int sizes_weights[] = { filters, tensor_shape[0] / groups, kernel_size, kernel_size };
|
||||
weightsBlob.create(4, sizes_weights, CV_32F);
|
||||
}
|
||||
else
|
||||
{
|
||||
filters = getParam<int>(layer_params, "output", 1);
|
||||
use_batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
||||
|
||||
CV_Assert(filters>0);
|
||||
|
||||
int sizes_weights[] = { filters, total(tensor_shape) };
|
||||
weightsBlob.create(2, sizes_weights, CV_32F);
|
||||
}
|
||||
CV_Assert(weightsBlob.isContinuous());
|
||||
|
||||
cv::Mat meanData_mat(1, filters, CV_32F); // mean
|
||||
cv::Mat stdData_mat(1, filters, CV_32F); // variance
|
||||
cv::Mat weightsData_mat(1, filters, CV_32F);// scale
|
||||
cv::Mat biasData_mat(1, filters, CV_32F); // bias
|
||||
|
||||
ifile.read(reinterpret_cast<char *>(biasData_mat.ptr<float>()), sizeof(float)*filters);
|
||||
if (use_batch_normalize) {
|
||||
ifile.read(reinterpret_cast<char *>(weightsData_mat.ptr<float>()), sizeof(float)*filters);
|
||||
ifile.read(reinterpret_cast<char *>(meanData_mat.ptr<float>()), sizeof(float)*filters);
|
||||
ifile.read(reinterpret_cast<char *>(stdData_mat.ptr<float>()), sizeof(float)*filters);
|
||||
}
|
||||
ifile.read(reinterpret_cast<char *>(weightsBlob.ptr<float>()), sizeof(float)*weightsBlob.total());
|
||||
|
||||
// set conv/connected weights
|
||||
std::vector<cv::Mat> layer_blobs;
|
||||
layer_blobs.push_back(weightsBlob);
|
||||
if (!use_batch_normalize) {
|
||||
// use BIAS in any case
|
||||
layer_blobs.push_back(biasData_mat);
|
||||
}
|
||||
setParams.setLayerBlobs(cv_layers_counter, layer_blobs);
|
||||
|
||||
// set batch normalize (mean, variance, scale, bias)
|
||||
if (use_batch_normalize) {
|
||||
++cv_layers_counter;
|
||||
std::vector<cv::Mat> bn_blobs;
|
||||
bn_blobs.push_back(meanData_mat);
|
||||
bn_blobs.push_back(stdData_mat);
|
||||
bn_blobs.push_back(weightsData_mat);
|
||||
bn_blobs.push_back(biasData_mat);
|
||||
setParams.setLayerBlobs(cv_layers_counter, bn_blobs);
|
||||
}
|
||||
}
|
||||
if (layer_type == "region" || layer_type == "yolo")
|
||||
{
|
||||
++cv_layers_counter; // For permute.
|
||||
}
|
||||
|
||||
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
|
||||
if (activation != "linear")
|
||||
++cv_layers_counter; // For ReLU, Swish, Mish, Sigmoid, etc
|
||||
|
||||
if(!darknet_layers_counter)
|
||||
tensor_shape.resize(1);
|
||||
|
||||
tensor_shape[0] = net->out_channels_vec[darknet_layers_counter];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ReadNetParamsFromCfgStreamOrDie(std::istream &ifile, darknet::NetParameter *net)
|
||||
{
|
||||
if (!darknet::ReadDarknetFromCfgStream(ifile, net)) {
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter stream");
|
||||
}
|
||||
}
|
||||
|
||||
void ReadNetParamsFromBinaryStreamOrDie(std::istream &ifile, darknet::NetParameter *net)
|
||||
{
|
||||
if (!darknet::ReadDarknetFromWeightsStream(ifile, net)) {
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
// (3-clause BSD License)
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the names of the copyright holders nor the names of the contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//MIT License
|
||||
//
|
||||
//Copyright (c) 2017 Joseph Redmon
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_DNN_DARKNET_IO_HPP__
|
||||
#define __OPENCV_DNN_DARKNET_IO_HPP__
|
||||
|
||||
#include <opencv2/dnn/dnn.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
namespace darknet {
|
||||
|
||||
class LayerParameter {
|
||||
std::string layer_name, layer_type;
|
||||
std::vector<std::string> bottom_indexes;
|
||||
cv::dnn::LayerParams layerParams;
|
||||
public:
|
||||
friend class setLayersParams;
|
||||
cv::dnn::LayerParams getLayerParams() const { return layerParams; }
|
||||
std::string name() const { return layer_name; }
|
||||
std::string type() const { return layer_type; }
|
||||
int bottom_size() const { return bottom_indexes.size(); }
|
||||
std::string bottom(const int index) const { return bottom_indexes.at(index); }
|
||||
int top_size() const { return 1; }
|
||||
std::string top(const int index) const { return layer_name; }
|
||||
};
|
||||
|
||||
class NetParameter {
|
||||
public:
|
||||
int width, height, channels;
|
||||
std::vector<LayerParameter> layers;
|
||||
std::vector<int> out_channels_vec;
|
||||
|
||||
std::map<int, std::map<std::string, std::string> > layers_cfg;
|
||||
std::map<std::string, std::string> net_cfg;
|
||||
|
||||
NetParameter() : width(0), height(0), channels(0) {}
|
||||
|
||||
int layer_size() const { return layers.size(); }
|
||||
|
||||
int input_size() const { return 1; }
|
||||
std::string input(const int index) const { return "data"; }
|
||||
LayerParameter layer(const int index) const { return layers.at(index); }
|
||||
};
|
||||
}
|
||||
|
||||
// Read parameters from a stream into a NetParameter message.
|
||||
void ReadNetParamsFromCfgStreamOrDie(std::istream &ifile, darknet::NetParameter *net);
|
||||
void ReadNetParamsFromBinaryStreamOrDie(std::istream &ifile, darknet::NetParameter *net);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -37,7 +37,7 @@ Net readNet(const String& _model, const String& _config, const String& _framewor
|
||||
{
|
||||
if (modelExt == "cfg" || configExt == "weights")
|
||||
std::swap(model, config);
|
||||
return readNetFromDarknet(config, model);
|
||||
CV_Error(Error::StsError, "Darknet importer has been removed. Please use readNet(\"darknet\", ...) with ONNX-converted models or use an older OpenCV version.");
|
||||
}
|
||||
if (framework == "dldt" || framework == "openvino" ||
|
||||
modelExt == "bin" || configExt == "bin" ||
|
||||
@@ -65,7 +65,7 @@ Net readNet(const String& _framework, const std::vector<uchar>& bufferModel,
|
||||
else if (framework == "tensorflow")
|
||||
return readNetFromTensorflow(bufferModel, bufferConfig, engine);
|
||||
else if (framework == "darknet")
|
||||
return readNetFromDarknet(bufferConfig, bufferModel);
|
||||
CV_Error(Error::StsError, "Darknet importer has been removed. Please use ONNX-converted models or use an older OpenCV version.");
|
||||
else if (framework == "dldt" || framework == "openvino")
|
||||
return readNetFromModelOptimizer(bufferConfig, bufferModel);
|
||||
else if (framework == "tflite")
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define __OPENCV_TEST_COMMON_HPP__
|
||||
|
||||
#include "opencv2/dnn/utils/inference_engine.hpp"
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
@@ -247,6 +248,23 @@ protected:
|
||||
|
||||
void runLayer(cv::Ptr<cv::dnn::Layer> layer, std::vector<cv::Mat> &inpBlobs, std::vector<cv::Mat> &outBlobs);
|
||||
|
||||
inline std::string getCurrentTestNameNoParams()
|
||||
{
|
||||
const ::testing::TestInfo* const test_info =
|
||||
::testing::UnitTest::GetInstance()->current_test_info();
|
||||
if (!test_info)
|
||||
return std::string();
|
||||
std::string suite = test_info->test_case_name();
|
||||
std::string name = test_info->name();
|
||||
const auto suite_slash = suite.find('/');
|
||||
if (suite_slash != std::string::npos)
|
||||
suite = suite.substr(0, suite_slash);
|
||||
const auto name_slash = name.find('/');
|
||||
if (name_slash != std::string::npos)
|
||||
name = name.substr(0, name_slash);
|
||||
return suite + "." + name;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,145 +53,45 @@ static std::string _tf(TString filename)
|
||||
return (getOpenCVExtraDir() + "/dnn/") + filename;
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_tiny_yolo_voc)
|
||||
TEST(Test_YOLO, read_yolov4_onnx)
|
||||
{
|
||||
Net net = readNetFromDarknet(_tf("tiny-yolo-voc.cfg"));
|
||||
auto engine_forced = static_cast<cv::dnn::EngineType>(
|
||||
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
|
||||
if (engine_forced == cv::dnn::ENGINE_CLASSIC)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_PARSER);
|
||||
return;
|
||||
}
|
||||
Net net = readNet(findDataFile("dnn/yolov4.onnx", false));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_yolo_voc)
|
||||
{
|
||||
Net net = readNetFromDarknet(_tf("yolo-voc.cfg"));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_yolo_voc_stream)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_MEMORY_1GB,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
Mat ref;
|
||||
Mat sample = imread(_tf("dog416.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0/255, Size(416, 416), Scalar(), true, false);
|
||||
const std::string cfgFile = findDataFile("dnn/yolo-voc.cfg");
|
||||
const std::string weightsFile = findDataFile("dnn/yolo-voc.weights", false);
|
||||
// Import by paths.
|
||||
{
|
||||
Net net = readNetFromDarknet(cfgFile, weightsFile);
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.enableWinograd(false);
|
||||
ref = net.forward();
|
||||
}
|
||||
// Import from bytes array.
|
||||
{
|
||||
std::vector<char> cfg, weights;
|
||||
readFileContent(cfgFile, cfg);
|
||||
readFileContent(weightsFile, weights);
|
||||
|
||||
Net net = readNetFromDarknet(cfg.data(), cfg.size(), weights.data(), weights.size());
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.enableWinograd(false);
|
||||
Mat out = net.forward();
|
||||
normAssert(ref, out);
|
||||
}
|
||||
}
|
||||
|
||||
class Test_Darknet_layers : public DNNTestLayer
|
||||
class Test_YOLO_nets : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
void testDarknetLayer(const std::string& name, bool hasWeights = false, bool testBatchProcessing = true,
|
||||
double l1 = 0.0, double lInf = 0.0)
|
||||
// Test object detection network from ONNX model.
|
||||
void testYOLOModel(const std::string& model,
|
||||
const std::vector<std::vector<int> >& refClassIds,
|
||||
const std::vector<std::vector<float> >& refConfidences,
|
||||
const std::vector<std::vector<Rect2d> >& refBoxes,
|
||||
double scoreDiff, double iouDiff, float confThreshold = 0.24,
|
||||
float nmsThreshold = 0.4, bool useWinograd = true,
|
||||
int zeroPadW = 0, Size inputSize = Size())
|
||||
{
|
||||
SCOPED_TRACE(name);
|
||||
Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy"));
|
||||
Mat ref = blobFromNPY(findDataFile("dnn/darknet/" + name + "_out.npy"));
|
||||
l1 = l1 ? l1 : default_l1;
|
||||
lInf = lInf ? lInf : default_lInf;
|
||||
|
||||
std::string cfg = findDataFile("dnn/darknet/" + name + ".cfg");
|
||||
std::string model = "";
|
||||
if (hasWeights)
|
||||
model = findDataFile("dnn/darknet/" + name + ".weights");
|
||||
|
||||
checkBackend(&inp, &ref);
|
||||
|
||||
Net net = readNet(cfg, model);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
normAssert(out, ref, "", l1, lInf);
|
||||
|
||||
if (inp.size[0] == 1 && testBatchProcessing) // test handling of batch size
|
||||
auto engine_forced = static_cast<cv::dnn::EngineType>(
|
||||
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
|
||||
if (engine_forced == cv::dnn::ENGINE_CLASSIC)
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if (target == DNN_TARGET_MYRIAD && name == "shortcut")
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
#endif
|
||||
|
||||
MatShape sz2 = shape(inp);
|
||||
sz2[0] = 2;
|
||||
|
||||
Net net2 = readNet(cfg, model);
|
||||
net2.setPreferableBackend(backend);
|
||||
net2.setPreferableTarget(target);
|
||||
Range ranges0[4] = { Range(0, 1), Range::all(), Range::all(), Range::all() };
|
||||
Range ranges1[4] = { Range(1, 2), Range::all(), Range::all(), Range::all() };
|
||||
Mat inp2(sz2, inp.type(), Scalar::all(0));
|
||||
inp.copyTo(inp2(ranges0));
|
||||
inp.copyTo(inp2(ranges1));
|
||||
net2.setInput(inp2);
|
||||
Mat out2 = net2.forward();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
EXPECT_LT(cv::norm(out2(ranges0), out2(ranges1), NORM_INF), 1e-4) << "Batch result is not similar: " << name;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(0, cv::norm(out2(ranges0), out2(ranges1), NORM_INF)) << "Batch result is not equal: " << name;
|
||||
}
|
||||
|
||||
Mat ref2 = ref;
|
||||
if (ref.dims == 2 && out2.dims == 3)
|
||||
{
|
||||
int ref_3d_sizes[3] = {1, ref.rows, ref.cols};
|
||||
ref2 = Mat(3, ref_3d_sizes, ref.type(), (void*)ref.data);
|
||||
}
|
||||
/*else if (ref.dims == 3 && out2.dims == 4)
|
||||
{
|
||||
int ref_4d_sizes[4] = {1, ref.size[0], ref.size[1], ref.size[2]};
|
||||
ref2 = Mat(4, ref_4d_sizes, ref.type(), (void*)ref.data);
|
||||
}*/
|
||||
ASSERT_EQ(out2.dims, ref2.dims) << ref.dims;
|
||||
|
||||
normAssert(out2(ranges0), ref2, "", l1, lInf);
|
||||
normAssert(out2(ranges1), ref2, "", l1, lInf);
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_PARSER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Test_Darknet_nets : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
// Test object detection network from Darknet framework.
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const std::vector<std::vector<int> >& refClassIds,
|
||||
const std::vector<std::vector<float> >& refConfidences,
|
||||
const std::vector<std::vector<Rect2d> >& refBoxes,
|
||||
double scoreDiff, double iouDiff, float confThreshold = 0.24,
|
||||
float nmsThreshold = 0.4, bool useWinograd = true,
|
||||
int zeroPadW = 0)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat img1 = imread(_tf("dog416.png"));
|
||||
Mat img2 = imread(_tf("street.png"));
|
||||
cv::resize(img2, img2, Size(416, 416));
|
||||
cv::resize(img1, img1, inputSize);
|
||||
cv::resize(img2, img2, inputSize);
|
||||
|
||||
// Pad images by black pixel at the right to test not equal width and height sizes
|
||||
if (zeroPadW) {
|
||||
@@ -209,8 +109,7 @@ public:
|
||||
|
||||
Mat inp = blobFromImages(samples, 1.0/255, Size(), Scalar(), true, false);
|
||||
|
||||
Net net = readNet(findDataFile("dnn/" + cfg),
|
||||
findDataFile("dnn/" + weights, false));
|
||||
Net net = readNet(findDataFile("dnn/" + model, false));
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.enableWinograd(useWinograd);
|
||||
@@ -218,41 +117,118 @@ public:
|
||||
std::vector<Mat> outs;
|
||||
net.forward(outs, net.getUnconnectedOutLayersNames());
|
||||
|
||||
// Detect output format: pytorch-YOLOv4 exports "boxes" [batch, N, 1, 4] + "confs" [batch, N, classes]
|
||||
bool isBoxConfsFormat = (outs.size() == 2 && outs[0].dims == 4 && outs[0].size[outs[0].dims - 1] == 4);
|
||||
// Detect 3-output format: boxes [batch, N, 4] + scores [batch, N] + class_idx [batch, N]
|
||||
bool isBoxScoresIdxFormat = (outs.size() == 3 && outs[0].dims == 3 && outs[0].size[2] == 4);
|
||||
|
||||
for (int b = 0; b < batch_size; ++b)
|
||||
{
|
||||
std::vector<int> classIds;
|
||||
std::vector<float> confidences;
|
||||
std::vector<Rect2d> boxes;
|
||||
for (int i = 0; i < outs.size(); ++i)
|
||||
if (isBoxScoresIdxFormat)
|
||||
{
|
||||
Mat out;
|
||||
if (batch_size > 1){
|
||||
// get the sample slice from 3D matrix (batch, box, classes+5)
|
||||
Range ranges[3] = {Range(b, b+1), Range::all(), Range::all()};
|
||||
out = outs[i](ranges).reshape(1, outs[i].size[1]);
|
||||
}else{
|
||||
out = outs[i];
|
||||
}
|
||||
for (int j = 0; j < out.rows; ++j)
|
||||
// yolov3-style format: boxes [batch, N, 4] + scores [batch, N] + class_idx [batch, N]
|
||||
// boxes are [x1, y1, x2, y2] in pixel coords (relative to model input size)
|
||||
int N = outs[0].size[1];
|
||||
float* boxesPtr = outs[0].ptr<float>(b);
|
||||
float* scoresPtr = outs[1].ptr<float>(b);
|
||||
float* classIdxPtr = outs[2].ptr<float>(b);
|
||||
|
||||
float modelW = (float)inp.size[3];
|
||||
float modelH = (float)inp.size[2];
|
||||
|
||||
for (int j = 0; j < N; ++j)
|
||||
{
|
||||
Mat scores = out.row(j).colRange(5, out.cols);
|
||||
float score = scoresPtr[j];
|
||||
if (score > confThreshold)
|
||||
{
|
||||
float x1 = boxesPtr[j * 4 + 0] / modelW;
|
||||
float y1 = boxesPtr[j * 4 + 1] / modelH;
|
||||
float x2 = boxesPtr[j * 4 + 2] / modelW;
|
||||
float y2 = boxesPtr[j * 4 + 3] / modelH;
|
||||
boxes.push_back(Rect2d(x1, y1, x2 - x1, y2 - y1));
|
||||
confidences.push_back(score);
|
||||
classIds.push_back((int)classIdxPtr[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isBoxConfsFormat)
|
||||
{
|
||||
// boxes [batch, N, 1, 4] (x1,y1,x2,y2), confs [batch, N, num_classes]
|
||||
Mat boxesMat = outs[0];
|
||||
Mat confsMat = outs[1];
|
||||
if (batch_size > 1)
|
||||
{
|
||||
if (boxesMat.dims == 4) {
|
||||
Range boxRanges[4] = {Range(b, b+1), Range::all(), Range::all(), Range::all()};
|
||||
boxesMat = boxesMat(boxRanges);
|
||||
} else {
|
||||
Range boxRanges[3] = {Range(b, b+1), Range::all(), Range::all()};
|
||||
boxesMat = boxesMat(boxRanges);
|
||||
}
|
||||
Range confRanges[3] = {Range(b, b+1), Range::all(), Range::all()};
|
||||
confsMat = confsMat(confRanges);
|
||||
}
|
||||
|
||||
int numBoxes = (int)(boxesMat.total() / 4);
|
||||
boxesMat = boxesMat.reshape(1, numBoxes);
|
||||
confsMat = confsMat.reshape(1, numBoxes);
|
||||
|
||||
for (int j = 0; j < numBoxes; ++j)
|
||||
{
|
||||
Mat scores = confsMat.row(j);
|
||||
double confidence;
|
||||
Point maxLoc;
|
||||
minMaxLoc(scores, 0, &confidence, 0, &maxLoc);
|
||||
|
||||
if (confidence > confThreshold) {
|
||||
float* detection = out.ptr<float>(j);
|
||||
double centerX = detection[0];
|
||||
double centerY = detection[1];
|
||||
double width = detection[2];
|
||||
double height = detection[3];
|
||||
boxes.push_back(Rect2d(centerX - 0.5 * width, centerY - 0.5 * height,
|
||||
width, height));
|
||||
float* box = boxesMat.ptr<float>(j);
|
||||
double x1 = box[0];
|
||||
double y1 = box[1];
|
||||
double x2 = box[2];
|
||||
double y2 = box[3];
|
||||
boxes.push_back(Rect2d(x1, y1, x2 - x1, y2 - y1));
|
||||
confidences.push_back(confidence);
|
||||
classIds.push_back(maxLoc.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < (int)outs.size(); ++i)
|
||||
{
|
||||
Mat out;
|
||||
if (batch_size > 1){
|
||||
Range ranges[3] = {Range(b, b+1), Range::all(), Range::all()};
|
||||
out = outs[i](ranges).reshape(1, outs[i].size[1]);
|
||||
}else{
|
||||
out = outs[i];
|
||||
}
|
||||
for (int j = 0; j < out.rows; ++j)
|
||||
{
|
||||
float objConf = out.at<float>(j, 4);
|
||||
Mat scores = out.row(j).colRange(5, out.cols);
|
||||
double maxClsScore;
|
||||
Point maxLoc;
|
||||
minMaxLoc(scores, 0, &maxClsScore, 0, &maxLoc);
|
||||
double confidence = objConf * maxClsScore;
|
||||
|
||||
if (confidence > confThreshold) {
|
||||
float* detection = out.ptr<float>(j);
|
||||
double centerX = detection[0];
|
||||
double centerY = detection[1];
|
||||
double width = detection[2];
|
||||
double height = detection[3];
|
||||
boxes.push_back(Rect2d(centerX - 0.5 * width, centerY - 0.5 * height,
|
||||
width, height));
|
||||
confidences.push_back(confidence);
|
||||
classIds.push_back(maxLoc.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// here we need NMS of boxes
|
||||
std::vector<int> indices;
|
||||
@@ -300,25 +276,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refConfidences,
|
||||
const std::vector<Rect2d>& refBoxes,
|
||||
double scoreDiff, double iouDiff, float confThreshold = 0.24,
|
||||
float nmsThreshold = 0.4, bool useWinograd = true,
|
||||
int zeroPadW = 0)
|
||||
void testYOLOModel(const std::string& model,
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refConfidences,
|
||||
const std::vector<Rect2d>& refBoxes,
|
||||
double scoreDiff, double iouDiff, float confThreshold = 0.24,
|
||||
float nmsThreshold = 0.4, bool useWinograd = true,
|
||||
int zeroPadW = 0, Size inputSize = Size())
|
||||
{
|
||||
testDarknetModel(cfg, weights,
|
||||
std::vector<std::vector<int> >(1, refClassIds),
|
||||
std::vector<std::vector<float> >(1, refConfidences),
|
||||
std::vector<std::vector<Rect2d> >(1, refBoxes),
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, useWinograd, zeroPadW);
|
||||
testYOLOModel(model,
|
||||
std::vector<std::vector<int> >(1, refClassIds),
|
||||
std::vector<std::vector<float> >(1, refConfidences),
|
||||
std::vector<std::vector<Rect2d> >(1, refBoxes),
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, useWinograd, zeroPadW, inputSize);
|
||||
}
|
||||
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const cv::Mat& ref, double scoreDiff, double iouDiff,
|
||||
float confThreshold = 0.24, float nmsThreshold = 0.4, bool useWinograd = true,
|
||||
int zeroPadW = 0)
|
||||
void testYOLOModel(const std::string& model,
|
||||
const cv::Mat& ref, double scoreDiff, double iouDiff,
|
||||
float confThreshold = 0.24, float nmsThreshold = 0.4, bool useWinograd = true,
|
||||
int zeroPadW = 0, Size inputSize = Size())
|
||||
{
|
||||
CV_Assert(ref.cols == 7);
|
||||
std::vector<std::vector<int> > refClassIds;
|
||||
@@ -334,7 +310,7 @@ public:
|
||||
float right = ref.at<float>(i, 5);
|
||||
float bottom = ref.at<float>(i, 6);
|
||||
Rect2d box(left, top, right - left, bottom - top);
|
||||
if (batchId >= refClassIds.size())
|
||||
if (batchId >= (int)refClassIds.size())
|
||||
{
|
||||
refClassIds.resize(batchId + 1);
|
||||
refScores.resize(batchId + 1);
|
||||
@@ -344,381 +320,12 @@ public:
|
||||
refScores[batchId].push_back(score);
|
||||
refBoxes[batchId].push_back(box);
|
||||
}
|
||||
testDarknetModel(cfg, weights, refClassIds, refScores, refBoxes,
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, useWinograd, zeroPadW);
|
||||
testYOLOModel(model, refClassIds, refScores, refBoxes,
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, useWinograd, zeroPadW, inputSize);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
{
|
||||
applyTestTag(
|
||||
#if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
#else
|
||||
CV_TEST_TAG_MEMORY_1GB,
|
||||
#endif
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
#elif defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); // need to update check function
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(6, 7) << 0, 6, 0.750469f, 0.577374f, 0.127391f, 0.902949f, 0.300809f, // a car
|
||||
0, 1, 0.780879f, 0.270762f, 0.264102f, 0.732475f, 0.745412f, // a bicycle
|
||||
0, 11, 0.901615f, 0.1386f, 0.338509f, 0.421337f, 0.938789f, // a dog
|
||||
1, 14, 0.623813f, 0.183179f, 0.381921f, 0.247726f, 0.625847f, // a person
|
||||
1, 6, 0.667770f, 0.446555f, 0.453578f, 0.499986f, 0.519167f, // a car
|
||||
1, 6, 0.844947f, 0.637058f, 0.460398f, 0.828508f, 0.66427f); // a car
|
||||
|
||||
double nmsThreshold = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16) ? 0.397 : 0.4;
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
scoreDiff = 1e-2;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.03;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string config_file = "yolo-voc.cfg";
|
||||
std::string weights_file = "yolo-voc.weights";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Exception: input != output
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// [ GENERAL_ERROR ] AssertionFailed: input != output
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, nmsThreshold, false);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); // need to update check function
|
||||
#endif
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(4, 7) << 0, 6, 0.761967f, 0.579042f, 0.159161f, 0.894482f, 0.31994f, // a car
|
||||
0, 11, 0.780595f, 0.129696f, 0.386467f, 0.445275f, 0.920994f, // a dog
|
||||
1, 6, 0.651450f, 0.460526f, 0.458019f, 0.522527f, 0.5341f, // a car
|
||||
1, 6, 0.928758f, 0.651024f, 0.463539f, 0.823784f, 0.654998f); // a car
|
||||
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
bool useWinograd = true;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 8e-3;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
else if(target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.008;
|
||||
iouDiff = 0.02;
|
||||
}
|
||||
else if (target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
useWinograd = false;
|
||||
scoreDiff = 8e-3;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
|
||||
std::string config_file = "tiny-yolo-voc.cfg";
|
||||
std::string weights_file = "tiny-yolo-voc.weights";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff, 0.24, 0.4, useWinograd);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, 0.4, useWinograd);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
static const std::chrono::milliseconds async_timeout(10000);
|
||||
|
||||
typedef testing::TestWithParam<tuple<std::string, tuple<Backend, Target> > > Test_Darknet_nets_async;
|
||||
TEST_P(Test_Darknet_nets_async, Accuracy)
|
||||
{
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
std::string prefix = get<0>(GetParam());
|
||||
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if (INF_ENGINE_VER_MAJOR_LT(2019020000) && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
#endif
|
||||
|
||||
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("No support for async forward");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
if (targetId == DNN_TARGET_MYRIAD && prefix == "yolov3") // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
if (targetId == DNN_TARGET_MYRIAD && prefix == "yolov3") // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE)
|
||||
if (targetId == DNN_TARGET_MYRIAD && prefix == "yolov4") // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
const int numInputs = 2;
|
||||
std::vector<Mat> inputs(numInputs);
|
||||
int blobSize[] = {1, 3, 416, 416};
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
inputs[i].create(4, &blobSize[0], CV_32F);
|
||||
randu(inputs[i], 0, 1);
|
||||
}
|
||||
|
||||
Net netSync = readNet(findDataFile("dnn/" + prefix + ".cfg"),
|
||||
findDataFile("dnn/" + prefix + ".weights", false));
|
||||
netSync.setPreferableBackend(backendId);
|
||||
netSync.setPreferableTarget(targetId);
|
||||
|
||||
// Run synchronously.
|
||||
std::vector<Mat> refs(numInputs);
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
netSync.setInput(inputs[i]);
|
||||
refs[i] = netSync.forward().clone();
|
||||
}
|
||||
|
||||
Net netAsync = readNet(findDataFile("dnn/" + prefix + ".cfg"),
|
||||
findDataFile("dnn/" + prefix + ".weights", false));
|
||||
netAsync.setPreferableBackend(backendId);
|
||||
netAsync.setPreferableTarget(targetId);
|
||||
|
||||
double l1 = 0.0;
|
||||
double lInf = 0.0;
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
if (targetId == DNN_TARGET_MYRIAD && prefix == "yolo-voc")
|
||||
{
|
||||
l1 = 0.02;
|
||||
lInf = 0.15;
|
||||
}
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16 && prefix == "yolo-voc")
|
||||
{
|
||||
l1 = 0.02;
|
||||
lInf = 0.1;
|
||||
}
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16 && prefix == "yolov3")
|
||||
{
|
||||
l1 = 0.001;
|
||||
lInf = 0.007;
|
||||
}
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16 && prefix == "yolov4")
|
||||
{
|
||||
l1 = 0.001;
|
||||
lInf = 0.005;
|
||||
}
|
||||
if (INF_ENGINE_VER_MAJOR_EQ(2021040000) && targetId == DNN_TARGET_OPENCL_FP16 && prefix == "yolov4-tiny-2020-12") // FIXIT: 4.x only, 3.4 branch works well
|
||||
{
|
||||
l1 = 0.001;
|
||||
lInf = 0.005;
|
||||
}
|
||||
if (INF_ENGINE_VER_MAJOR_EQ(2022010000) && targetId == DNN_TARGET_OPENCL_FP16 && prefix == "yolov4-tiny-2020-12") // FIXIT: 4.x only, 3.4 branch works well
|
||||
{
|
||||
l1 = 0.001;
|
||||
lInf = 0.005;
|
||||
}
|
||||
if (targetId == DNN_TARGET_MYRIAD && prefix == "yolov4")
|
||||
{
|
||||
l1 = 0.005;
|
||||
lInf = 1.6f; // |ref| = 0.95431125164031982
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Run asynchronously. To make test more robust, process inputs in the reversed order.
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
netAsync.setInput(inputs[i]);
|
||||
|
||||
AsyncArray out = netAsync.forwardAsync();
|
||||
ASSERT_TRUE(out.valid());
|
||||
Mat result;
|
||||
EXPECT_TRUE(out.get(result, async_timeout));
|
||||
normAssert(refs[i], result, format("Index: %d", i).c_str(), l1, lInf);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine(
|
||||
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4", "yolov4-tiny-2020-12"),
|
||||
dnnBackendsAndTargets()
|
||||
));
|
||||
|
||||
#endif
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv3)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 6;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 16, 0.998836f, 0.160024f, 0.389964f, 0.417885f, 0.943716f,
|
||||
0, 1, 0.987908f, 0.150913f, 0.221933f, 0.742255f, 0.746261f,
|
||||
0, 7, 0.952983f, 0.614621f, 0.150257f, 0.901368f, 0.289251f,
|
||||
|
||||
1, 2, 0.997412f, 0.647584f, 0.459939f, 0.821037f, 0.663947f,
|
||||
1, 2, 0.989633f, 0.450719f, 0.463353f, 0.496306f, 0.522258f,
|
||||
1, 0, 0.980053f, 0.195856f, 0.378454f, 0.258626f, 0.629257f,
|
||||
1, 9, 0.785341f, 0.665503f, 0.373543f, 0.688893f, 0.439244f,
|
||||
1, 9, 0.733275f, 0.376029f, 0.315694f, 0.401776f, 0.395165f,
|
||||
1, 9, 0.384815f, 0.659824f, 0.372389f, 0.673927f, 0.429412f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2022010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
scoreDiff = 0.009;
|
||||
else
|
||||
#endif
|
||||
scoreDiff = 0.006;
|
||||
iouDiff = 0.042;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.03;
|
||||
}
|
||||
std::string config_file = "yolov3.cfg";
|
||||
std::string weights_file = "yolov3.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.2;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4)
|
||||
TEST_P(Test_YOLO_nets, YOLOv4)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_LONG,
|
||||
@@ -726,32 +333,20 @@ TEST_P(Test_Darknet_nets, YOLOv4)
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2022010000)
|
||||
if (target == DNN_TARGET_MYRIAD) // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 7;
|
||||
const int N1 = 6;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 16, 0.992194f, 0.172375f, 0.402458f, 0.403918f, 0.932801f,
|
||||
0, 1, 0.988326f, 0.166708f, 0.228236f, 0.737208f, 0.735803f,
|
||||
0, 7, 0.94639f, 0.602523f, 0.130399f, 0.901623f, 0.298452f,
|
||||
0, 16, 0.968371f, 0.167918f, 0.394843f, 0.40767f, 0.942042f,
|
||||
0, 1, 0.963549f, 0.146538f, 0.227724f, 0.745242f, 0.736494f,
|
||||
0, 7, 0.951405f, 0.606025f, 0.133886f, 0.895092f, 0.294835f,
|
||||
|
||||
1, 2, 0.99761f, 0.646556f, 0.45985f, 0.816041f, 0.659067f,
|
||||
1, 0, 0.988913f, 0.201726f, 0.360282f, 0.266181f, 0.631728f,
|
||||
1, 2, 0.98233f, 0.452007f, 0.462217f, 0.495612f, 0.521687f,
|
||||
1, 9, 0.919195f, 0.374642f, 0.316524f, 0.398126f, 0.393714f,
|
||||
1, 9, 0.856303f, 0.666842f, 0.372215f, 0.685539f, 0.44141f,
|
||||
1, 9, 0.313516f, 0.656791f, 0.374734f, 0.671959f, 0.438371f,
|
||||
1, 9, 0.256625f, 0.940232f, 0.326931f, 0.967586f, 0.374002f,
|
||||
1, 2, 0.99849f, 0.651516f, 0.456526f, 0.812706f, 0.66287f,
|
||||
1, 0, 0.996791f, 0.200903f, 0.362404f, 0.264643f, 0.627633f,
|
||||
1, 2, 0.987972f, 0.450125f, 0.464126f, 0.495712f, 0.519708f,
|
||||
1, 9, 0.85872f, 0.375374f, 0.314192f, 0.399161f, 0.39453f,
|
||||
1, 9, 0.841318f, 0.667602f, 0.377284f, 0.686024f, 0.440855f,
|
||||
1, 9, 0.502608f, 0.656728f, 0.378153f, 0.668251f, 0.432035f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
@@ -763,106 +358,65 @@ TEST_P(Test_Darknet_nets, YOLOv4)
|
||||
iouDiff = 0.03;
|
||||
}
|
||||
|
||||
std::string config_file = "yolov4.cfg";
|
||||
std::string weights_file = "yolov4.weights";
|
||||
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy (batch 1): no detections
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy (batch 1)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2022010000)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.2;
|
||||
}
|
||||
#endif
|
||||
std::string model_file = "yolov4.onnx";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
// Test not equal width and height applying zero padding
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), 0.006, 0.008, 0.24, 0.4, false, /*zeroPadW*/ 32);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.3, 0.4, false, 0, Size(608, 608));
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy (batch 2)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
scoreDiff = 0.008f;
|
||||
iouDiff = 0.05f;
|
||||
testYOLOModel(model_file, ref, scoreDiff, iouDiff, 0.3, 0.4, false, 0, Size(608, 608));
|
||||
}
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy (batch 2)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
iouDiff = 0.45f;
|
||||
}
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2022010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
#endif
|
||||
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4_tiny)
|
||||
TEST_P(Test_YOLO_nets, YOLOv3)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 0;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 7, 0.606292f, 0.612037f, 0.149921f, 0.910763f, 0.300503f,
|
||||
0, 16, 0.55195f, 0.17069f, 0.356024f, 0.471459f, 0.877178f,
|
||||
0, 1, 0.433444f, 0.199235f, 0.301175f, 0.753253f, 0.744156f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
scoreDiff = 0.006;
|
||||
iouDiff = 0.042;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.03;
|
||||
}
|
||||
std::string model_file = "yolov3.onnx";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_YOLO_nets, YOLOv4_tiny)
|
||||
{
|
||||
applyTestTag(
|
||||
target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2021010000) // nGraph compilation failure
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
const double confThreshold = 0.5;
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
@@ -883,41 +437,20 @@ TEST_P(Test_Darknet_nets, YOLOv4_tiny)
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
iouDiff = 0.02;
|
||||
|
||||
std::string config_file = "yolov4-tiny-2020-12.cfg";
|
||||
std::string weights_file = "yolov4-tiny-2020-12.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // bad accuracy
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
#endif
|
||||
std::string model_file = "yolov4-tiny.onnx";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold, 0.4, false);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold, 0.4, false, 0, Size(416, 416));
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold, 0.4, false);
|
||||
testYOLOModel(model_file, ref, scoreDiff, iouDiff, confThreshold, 0.4, false, 0, Size(416, 416));
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // bad accuracy
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4x_mish)
|
||||
TEST_P(Test_YOLO_nets, YOLOv4x_mish)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
@@ -925,37 +458,19 @@ TEST_P(Test_Darknet_nets, YOLOv4x_mish)
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// IE exception: Ngraph operation Transpose with name permute_168 has dynamic output shape on 0 port, but CPU plug-in supports only static shape
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 5;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 16, 0.925536f, 0.17188f, 0.386832f, 0.406138f, 0.941696f,
|
||||
0, 1, 0.912028f, 0.162125f, 0.208863f, 0.741316f, 0.729332f,
|
||||
0, 7, 0.841018f, 0.608953f, 0.128653f, 0.900692f, 0.295657f,
|
||||
0, 1, 0.93241f, 0.161592f, 0.232638f, 0.738411f, 0.731285f,
|
||||
0, 16, 0.929881f, 0.171312f, 0.385948f, 0.405568f, 0.940067f,
|
||||
0, 7, 0.812158f, 0.60486f, 0.129621f, 0.895285f, 0.296402f,
|
||||
|
||||
1, 2, 0.925697f, 0.650438f, 0.458118f, 0.813927f, 0.661775f,
|
||||
1, 0, 0.882156f, 0.203644f, 0.365763f, 0.265473f, 0.632195f,
|
||||
1, 2, 0.848857f, 0.451044f, 0.462997f, 0.496629f, 0.522719f,
|
||||
1, 9, 0.736015f, 0.374503f, 0.316029f, 0.399358f, 0.392883f,
|
||||
1, 9, 0.727129f, 0.662469f, 0.373687f, 0.687877f, 0.441335f,
|
||||
1, 2, 0.929241f, 0.651517f, 0.457701f, 0.8147f, 0.660816f,
|
||||
1, 0, 0.918966f, 0.200175f, 0.35915f, 0.265996f, 0.631935f,
|
||||
1, 2, 0.881782f, 0.45082f, 0.461253f, 0.495884f, 0.522369f,
|
||||
1, 9, 0.746081f, 0.661127f, 0.372649f, 0.686827f, 0.441998f,
|
||||
1, 9, 0.730318f, 0.373671f, 0.314795f, 0.401108f, 0.397822f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
@@ -968,190 +483,19 @@ TEST_P(Test_Darknet_nets, YOLOv4x_mish)
|
||||
iouDiff = 0.042;
|
||||
}
|
||||
|
||||
std::string config_file = "yolov4x-mish.cfg";
|
||||
std::string weights_file = "yolov4x-mish.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.2;
|
||||
}
|
||||
#endif
|
||||
std::string model_file = "yolov4x-mish.onnx";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
#endif
|
||||
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, 0.4, false);
|
||||
testYOLOModel(model_file, ref, scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets());
|
||||
|
||||
TEST_P(Test_Darknet_layers, shortcut)
|
||||
{
|
||||
testDarknetLayer("shortcut");
|
||||
}
|
||||
TEST_P(Test_Darknet_layers, shortcut_leaky)
|
||||
{
|
||||
testDarknetLayer("shortcut_leaky");
|
||||
}
|
||||
TEST_P(Test_Darknet_layers, shortcut_unequal)
|
||||
{
|
||||
testDarknetLayer("shortcut_unequal");
|
||||
}
|
||||
TEST_P(Test_Darknet_layers, shortcut_unequal_2)
|
||||
{
|
||||
testDarknetLayer("shortcut_unequal_2");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, upsample)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
|
||||
#endif
|
||||
testDarknetLayer("upsample");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, mish)
|
||||
{
|
||||
testDarknetLayer("mish", true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, tanh)
|
||||
{
|
||||
testDarknetLayer("tanh");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, avgpool_softmax)
|
||||
{
|
||||
testDarknetLayer("avgpool_softmax");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, crop)
|
||||
{
|
||||
testDarknetLayer("crop");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, region)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && INF_ENGINE_VER_MAJOR_GE(2020020000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2022010000)
|
||||
// accuracy on CPU, OpenCL
|
||||
// Expected: (normL1) <= (l1), actual: 0.000358148 vs 1e-05
|
||||
// |ref| = 1.207319974899292
|
||||
// Expected: (normInf) <= (lInf), actual: 0.763223 vs 0.0001
|
||||
// |ref| = 1.207319974899292
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy on CPU, OpenCL
|
||||
// Expected: (normInf) <= (lInf), actual: 0.763223 vs 0.0001
|
||||
// |ref| = 1.207319974899292
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#endif
|
||||
|
||||
testDarknetLayer("region");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, reorg)
|
||||
{
|
||||
testDarknetLayer("reorg");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, route)
|
||||
{
|
||||
testDarknetLayer("route");
|
||||
testDarknetLayer("route_multi");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, maxpool)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
testDarknetLayer("maxpool");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, convolutional)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
default_l1 = 0.01f;
|
||||
}
|
||||
#endif
|
||||
testDarknetLayer("convolutional", true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, scale_channels)
|
||||
{
|
||||
bool testBatches = backend == DNN_BACKEND_CUDA;
|
||||
testDarknetLayer("scale_channels", false, testBatches);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, connected)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_CPU_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU_FP16);
|
||||
double l1 = 0.0;
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
{
|
||||
l1 = 3e-5;
|
||||
}
|
||||
testDarknetLayer("connected", true, true, l1);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, relu)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
testDarknetLayer("relu");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, sam)
|
||||
{
|
||||
testDarknetLayer("sam", true);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_layers, dnnBackendsAndTargets());
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_YOLO_nets, dnnBackendsAndTargets());
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -651,9 +651,9 @@ public:
|
||||
normAssert(ref, out, "", l1, lInf);
|
||||
}
|
||||
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const cv::Mat& ref, double scoreDiff, double iouDiff,
|
||||
float confThreshold = 0.24, float nmsThreshold = 0.4, bool perChannel = true)
|
||||
void testYOLOModel(const std::string& model,
|
||||
const cv::Mat& ref, double scoreDiff, double iouDiff,
|
||||
float confThreshold = 0.24, float nmsThreshold = 0.4, bool perChannel = true)
|
||||
{
|
||||
CV_Assert(ref.cols == 7);
|
||||
std::vector<std::vector<int> > refClassIds;
|
||||
@@ -692,7 +692,7 @@ public:
|
||||
|
||||
Mat inp = blobFromImages(samples, 1.0/255, Size(416, 416), Scalar(), true, false);
|
||||
|
||||
Net baseNet = readNetFromDarknet(findDataFile("dnn/" + cfg), findDataFile("dnn/" + weights, false));
|
||||
Net baseNet = readNet(findDataFile("dnn/" + model, false));
|
||||
Net qnet = baseNet.quantize(inp, CV_32F, CV_32F, perChannel);
|
||||
qnet.setPreferableBackend(backend);
|
||||
qnet.setPreferableTarget(target);
|
||||
@@ -1228,86 +1228,6 @@ TEST_P(Test_Int8_nets, RFCN)
|
||||
testFaster(net, ref, confThreshold, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
TEST_P(Test_Int8_nets, YoloVoc)
|
||||
{
|
||||
applyTestTag(
|
||||
#if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
#else
|
||||
CV_TEST_TAG_MEMORY_1GB,
|
||||
#endif
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
if (target == DNN_TARGET_OPENCL_FP16 && !ocl::Device::getDefault().isIntel())
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
if (target == DNN_TARGET_OPENCL && !ocl::Device::getDefault().isIntel())
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL);
|
||||
|
||||
Mat ref = (Mat_<float>(6, 7) << 0, 6, 0.750469f, 0.577374f, 0.127391f, 0.902949f, 0.300809f,
|
||||
0, 1, 0.780879f, 0.270762f, 0.264102f, 0.732475f, 0.745412f,
|
||||
0, 11, 0.901615f, 0.1386f, 0.338509f, 0.421337f, 0.938789f,
|
||||
1, 14, 0.623813f, 0.183179f, 0.381921f, 0.247726f, 0.625847f,
|
||||
1, 6, 0.667770f, 0.446555f, 0.453578f, 0.499986f, 0.519167f,
|
||||
1, 6, 0.844947f, 0.637058f, 0.460398f, 0.828508f, 0.66427f);
|
||||
|
||||
std::string config_file = "yolo-voc.cfg";
|
||||
std::string weights_file = "yolo-voc.weights";
|
||||
|
||||
double scoreDiff = 0.12, iouDiff = 0.3;
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Int8_nets, TinyYoloVoc)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_MEMORY_512MB,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
if (target == DNN_TARGET_OPENCL_FP16 && !ocl::Device::getDefault().isIntel())
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
if (target == DNN_TARGET_OPENCL && !ocl::Device::getDefault().isIntel())
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL);
|
||||
|
||||
Mat ref = (Mat_<float>(4, 7) << 0, 6, 0.761967f, 0.579042f, 0.159161f, 0.894482f, 0.31994f,
|
||||
0, 11, 0.780595f, 0.129696f, 0.386467f, 0.445275f, 0.920994f,
|
||||
1, 6, 0.651450f, 0.460526f, 0.458019f, 0.522527f, 0.5341f,
|
||||
1, 6, 0.928758f, 0.651024f, 0.463539f, 0.823784f, 0.654998f);
|
||||
|
||||
std::string config_file = "tiny-yolo-voc.cfg";
|
||||
std::string weights_file = "tiny-yolo-voc.weights";
|
||||
|
||||
double scoreDiff = 0.043, iouDiff = 0.12;
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff);
|
||||
{
|
||||
SCOPED_TRACE("Per-tensor quantize");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), 0.1, 0.2, 0.24, 0.6, false);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
|
||||
{
|
||||
SCOPED_TRACE("Per-tensor quantize");
|
||||
testDarknetModel(config_file, weights_file, ref, 0.1, 0.2, 0.24, 0.6, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Int8_nets, YOLOv3)
|
||||
{
|
||||
applyTestTag(
|
||||
@@ -1337,18 +1257,17 @@ TEST_P(Test_Int8_nets, YOLOv3)
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
std::string config_file = "yolov3.cfg";
|
||||
std::string weights_file = "yolov3.weights";
|
||||
std::string model_file = "yolov3.onnx";
|
||||
|
||||
double scoreDiff = 0.08, iouDiff = 0.21, confThreshold = 0.25;
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
|
||||
testYOLOModel(model_file, ref, scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,18 +1301,17 @@ TEST_P(Test_Int8_nets, YOLOv4)
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
std::string config_file = "yolov4.cfg";
|
||||
std::string weights_file = "yolov4.weights";
|
||||
std::string model_file = "yolov4.onnx";
|
||||
double scoreDiff = 0.15, iouDiff = 0.2;
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
testYOLOModel(model_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1424,18 +1342,17 @@ TEST_P(Test_Int8_nets, YOLOv4_tiny)
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
std::string config_file = "yolov4-tiny-2020-12.cfg";
|
||||
std::string weights_file = "yolov4-tiny-2020-12.weights";
|
||||
std::string model_file = "yolov4-tiny.onnx";
|
||||
double scoreDiff = 0.12;
|
||||
double iouDiff = target == DNN_TARGET_OPENCL_FP16 ? 0.2 : 0.118;
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
|
||||
|
||||
{
|
||||
SCOPED_TRACE("Per-tensor quantize");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, 0.224, 0.7, 0.4, false);
|
||||
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, 0.224, 0.7, 0.4, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1443,7 +1360,7 @@ TEST_P(Test_Int8_nets, YOLOv4_tiny)
|
||||
/* bad accuracy on second image
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
|
||||
testYOLOModel(model_file, ref, scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -247,9 +247,6 @@ TEST(readNet, Regression)
|
||||
Net net = readNet(findDataFile("dnn/squeezenet_v1.1.prototxt"),
|
||||
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
net = readNet(findDataFile("dnn/tiny-yolo-voc.cfg"),
|
||||
findDataFile("dnn/tiny-yolo-voc.weights", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
net = readNet(findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt"),
|
||||
findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
|
||||
@@ -289,129 +289,6 @@ TEST_P(Test_Model, Classify)
|
||||
}
|
||||
|
||||
|
||||
TEST_P(Test_Model, DetectRegion)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
// FIXIT DNN_BACKEND_INFERENCE_ENGINE is misused
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
|
||||
std::vector<int> refClassIds = {6, 1, 11};
|
||||
std::vector<float> refConfidences = {0.750469f, 0.780879f, 0.901615f};
|
||||
std::vector<Rect2d> refBoxes = {Rect2d(240, 53, 135, 72),
|
||||
Rect2d(112, 109, 192, 200),
|
||||
Rect2d(58, 141, 117, 249)};
|
||||
|
||||
std::string img_path = _tf("dog416.png");
|
||||
std::string weights_file = _tf("yolo-voc.weights", false);
|
||||
std::string config_file = _tf("yolo-voc.cfg");
|
||||
|
||||
double scale = 1.0 / 255.0;
|
||||
Size size{416, 416};
|
||||
bool swapRB = true;
|
||||
|
||||
double confThreshold = 0.24;
|
||||
double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.397 : 0.4;
|
||||
double scoreDiff = 8e-5, iouDiff = 1e-5;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
scoreDiff = 1e-2;
|
||||
iouDiff = 1.6e-2;
|
||||
}
|
||||
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences,
|
||||
refBoxes, scoreDiff, iouDiff, confThreshold, nmsThreshold, size,
|
||||
Scalar(), scale, swapRB);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, DetectRegionWithNmsAcrossClasses)
|
||||
{
|
||||
applyTestTag(
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
|
||||
std::vector<int> refClassIds = { 6, 11 };
|
||||
std::vector<float> refConfidences = { 0.750469f, 0.901615f };
|
||||
std::vector<Rect2d> refBoxes = { Rect2d(240, 53, 135, 72),
|
||||
Rect2d(58, 141, 117, 249) };
|
||||
|
||||
std::string img_path = _tf("dog416.png");
|
||||
std::string weights_file = _tf("yolo-voc.weights", false);
|
||||
std::string config_file = _tf("yolo-voc.cfg");
|
||||
|
||||
double scale = 1.0 / 255.0;
|
||||
Size size{ 416, 416 };
|
||||
bool swapRB = true;
|
||||
bool crop = false;
|
||||
bool nmsAcrossClasses = true;
|
||||
|
||||
double confThreshold = 0.24;
|
||||
double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.15: 0.15;
|
||||
double scoreDiff = 8e-5, iouDiff = 1e-5;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
scoreDiff = 1e-2;
|
||||
iouDiff = 1.6e-2;
|
||||
}
|
||||
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences,
|
||||
refBoxes, scoreDiff, iouDiff, confThreshold, nmsThreshold, size,
|
||||
Scalar(), scale, swapRB, crop,
|
||||
nmsAcrossClasses);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, DetectionOutput)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
|
||||
@@ -172,7 +172,7 @@ video = {
|
||||
}
|
||||
|
||||
dnn = {'dnn_Net': ['setInput', 'forward', 'setPreferableBackend','getUnconnectedOutLayersNames'],
|
||||
'': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromDarknet',
|
||||
'': ['readNetFromCaffe', 'readNetFromTensorflow',
|
||||
'readNetFromONNX', 'readNetFromTFLite', 'readNet', 'blobFromImage']}
|
||||
|
||||
features = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptorSize', 'descriptorType', 'defaultNorm', 'empty', 'getDefaultName'],
|
||||
|
||||
Reference in New Issue
Block a user