Merge pull request #24294 from alexlyulkov:al/remove-torch7-from-dnn

Remove torch (old torch7) from dnn in 5.x #24294

Merge with https://github.com/opencv/opencv_extra/pull/1097

Completely removed torch (old torch7) from dnn:
- removed modules/dnn/src/torch directory that contained torch7 model parser
- removed readNetFromTorch() and readTorchBlob() public functions
- removed torch7 references from comments and help texts
- replaced links to t7 models by links to similar onnx models in js_style_transfer turtorial (similar to https://github.com/opencv/opencv/pull/24245/files)
pull/24486/head
alexlyulkov 1 year ago committed by GitHub
parent 97620c053f
commit b71be65f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 74
      doc/js_tutorials/js_assets/js_style_transfer_model_info.json
  2. 2
      modules/dnn/CMakeLists.txt
  3. 4
      modules/dnn/include/opencv2/dnn/all_layers.hpp
  4. 38
      modules/dnn/include/opencv2/dnn/dnn.hpp
  5. 23
      modules/dnn/perf/perf_net.cpp
  6. 6
      modules/dnn/src/dnn_read.cpp
  7. 36
      modules/dnn/src/torch/COPYRIGHT.txt
  8. 530
      modules/dnn/src/torch/THDiskFile.cpp
  9. 22
      modules/dnn/src/torch/THDiskFile.h
  10. 120
      modules/dnn/src/torch/THFile.cpp
  11. 53
      modules/dnn/src/torch/THFile.h
  12. 37
      modules/dnn/src/torch/THFilePrivate.h
  13. 2
      modules/dnn/src/torch/THGeneral.cpp
  14. 22
      modules/dnn/src/torch/THGeneral.h
  15. 1267
      modules/dnn/src/torch/torch_importer.cpp
  16. 140
      modules/dnn/test/cityscapes_semsegm_test_enet.py
  17. 49
      modules/dnn/test/test_backends.cpp
  18. 2
      modules/dnn/test/test_misc.cpp
  19. 664
      modules/dnn/test/test_torch_importer.cpp
  20. 2
      platforms/js/opencv_js.config.py
  21. 2
      samples/dnn/classification.py
  22. 2
      samples/dnn/common.hpp
  23. 2
      samples/dnn/common.py
  24. 15
      samples/dnn/models.yml
  25. 2
      samples/dnn/object_detection.py
  26. 2
      samples/dnn/segmentation.py

@ -1,76 +1,44 @@
{ {
"torch": [ "onnx": [
{ {
"model": "candy.t7", "model": "mosaic-9.onnx",
"inputSize": "224, 224", "inputSize": "224, 224",
"mean": "104, 117, 123", "mean": "0, 0, 0",
"std": "1", "std": "1",
"swapRB": "false", "swapRB": "true",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/candy.t7" "modelUrl": "https://media.githubusercontent.com/media/onnx/models/main/vision/style_transfer/fast_neural_style/model/mosaic-9.onnx"
}, },
{ {
"model": "composition_vii.t7", "model": "candy-9.onnx",
"inputSize": "224, 224", "inputSize": "224, 224",
"mean": "104, 117, 123", "mean": "0, 0, 0",
"std": "1", "std": "1",
"swapRB": "false", "swapRB": "true",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/composition_vii.t7" "modelUrl": "https://media.githubusercontent.com/media/onnx/models/main/vision/style_transfer/fast_neural_style/model/candy-9.onnx"
}, },
{ {
"model": "feathers.t7", "model": "rain-princess-9.onnx",
"inputSize": "224, 224", "inputSize": "224, 224",
"mean": "104, 117, 123", "mean": "0, 0, 0",
"std": "1", "std": "1",
"swapRB": "false", "swapRB": "true",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/feathers.t7" "modelUrl": "https://media.githubusercontent.com/media/onnx/models/main/vision/style_transfer/fast_neural_style/model/rain-princess-9.onnx"
}, },
{ {
"model": "la_muse.t7", "model": "udnie-9.onnx",
"inputSize": "224, 224", "inputSize": "224, 224",
"mean": "104, 117, 123", "mean": "0, 0, 0",
"std": "1", "std": "1",
"swapRB": "false", "swapRB": "true",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/la_muse.t7" "modelUrl": "https://media.githubusercontent.com/media/onnx/models/main/vision/style_transfer/fast_neural_style/model/udnie-9.onnx"
}, },
{ {
"model": "mosaic.t7", "model": "pointilism-9.onnx",
"inputSize": "224, 224", "inputSize": "224, 224",
"mean": "104, 117, 123", "mean": "0, 0, 0",
"std": "1", "std": "1",
"swapRB": "false", "swapRB": "true",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/mosaic.t7" "modelUrl": "https://media.githubusercontent.com/media/onnx/models/main/vision/style_transfer/fast_neural_style/model/pointilism-9.onnx"
},
{
"model": "starry_night.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/starry_night.t7"
},
{
"model": "the_scream.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/the_scream.t7"
},
{
"model": "the_wave.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/the_wave.t7"
},
{
"model": "udnie.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/udnie.t7"
} }
] ]
} }

@ -209,7 +209,7 @@ set(dnn_plugin_srcs ${dnn_srcs} ${dnn_int_hdrs})
ocv_list_filterout_ex(dnn_plugin_srcs ocv_list_filterout_ex(dnn_plugin_srcs
"/src/dnn.cpp$|/src/dnn_utils.cpp$|/src/dnn_utils.cpp$|/src/dnn_read.cpp$|/src/registry.cpp$|/src/backend.cpp$" "/src/dnn.cpp$|/src/dnn_utils.cpp$|/src/dnn_utils.cpp$|/src/dnn_read.cpp$|/src/registry.cpp$|/src/backend.cpp$"
# importers # importers
"/src/(caffe|darknet|onnx|tensorflow|torch)/" "/src/(caffe|darknet|onnx|tensorflow)/"
# executors # executors
"/src/(cuda|cuda4dnn|ocl4dnn|vkcom|webnn)/" "/src/(cuda|cuda4dnn|ocl4dnn|vkcom|webnn)/"
) )

@ -55,9 +55,9 @@ CV__DNN_INLINE_NS_BEGIN
Classes listed here, in fact, provides C++ API for creating instances of built-in layers. Classes listed here, in fact, provides C++ API for creating instances of built-in layers.
In addition to this way of layers instantiation, there is a more common factory API (see @ref dnnLayerFactory), it allows to create layers dynamically (by name) and register new ones. In addition to this way of layers instantiation, there is a more common factory API (see @ref dnnLayerFactory), it allows to create layers dynamically (by name) and register new ones.
You can use both API, but factory API is less convenient for native C++ programming and basically designed for use inside importers (see @ref readNetFromCaffe(), @ref readNetFromTorch(), @ref readNetFromTensorflow()). You can use both API, but factory API is less convenient for native C++ programming and basically designed for use inside importers (see @ref readNetFromCaffe(), @ref readNetFromTensorflow()).
Built-in layers partially reproduce functionality of corresponding Caffe and Torch7 layers. Built-in layers partially reproduce functionality of corresponding ONNX, TensorFlow and Caffe layers.
In particular, the following layers and Caffe importer were tested to reproduce <a href="http://caffe.berkeleyvision.org/tutorial/layers.html">Caffe</a> functionality: In particular, the following layers and Caffe importer were tested to reproduce <a href="http://caffe.berkeleyvision.org/tutorial/layers.html">Caffe</a> functionality:
- Convolution - Convolution
- Deconvolution - Deconvolution

@ -934,41 +934,12 @@ CV__DNN_INLINE_NS_BEGIN
*/ */
CV_EXPORTS Net readNetFromTFLite(const char *bufferModel, size_t lenModel); CV_EXPORTS Net readNetFromTFLite(const char *bufferModel, size_t lenModel);
/**
* @brief Reads a network model stored in <a href="http://torch.ch">Torch7</a> framework's format.
* @param model path to the file, dumped from Torch by using torch.save() function.
* @param isBinary specifies whether the network was serialized in ascii mode or binary.
* @param evaluate specifies testing phase of network. If true, it's similar to evaluate() method in Torch.
* @returns Net object.
*
* @note Ascii mode of Torch serializer is more preferable, because binary mode extensively use `long` type of C language,
* which has various bit-length on different systems.
*
* The loading file must contain serialized <a href="https://github.com/torch/nn/blob/master/doc/module.md">nn.Module</a> object
* with importing network. Try to eliminate a custom objects from serialazing data to avoid importing errors.
*
* List of supported layers (i.e. object instances derived from Torch nn.Module class):
* - nn.Sequential
* - nn.Parallel
* - nn.Concat
* - nn.Linear
* - nn.SpatialConvolution
* - nn.SpatialMaxPooling, nn.SpatialAveragePooling
* - nn.ReLU, nn.TanH, nn.Sigmoid
* - nn.Reshape
* - nn.SoftMax, nn.LogSoftMax
*
* Also some equivalents of these classes from cunn, cudnn, and fbcunn may be successfully imported.
*/
CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true, bool evaluate = true);
/** /**
* @brief Read deep learning network represented in one of the supported formats. * @brief Read deep learning network represented in one of the supported formats.
* @param[in] model Binary file contains trained weights. The following file * @param[in] model Binary file contains trained weights. The following file
* extensions are expected for models from different frameworks: * extensions are expected for models from different frameworks:
* * `*.caffemodel` (Caffe, http://caffe.berkeleyvision.org/) * * `*.caffemodel` (Caffe, http://caffe.berkeleyvision.org/)
* * `*.pb` (TensorFlow, https://www.tensorflow.org/) * * `*.pb` (TensorFlow, https://www.tensorflow.org/)
* * `*.t7` | `*.net` (Torch, http://torch.ch/)
* * `*.weights` (Darknet, https://pjreddie.com/darknet/) * * `*.weights` (Darknet, https://pjreddie.com/darknet/)
* * `*.bin` (DLDT, https://software.intel.com/openvino-toolkit) * * `*.bin` (DLDT, https://software.intel.com/openvino-toolkit)
* * `*.onnx` (ONNX, https://onnx.ai/) * * `*.onnx` (ONNX, https://onnx.ai/)
@ -982,8 +953,8 @@ CV__DNN_INLINE_NS_BEGIN
* @returns Net object. * @returns Net object.
* *
* This function automatically detects an origin framework of trained model * This function automatically detects an origin framework of trained model
* and calls an appropriate function such @ref readNetFromCaffe, @ref readNetFromTensorflow, * and calls an appropriate function such @ref readNetFromCaffe, @ref readNetFromTensorflow
* @ref readNetFromTorch or @ref readNetFromDarknet. An order of @p model and @p config * or @ref readNetFromDarknet. An order of @p model and @p config
* arguments does not matter. * arguments does not matter.
*/ */
CV_EXPORTS_W Net readNet(const String& model, const String& config = "", const String& framework = ""); CV_EXPORTS_W Net readNet(const String& model, const String& config = "", const String& framework = "");
@ -1000,11 +971,6 @@ CV__DNN_INLINE_NS_BEGIN
CV_EXPORTS_W Net readNet(const String& framework, const std::vector<uchar>& bufferModel, CV_EXPORTS_W Net readNet(const String& framework, const std::vector<uchar>& bufferModel,
const std::vector<uchar>& bufferConfig = std::vector<uchar>()); const std::vector<uchar>& bufferConfig = std::vector<uchar>());
/** @brief Loads blob which was serialized as torch.Tensor object of Torch7 framework.
* @warning This function has the same limitations as readNetFromTorch().
*/
CV_EXPORTS_W Mat readTorchBlob(const String &filename, bool isBinary = true);
/** @brief Load a network from Intel's Model Optimizer intermediate representation. /** @brief Load a network from Intel's Model Optimizer intermediate representation.
* @param[in] xml XML configuration file with network's topology. * @param[in] xml XML configuration file with network's topology.
* @param[in] bin Binary file with trained weights. * @param[in] bin Binary file with trained weights.

@ -109,32 +109,11 @@ PERF_TEST_P_(DNNTestNetwork, Inception_5h)
processNet("dnn/tensorflow_inception_graph.pb", "", cv::Size(224, 224), "softmax2"); processNet("dnn/tensorflow_inception_graph.pb", "", cv::Size(224, 224), "softmax2");
} }
PERF_TEST_P_(DNNTestNetwork, ENet)
{
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU) ||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2021010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
throw SkipTestException("");
#endif
processNet("dnn/Enet-model-best.net", "", cv::Size(512, 256));
}
PERF_TEST_P_(DNNTestNetwork, SSD) PERF_TEST_P_(DNNTestNetwork, SSD)
{ {
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", "dnn/ssd_vgg16.prototxt", cv::Size(300, 300)); processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", "dnn/ssd_vgg16.prototxt", cv::Size(300, 300));
} }
PERF_TEST_P_(DNNTestNetwork, OpenFace)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_HDDL))
throw SkipTestException("");
#endif
processNet("dnn/openface_nn4.small2.v1.t7", "", cv::Size(96, 96));
}
PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_Caffe) PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_Caffe)
{ {
processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt", cv::Size(300, 300)); processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt", cv::Size(300, 300));
@ -248,7 +227,7 @@ PERF_TEST_P_(DNNTestNetwork, EAST_text_detection)
PERF_TEST_P_(DNNTestNetwork, FastNeuralStyle_eccv16) PERF_TEST_P_(DNNTestNetwork, FastNeuralStyle_eccv16)
{ {
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", cv::Size(320, 240)); processNet("", "dnn/mosaic-9.onnx", cv::Size(224, 224));
} }
PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN) PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN)

@ -33,10 +33,6 @@ Net readNet(const String& _model, const String& _config, const String& _framewor
{ {
return readNetFromTFLite(model); return readNetFromTFLite(model);
} }
if (framework == "torch" || modelExt == "t7" || modelExt == "net" || configExt == "t7" || configExt == "net")
{
return readNetFromTorch(model.empty() ? config : model);
}
if (framework == "darknet" || modelExt == "weights" || configExt == "weights" || modelExt == "cfg" || configExt == "cfg") if (framework == "darknet" || modelExt == "weights" || configExt == "weights" || modelExt == "cfg" || configExt == "cfg")
{ {
if (modelExt == "cfg" || configExt == "weights") if (modelExt == "cfg" || configExt == "weights")
@ -66,8 +62,6 @@ Net readNet(const String& _framework, const std::vector<uchar>& bufferModel,
return readNetFromTensorflow(bufferModel, bufferConfig); return readNetFromTensorflow(bufferModel, bufferConfig);
else if (framework == "darknet") else if (framework == "darknet")
return readNetFromDarknet(bufferConfig, bufferModel); return readNetFromDarknet(bufferConfig, bufferModel);
else if (framework == "torch")
CV_Error(Error::StsNotImplemented, "Reading Torch models from buffers");
else if (framework == "dldt") else if (framework == "dldt")
return readNetFromModelOptimizer(bufferConfig, bufferModel); return readNetFromModelOptimizer(bufferConfig, bufferModel);
else if (framework == "tflite") else if (framework == "tflite")

@ -1,36 +0,0 @@
Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert)
Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu)
Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu)
Copyright (c) 2011-2013 NYU (Clement Farabet)
Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston)
Copyright (c) 2006 Idiap Research Institute (Samy Bengio)
Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. Neither the names of Deepmind Technologies, NYU, NEC Laboratories America
and IDIAP Research Institute nor the names of its 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 THE COPYRIGHT OWNER 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.

@ -1,530 +0,0 @@
#include "../precomp.hpp"
#include "THGeneral.h"
#include "THDiskFile.h"
#include "THFilePrivate.h"
namespace TH
{
typedef struct THDiskFile__
{
THFile file;
FILE *handle;
int isNativeEncoding;
int longSize;
} THDiskFile;
static int THDiskFile_isOpened(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)self;
return (dfself->handle != NULL);
}
/* workaround mac osx lion ***insane*** fread bug */
#ifdef __APPLE__
static size_t fread__(void *ptr, size_t size, size_t nitems, FILE *stream)
{
size_t nread = 0;
while(!feof(stream) && !ferror(stream) && (nread < nitems))
nread += fread((char*)ptr+nread*size, size, std::min<size_t>(2147483648UL/size, nitems-nread), stream);
return nread;
}
#else
#define fread__ fread
#endif
#define READ_WRITE_METHODS(TYPE, TYPEC, ASCII_READ_ELEM, ASCII_WRITE_ELEM) \
static long THDiskFile_read##TYPEC(THFile *self, TYPE *data, long n) \
{ \
THDiskFile *dfself = (THDiskFile*)(self); \
long nread = 0L; \
\
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file"); \
THArgCheck(dfself->file.isReadable, 1, "attempt to read in a write-only file"); \
\
if(dfself->file.isBinary) \
{ \
nread = fread__(data, sizeof(TYPE), n, dfself->handle); \
if(!dfself->isNativeEncoding && (sizeof(TYPE) > 1) && (nread > 0)) \
THDiskFile_reverseMemory(data, data, sizeof(TYPE), nread); \
} \
else \
{ \
long i; \
for(i = 0; i < n; i++) \
{ \
ASCII_READ_ELEM; /* increment here result and break if wrong */ \
} \
if(dfself->file.isAutoSpacing && (n > 0)) \
{ \
int c = fgetc(dfself->handle); \
if( (c != '\n') && (c != EOF) ) \
ungetc(c, dfself->handle); \
} \
} \
\
if(nread != n) \
{ \
dfself->file.hasError = 1; /* shouldn't we put hasError to 0 all the time ? */ \
if(!dfself->file.isQuiet) \
THError("read error: read %ld blocks instead of %ld", nread, n);\
} \
\
return nread; \
}
static int THDiskFile_mode(const char *mode, int *isReadable, int *isWritable)
{
*isReadable = 0;
*isWritable = 0;
if(strlen(mode) == 1)
{
if(*mode == 'r')
{
*isReadable = 1;
return 1;
}
else if(*mode == 'w')
{
*isWritable = 1;
return 1;
}
}
else if(strlen(mode) == 2)
{
if(mode[0] == 'r' && mode[1] == 'w')
{
*isReadable = 1;
*isWritable = 1;
return 1;
}
}
return 0;
}
static void THDiskFile_seek(THFile *self, long position)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
#if defined(_WIN64)
if(_fseeki64(dfself->handle, (__int64)position, SEEK_SET) < 0)
#elif defined(_WIN32)
if(fseek(dfself->handle, (long)position, SEEK_SET) < 0)
#else
if(fseeko(dfself->handle, (off_t)position, SEEK_SET) < 0)
#endif
{
dfself->file.hasError = 1;
if(!dfself->file.isQuiet)
THError("unable to seek at position %ld", position);
}
}
static void THDiskFile_seekEnd(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
#if defined(_WIN64)
if(_fseeki64(dfself->handle, 0L, SEEK_END) < 0)
#elif defined(_WIN32)
if(fseek(dfself->handle, 0L, SEEK_END) < 0)
#else
if(fseeko(dfself->handle, 0L, SEEK_END) < 0)
#endif
{
dfself->file.hasError = 1;
if(!dfself->file.isQuiet)
THError("unable to seek at end of file");
}
}
static long THDiskFile_position(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
#if defined(_WIN64)
__int64 offset = _ftelli64(dfself->handle);
#elif defined(_WIN32)
long offset = ftell(dfself->handle);
#else
off_t offset = ftello(dfself->handle);
#endif
if (offset > -1)
return (long)offset;
else if(!dfself->file.isQuiet)
THError("unable to obtain disk file offset (maybe a long overflow occurred)");
return 0;
}
static void THDiskFile_close(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
fclose(dfself->handle);
dfself->handle = NULL;
}
/* Little and Big Endian */
static void THDiskFile_reverseMemory(void *dst, const void *src, long blockSize, long numBlocks)
{
if(blockSize != 1)
{
long halfBlockSize = blockSize/2;
char *charSrc = (char*)src;
char *charDst = (char*)dst;
long b, i;
for(b = 0; b < numBlocks; b++)
{
for(i = 0; i < halfBlockSize; i++)
{
char z = charSrc[i];
charDst[i] = charSrc[blockSize-1-i];
charDst[blockSize-1-i] = z;
}
charSrc += blockSize;
charDst += blockSize;
}
}
}
int THDiskFile_isLittleEndianCPU(void)
{
int x = 7;
char *ptr = (char *)&x;
if(ptr[0] == 0)
return 0;
else
return 1;
}
int THDiskFile_isBigEndianCPU(void)
{
return(!THDiskFile_isLittleEndianCPU());
}
void THDiskFile_nativeEndianEncoding(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
dfself->isNativeEncoding = 1;
}
void THDiskFile_littleEndianEncoding(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
dfself->isNativeEncoding = THDiskFile_isLittleEndianCPU();
}
void THDiskFile_bigEndianEncoding(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
dfself->isNativeEncoding = !THDiskFile_isLittleEndianCPU();
}
/* End of Little and Big Endian Stuff */
void THDiskFile_longSize(THFile *self, int size)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
THArgCheck(size == 0 || size == 4 || size == 8, 1, "Invalid long size specified");
dfself->longSize = size;
}
void THDiskFile_noBuffer(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
if (setvbuf(dfself->handle, NULL, _IONBF, 0)) {
THError("error: cannot disable buffer");
}
}
static void THDiskFile_free(THFile *self)
{
THDiskFile *dfself = (THDiskFile*)(self);
if(dfself->handle)
fclose(dfself->handle);
THFree(dfself);
}
/* Note that we do a trick */
READ_WRITE_METHODS(unsigned char, Byte,
nread = fread(data, 1, n, dfself->handle); break,
nwrite = fwrite(data, 1, n, dfself->handle); break)
READ_WRITE_METHODS(char, Char,
nread = fread(data, 1, n, dfself->handle); break,
nwrite = fwrite(data, 1, n, dfself->handle); break)
READ_WRITE_METHODS(short, Short,
int ret = fscanf(dfself->handle, "%hd", &data[i]); if(ret <= 0) break; else nread++,
int ret = fprintf(dfself->handle, "%hd", data[i]); if(ret <= 0) break; else nwrite++)
READ_WRITE_METHODS(int, Int,
int ret = fscanf(dfself->handle, "%d\n\r", &data[i]); if(ret <= 0) break; else nread++,
int ret = fprintf(dfself->handle, "%d", data[i]); if(ret <= 0) break; else nwrite++)
/*READ_WRITE_METHODS(long, Long,
int ret = fscanf(dfself->handle, "%ld", &data[i]); if(ret <= 0) break; else nread++,
int ret = fprintf(dfself->handle, "%ld", data[i]); if(ret <= 0) break; else nwrite++)*/
READ_WRITE_METHODS(float, Float,
int ret = fscanf(dfself->handle, "%g", &data[i]); if(ret <= 0) break; else nread++,
int ret = fprintf(dfself->handle, "%.9g", data[i]); if(ret <= 0) break; else nwrite++)
READ_WRITE_METHODS(double, Double,
int ret = fscanf(dfself->handle, "%lg", &data[i]); if(ret <= 0) break; else nread++,
int ret = fprintf(dfself->handle, "%.17g", data[i]); if(ret <= 0) break; else nwrite++)
/* For Long we need to rewrite everything, because of the special management of longSize */
static long THDiskFile_readLong(THFile *self, int64 *data, long n)
{
THDiskFile *dfself = (THDiskFile*)(self);
long nread = 0L;
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
THArgCheck(dfself->file.isReadable, 1, "attempt to read in a write-only file");
if(dfself->file.isBinary)
{
if(dfself->longSize == 0 || dfself->longSize == sizeof(int64))
{
nread = fread__(data, sizeof(int64), n, dfself->handle);
if(!dfself->isNativeEncoding && (sizeof(int64) > 1) && (nread > 0))
THDiskFile_reverseMemory(data, data, sizeof(int64), nread);
} else if(dfself->longSize == 4)
{
nread = fread__(data, 4, n, dfself->handle);
if(!dfself->isNativeEncoding && (nread > 0))
THDiskFile_reverseMemory(data, data, 4, nread);
long i;
for(i = nread; i > 0; i--)
data[i-1] = ((int *)data)[i-1];
}
else /* if(dfself->longSize == 8) */
{
int big_endian = !THDiskFile_isLittleEndianCPU();
int32_t *buffer = (int32_t*)THAlloc(8*n);
if (!buffer)
THError("can not allocate buffer");
nread = fread__(buffer, 8, n, dfself->handle);
long i;
for(i = nread; i > 0; i--)
data[i-1] = buffer[2*(i-1) + big_endian];
THFree(buffer);
if(!dfself->isNativeEncoding && (nread > 0))
THDiskFile_reverseMemory(data, data, 4, nread);
}
}
else
{
long i;
for(i = 0; i < n; i++)
{
long d;
int ret = fscanf(dfself->handle, "%ld", &d); if(ret <= 0) break; else nread++;
data[i] = d;
}
if(dfself->file.isAutoSpacing && (n > 0))
{
int c = fgetc(dfself->handle);
if( (c != '\n') && (c != EOF) )
ungetc(c, dfself->handle);
}
}
if(nread != n)
{
dfself->file.hasError = 1; /* shouldn't we put hasError to 0 all the time ? */
if(!dfself->file.isQuiet)
THError("read error: read %ld blocks instead of %ld", nread, n);
}
return nread;
}
static long THDiskFile_readString(THFile *self, const char *format, char **str_)
{
THDiskFile *dfself = (THDiskFile*)(self);
THArgCheck(dfself->handle != NULL, 1, "attempt to use a closed file");
THArgCheck(dfself->file.isReadable, 1, "attempt to read in a write-only file");
THArgCheck((strlen(format) >= 2 ? (format[0] == '*') && (format[1] == 'a' || format[1] == 'l') : 0), 2, "format must be '*a' or '*l'");
/* note: the string won't survive long, as it is copied into lua */
/* so 1024 is not that big... */
#define TBRS_BSZ 1024L
if(format[1] == 'a')
{
char *p = (char*)THAlloc(TBRS_BSZ);
long total = TBRS_BSZ;
long pos = 0L;
if (p == NULL)
THError("read error: failed to allocate buffer");
for (;;)
{
if(total-pos == 0) /* we need more space! */
{
total += TBRS_BSZ;
char *new_p = (char*)THRealloc(p, total);
if (new_p == NULL)
{
THFree(p);
THError("read error: failed to reallocate buffer");
}
p = new_p;
}
pos += fread(p+pos, 1, total-pos, dfself->handle);
if (pos < total) /* eof? */
{
if(pos == 0L)
{
THFree(p);
dfself->file.hasError = 1;
if(!dfself->file.isQuiet)
THError("read error: read 0 blocks instead of 1");
*str_ = NULL;
return 0;
}
*str_ = p;
return pos;
}
}
}
else
{
char *p = (char*)THAlloc(TBRS_BSZ);
long total = TBRS_BSZ;
long pos = 0L;
long size;
if (p == NULL)
THError("read error: failed to allocate buffer");
for (;;)
{
if(total-pos <= 1) /* we can only write '\0' in there! */
{
total += TBRS_BSZ;
char *new_p = (char*)THRealloc(p, total);
if (new_p == NULL)
{
THFree(p);
THError("read error: failed to reallocate buffer");
}
p = new_p;
}
if (fgets(p+pos, total-pos, dfself->handle) == NULL) /* eof? */
{
if(pos == 0L)
{
THFree(p);
dfself->file.hasError = 1;
if(!dfself->file.isQuiet)
THError("read error: read 0 blocks instead of 1");
*str_ = NULL;
return 0;
}
*str_ = p;
return pos;
}
size = strlen(p+pos);
if (size == 0L || (p+pos)[size-1] != '\n')
{
pos += size;
}
else
{
pos += size-1L; /* do not include `eol' */
*str_ = p;
return pos;
}
}
}
*str_ = NULL;
return 0;
}
THFile *THDiskFile_new(const std::string &name, const char *mode, int isQuiet)
{
static struct THFileVTable vtable = {
THDiskFile_isOpened,
THDiskFile_readByte,
THDiskFile_readChar,
THDiskFile_readShort,
THDiskFile_readInt,
THDiskFile_readLong,
THDiskFile_readFloat,
THDiskFile_readDouble,
THDiskFile_readString,
THDiskFile_seek,
THDiskFile_seekEnd,
THDiskFile_position,
THDiskFile_close,
THDiskFile_free
};
int isReadable;
int isWritable;
FILE *handle;
THDiskFile *self;
THArgCheck(THDiskFile_mode(mode, &isReadable, &isWritable), 2, "file mode should be 'r','w' or 'rw'");
CV_Assert(isReadable && !isWritable);
#ifdef _MSC_VER
if (fopen_s(&handle, name.c_str(), "rb") != 0)
handle = NULL;
#else
handle = fopen(name.c_str(),"rb");
#endif
if(!handle)
{
if(isQuiet)
return 0;
else
THError("cannot open <%s> in mode %c%c", name.c_str(), (isReadable ? 'r' : ' '), (isWritable ? 'w' : ' '));
}
self = (THDiskFile*)THAlloc(sizeof(THDiskFile));
if (!self)
THError("cannot allocate memory for self");
self->handle = handle;
self->isNativeEncoding = 1;
self->longSize = 0;
self->file.vtable = &vtable;
self->file.isQuiet = isQuiet;
self->file.isReadable = isReadable;
self->file.isWritable = isWritable;
self->file.isBinary = 0;
self->file.isAutoSpacing = 1;
self->file.hasError = 0;
return (THFile*)self;
}
}

@ -1,22 +0,0 @@
#ifndef TH_DISK_FILE_INC
#define TH_DISK_FILE_INC
#include "THFile.h"
#include <string>
namespace TH
{
TH_API THFile *THDiskFile_new(const std::string &name, const char *mode, int isQuiet);
TH_API int THDiskFile_isLittleEndianCPU(void);
TH_API int THDiskFile_isBigEndianCPU(void);
TH_API void THDiskFile_nativeEndianEncoding(THFile *self);
TH_API void THDiskFile_littleEndianEncoding(THFile *self);
TH_API void THDiskFile_bigEndianEncoding(THFile *self);
TH_API void THDiskFile_longSize(THFile *self, int size);
TH_API void THDiskFile_noBuffer(THFile *self);
} // namespace
#endif

@ -1,120 +0,0 @@
#include "../precomp.hpp"
#include "THFile.h"
#include "THFilePrivate.h"
namespace TH {
#define IMPLEMENT_THFILE_RW(TYPEC, TYPE) \
long THFile_read##TYPEC##Raw(THFile *self, TYPE *data, long n) \
{ \
return (*self->vtable->read##TYPEC)(self, data, n); \
}
IMPLEMENT_THFILE_RW(Byte, unsigned char)
IMPLEMENT_THFILE_RW(Char, char)
IMPLEMENT_THFILE_RW(Short, short)
IMPLEMENT_THFILE_RW(Int, int)
IMPLEMENT_THFILE_RW(Long, int64)
IMPLEMENT_THFILE_RW(Float, float)
IMPLEMENT_THFILE_RW(Double, double)
long THFile_readStringRaw(THFile *self, const char *format, char **str_)
{
return self->vtable->readString(self, format, str_);
}
void THFile_seek(THFile *self, long position)
{
self->vtable->seek(self, position);
}
void THFile_seekEnd(THFile *self)
{
self->vtable->seekEnd(self);
}
long THFile_position(THFile *self)
{
return self->vtable->position(self);
}
void THFile_close(THFile *self)
{
self->vtable->close(self);
}
void THFile_free(THFile *self)
{
self->vtable->free(self);
}
int THFile_isOpened(THFile *self)
{
return self->vtable->isOpened(self);
}
#define IMPLEMENT_THFILE_FLAGS(FLAG) \
int THFile_##FLAG(THFile *self) \
{ \
return self->FLAG; \
}
IMPLEMENT_THFILE_FLAGS(isQuiet)
IMPLEMENT_THFILE_FLAGS(isReadable)
IMPLEMENT_THFILE_FLAGS(isWritable)
IMPLEMENT_THFILE_FLAGS(isBinary)
IMPLEMENT_THFILE_FLAGS(isAutoSpacing)
IMPLEMENT_THFILE_FLAGS(hasError)
void THFile_binary(THFile *self)
{
self->isBinary = 1;
}
void THFile_ascii(THFile *self)
{
self->isBinary = 0;
}
void THFile_autoSpacing(THFile *self)
{
self->isAutoSpacing = 1;
}
void THFile_noAutoSpacing(THFile *self)
{
self->isAutoSpacing = 0;
}
void THFile_quiet(THFile *self)
{
self->isQuiet = 1;
}
void THFile_pedantic(THFile *self)
{
self->isQuiet = 0;
}
void THFile_clearError(THFile *self)
{
self->hasError = 0;
}
#define IMPLEMENT_THFILE_SCALAR(TYPEC, TYPE) \
TYPE THFile_read##TYPEC##Scalar(THFile *self) \
{ \
TYPE scalar; \
THFile_read##TYPEC##Raw(self, &scalar, 1); \
return scalar; \
}
IMPLEMENT_THFILE_SCALAR(Byte, unsigned char)
IMPLEMENT_THFILE_SCALAR(Char, char)
IMPLEMENT_THFILE_SCALAR(Short, short)
IMPLEMENT_THFILE_SCALAR(Int, int)
IMPLEMENT_THFILE_SCALAR(Long, int64)
IMPLEMENT_THFILE_SCALAR(Float, float)
IMPLEMENT_THFILE_SCALAR(Double, double)
} // namespace

@ -1,53 +0,0 @@
#ifndef TH_FILE_INC
#define TH_FILE_INC
//#include "THStorage.h"
#include "opencv2/core/hal/interface.h"
#include "THGeneral.h"
namespace TH
{
typedef struct THFile__ THFile;
TH_API int THFile_isOpened(THFile *self);
TH_API int THFile_isQuiet(THFile *self);
TH_API int THFile_isReadable(THFile *self);
TH_API int THFile_isWritable(THFile *self);
TH_API int THFile_isBinary(THFile *self);
TH_API int THFile_isAutoSpacing(THFile *self);
TH_API int THFile_hasError(THFile *self);
TH_API void THFile_binary(THFile *self);
TH_API void THFile_ascii(THFile *self);
TH_API void THFile_autoSpacing(THFile *self);
TH_API void THFile_noAutoSpacing(THFile *self);
TH_API void THFile_quiet(THFile *self);
TH_API void THFile_pedantic(THFile *self);
TH_API void THFile_clearError(THFile *self);
/* scalar */
TH_API unsigned char THFile_readByteScalar(THFile *self);
TH_API char THFile_readCharScalar(THFile *self);
TH_API short THFile_readShortScalar(THFile *self);
TH_API int THFile_readIntScalar(THFile *self);
TH_API int64 THFile_readLongScalar(THFile *self);
TH_API float THFile_readFloatScalar(THFile *self);
TH_API double THFile_readDoubleScalar(THFile *self);
/* raw */
TH_API long THFile_readByteRaw(THFile *self, unsigned char *data, long n);
TH_API long THFile_readCharRaw(THFile *self, char *data, long n);
TH_API long THFile_readShortRaw(THFile *self, short *data, long n);
TH_API long THFile_readIntRaw(THFile *self, int *data, long n);
TH_API long THFile_readLongRaw(THFile *self, int64 *data, long n);
TH_API long THFile_readFloatRaw(THFile *self, float *data, long n);
TH_API long THFile_readDoubleRaw(THFile *self, double *data, long n);
TH_API long THFile_readStringRaw(THFile *self, const char *format, char **str_); /* you must deallocate str_ */
TH_API void THFile_seek(THFile *self, long position);
TH_API void THFile_seekEnd(THFile *self);
TH_API long THFile_position(THFile *self);
TH_API void THFile_close(THFile *self);
TH_API void THFile_free(THFile *self);
} // namespace
#endif //TH_FILE_INC

@ -1,37 +0,0 @@
namespace TH {
struct THFile__
{
struct THFileVTable *vtable;
int isQuiet;
int isReadable;
int isWritable;
int isBinary;
int isAutoSpacing;
int hasError;
};
/* virtual table definition */
struct THFileVTable
{
int (*isOpened)(THFile *self);
long (*readByte)(THFile *self, unsigned char *data, long n);
long (*readChar)(THFile *self, char *data, long n);
long (*readShort)(THFile *self, short *data, long n);
long (*readInt)(THFile *self, int *data, long n);
long (*readLong)(THFile *self, int64 *data, long n);
long (*readFloat)(THFile *self, float *data, long n);
long (*readDouble)(THFile *self, double *data, long n);
long (*readString)(THFile *self, const char *format, char **str_);
void (*seek)(THFile *self, long position);
void (*seekEnd)(THFile *self);
long (*position)(THFile *self);
void (*close)(THFile *self);
void (*free)(THFile *self);
};
} // namespace

@ -1,2 +0,0 @@
#include "../precomp.hpp"
#include "THGeneral.h"

@ -1,22 +0,0 @@
#ifndef TH_GENERAL_INC
#define TH_GENERAL_INC
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <limits.h>
#include <float.h>
#include <time.h>
#include <string.h>
#define TH_API
#define THError(...) CV_Error(cv::Error::StsError, cv::format(__VA_ARGS__))
#define THArgCheck(cond, ...) CV_Assert(cond)
#define THAlloc malloc
#define THRealloc realloc
#define THFree free
#endif

File diff suppressed because it is too large Load Diff

@ -1,140 +0,0 @@
import numpy as np
import sys
import os
import fnmatch
import argparse
try:
import cv2 as cv
except ImportError:
raise ImportError('Can\'t find OpenCV Python module. If you\'ve built it from sources without installation, '
'configure environment variable PYTHONPATH to "opencv_build_dir/lib" directory (with "python3" subdirectory if required)')
try:
import torch
except ImportError:
raise ImportError('Can\'t find pytorch. Please install it by following instructions on the official site')
from torch.utils.serialization import load_lua
from pascal_semsegm_test_fcn import eval_segm_result, get_conf_mat, get_metrics, DatasetImageFetch, SemSegmEvaluation
from imagenet_cls_test_alexnet import Framework, DnnCaffeModel
class NormalizePreproc:
def __init__(self):
pass
@staticmethod
def process(img):
image_data = np.array(img).transpose(2, 0, 1).astype(np.float32)
image_data = np.expand_dims(image_data, 0)
image_data /= 255.0
return image_data
class CityscapesDataFetch(DatasetImageFetch):
img_dir = ''
segm_dir = ''
segm_files = []
colors = []
i = 0
def __init__(self, img_dir, segm_dir, preproc):
self.img_dir = img_dir
self.segm_dir = segm_dir
self.segm_files = sorted([img for img in self.locate('*_color.png', segm_dir)])
self.colors = self.get_colors()
self.data_prepoc = preproc
self.i = 0
@staticmethod
def get_colors():
result = []
colors_list = (
(0, 0, 0), (128, 64, 128), (244, 35, 232), (70, 70, 70), (102, 102, 156), (190, 153, 153), (153, 153, 153),
(250, 170, 30), (220, 220, 0), (107, 142, 35), (152, 251, 152), (70, 130, 180), (220, 20, 60), (255, 0, 0),
(0, 0, 142), (0, 0, 70), (0, 60, 100), (0, 80, 100), (0, 0, 230), (119, 11, 32))
for c in colors_list:
result.append(DatasetImageFetch.pix_to_c(c))
return result
def __iter__(self):
return self
def next(self):
if self.i < len(self.segm_files):
segm_file = self.segm_files[self.i]
segm = cv.imread(segm_file, cv.IMREAD_COLOR)[:, :, ::-1]
segm = cv.resize(segm, (1024, 512), interpolation=cv.INTER_NEAREST)
img_file = self.rreplace(self.img_dir + segm_file[len(self.segm_dir):], 'gtFine_color', 'leftImg8bit')
assert os.path.exists(img_file)
img = cv.imread(img_file, cv.IMREAD_COLOR)[:, :, ::-1]
img = cv.resize(img, (1024, 512))
self.i += 1
gt = self.color_to_gt(segm, self.colors)
img = self.data_prepoc.process(img)
return img, gt
else:
self.i = 0
raise StopIteration
def get_num_classes(self):
return len(self.colors)
@staticmethod
def locate(pattern, root_path):
for path, dirs, files in os.walk(os.path.abspath(root_path)):
for filename in fnmatch.filter(files, pattern):
yield os.path.join(path, filename)
@staticmethod
def rreplace(s, old, new, occurrence=1):
li = s.rsplit(old, occurrence)
return new.join(li)
class TorchModel(Framework):
net = object
def __init__(self, model_file):
self.net = load_lua(model_file)
def get_name(self):
return 'Torch'
def get_output(self, input_blob):
tensor = torch.FloatTensor(input_blob)
out = self.net.forward(tensor).numpy()
return out
class DnnTorchModel(DnnCaffeModel):
net = cv.dnn.Net()
def __init__(self, model_file):
self.net = cv.dnn.readNetFromTorch(model_file)
def get_output(self, input_blob):
self.net.setBlob("", input_blob)
self.net.forward()
return self.net.getBlob(self.net.getLayerNames()[-1])
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--imgs_dir", help="path to Cityscapes validation images dir, imgsfine/leftImg8bit/val")
parser.add_argument("--segm_dir", help="path to Cityscapes dir with segmentation, gtfine/gtFine/val")
parser.add_argument("--model", help="path to torch model, download it here: "
"https://www.dropbox.com/sh/dywzk3gyb12hpe5/AAD5YkUa8XgMpHs2gCRgmCVCa")
parser.add_argument("--log", help="path to logging file")
args = parser.parse_args()
prep = NormalizePreproc()
df = CityscapesDataFetch(args.imgs_dir, args.segm_dir, prep)
fw = [TorchModel(args.model),
DnnTorchModel(args.model)]
segm_eval = SemSegmEvaluation(args.log)
segm_eval.process(fw, df)

@ -147,26 +147,6 @@ TEST_P(DNNTestNetwork, Inception_5h)
expectNoFallbacksFromCUDA(net); expectNoFallbacksFromCUDA(net);
} }
TEST_P(DNNTestNetwork, ENet)
{
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2023000000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
#endif
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_CPU_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU_FP16);
processNet("dnn/Enet-model-best.net", "", Size(512, 512), "l367_Deconvolution", 2e-5, 0.15);
expectNoFallbacksFromCUDA(net);
}
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe) TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
{ {
applyTestTag(CV_TEST_TAG_MEMORY_512MB); applyTestTag(CV_TEST_TAG_MEMORY_512MB);
@ -380,21 +360,6 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
expectNoFallbacksFromCUDA(net); expectNoFallbacksFromCUDA(net);
} }
TEST_P(DNNTestNetwork, OpenFace)
{
#if defined(INF_ENGINE_RELEASE)
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#endif
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0024 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.0071 : 0.0;
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "", l1, lInf);
expectNoFallbacksFromCUDA(net);
}
TEST_P(DNNTestNetwork, opencv_face_detector) TEST_P(DNNTestNetwork, opencv_face_detector)
{ {
Mat img = imread(findDataFile("gpu/lbpcascade/er.png")); Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
@ -482,9 +447,9 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
#endif #endif
Mat img = imread(findDataFile("dnn/googlenet_1.png")); Mat img = imread(findDataFile("dnn/googlenet_1.png"));
Mat inp = blobFromImage(img, 1.0, Size(320, 240), Scalar(103.939, 116.779, 123.68), false, false); Mat inp = blobFromImage(img, 1.0, Size(224, 224), Scalar(0.0, 0.0, 0.0), true, false);
// Output image has values in range [-143.526, 148.539]. // Output image has values in range [0.0, 255.0].
float l1 = 2e-4, lInf = 2.4e-3; float l1 = 5e-4, lInf = 1e-2;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{ {
l1 = 0.4; l1 = 0.4;
@ -492,13 +457,13 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
} }
else if (target == DNN_TARGET_CUDA_FP16) else if (target == DNN_TARGET_CUDA_FP16)
{ {
l1 = 0.3; l1 = 0.9;
lInf = 7.6; lInf = 16;
} }
else if (target == DNN_TARGET_CPU_FP16) else if (target == DNN_TARGET_CPU_FP16)
{ {
l1 = 0.4; l1 = 0.4;
lInf = 19.; lInf = 26.;
} }
else if (target == DNN_TARGET_VULKAN) else if (target == DNN_TARGET_VULKAN)
{ {
@ -519,7 +484,7 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
#endif #endif
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", inp, "", l1, lInf); processNet("dnn/mosaic-9.onnx", "", inp, "", l1, lInf);
#if defined(HAVE_INF_ENGINE) && INF_ENGINE_VER_MAJOR_GE(2019010000) #if defined(HAVE_INF_ENGINE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
expectNoFallbacksFromIE(net); expectNoFallbacksFromIE(net);
#endif #endif

@ -150,8 +150,6 @@ TEST(readNet, Regression)
net = readNet(findDataFile("dnn/opencv_face_detector.caffemodel", false), net = readNet(findDataFile("dnn/opencv_face_detector.caffemodel", false),
findDataFile("dnn/opencv_face_detector.prototxt")); findDataFile("dnn/opencv_face_detector.prototxt"));
EXPECT_FALSE(net.empty()); EXPECT_FALSE(net.empty());
net = readNet(findDataFile("dnn/openface_nn4.small2.v1.t7", false));
EXPECT_FALSE(net.empty());
net = readNet(findDataFile("dnn/tiny-yolo-voc.cfg"), net = readNet(findDataFile("dnn/tiny-yolo-voc.cfg"),
findDataFile("dnn/tiny-yolo-voc.weights", false)); findDataFile("dnn/tiny-yolo-voc.weights", false));
EXPECT_FALSE(net.empty()); EXPECT_FALSE(net.empty());

@ -1,664 +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
//
// Copyright (C) 2013, OpenCV Foundation, 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:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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 "test_precomp.hpp"
#include "npy_blob.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
namespace opencv_test
{
using namespace std;
using namespace testing;
using namespace cv;
using namespace cv::dnn;
template<typename TStr>
static std::string _tf(TStr filename, bool inTorchDir = true, bool required = true)
{
String path = "dnn/";
if (inTorchDir)
path += "torch/";
path += filename;
return findDataFile(path, required);
}
TEST(Torch_Importer, simple_read)
{
Net net;
ASSERT_NO_THROW(net = readNetFromTorch(_tf("net_simple_net.txt"), false));
ASSERT_FALSE(net.empty());
}
class Test_Torch_layers : public DNNTestLayer
{
public:
void runTorchNet(const String& prefix, String outLayerName = "",
bool check2ndBlob = false, bool isBinary = false, bool evaluate = true,
double l1 = 0.0, double lInf = 0.0)
{
String suffix = (isBinary) ? ".dat" : ".txt";
Mat inp, outRef;
ASSERT_NO_THROW( inp = readTorchBlob(_tf(prefix + "_input" + suffix), isBinary) );
ASSERT_NO_THROW( outRef = readTorchBlob(_tf(prefix + "_output" + suffix), isBinary) );
checkBackend(backend, target, &inp, &outRef);
Net net = readNetFromTorch(_tf(prefix + "_net" + suffix), isBinary, evaluate);
ASSERT_FALSE(net.empty());
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
if (outLayerName.empty())
outLayerName = net.getLayerNames().back();
net.setInput(inp);
std::vector<Mat> outBlobs;
net.forward(outBlobs, outLayerName);
l1 = l1 ? l1 : default_l1;
lInf = lInf ? lInf : default_lInf;
normAssert(outRef, outBlobs[0], "", l1, lInf);
if (check2ndBlob && backend == DNN_BACKEND_OPENCV)
{
Mat out2 = outBlobs[1];
Mat ref2 = readTorchBlob(_tf(prefix + "_output_2" + suffix), isBinary);
normAssert(out2, ref2, "", l1, lInf);
}
}
};
TEST_P(Test_Torch_layers, run_convolution)
{
// Output reference values are in range [23.4018, 72.0181]
double l1 = default_l1, lInf = default_lInf;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
{
l1 = 0.08;
lInf = 0.43;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
l1 = 0.08;
lInf = 0.5;
}
runTorchNet("net_conv", "", false, true, true, l1, lInf);
}
TEST_P(Test_Torch_layers, run_pool_max)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
if (target == DNN_TARGET_CUDA_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
if (target == DNN_TARGET_CPU_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU_FP16);
double l1 = 0.0, lInf = 0.0;
runTorchNet("net_pool_max", "", true, false, true, l1, lInf);
}
TEST_P(Test_Torch_layers, run_pool_ave)
{
runTorchNet("net_pool_ave");
}
TEST_P(Test_Torch_layers, run_reshape_change_batch_size)
{
runTorchNet("net_reshape");
}
TEST_P(Test_Torch_layers, run_reshape)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
runTorchNet("net_reshape_batch");
runTorchNet("net_reshape_channels", "", false, true);
}
TEST_P(Test_Torch_layers, run_reshape_single_sample)
{
// Reference output values in range [14.4586, 18.4492].
double l1 = default_l1, lInf = default_lInf;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
{
l1 = 0.033;
lInf = 0.05;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
l1 = 0.02;
lInf = 0.04;
}
runTorchNet("net_reshape_single_sample", "", false, false, true, l1, lInf);
}
TEST_P(Test_Torch_layers, run_linear)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
if (target == DNN_TARGET_CPU_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU_FP16);
runTorchNet("net_linear_2d");
}
TEST_P(Test_Torch_layers, run_concat)
{
runTorchNet("net_concat", "l5_torchMerge");
}
TEST_P(Test_Torch_layers, run_depth_concat)
{
double lInf = 0.0;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
{
lInf = 0.032;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
lInf = 0.03;
}
runTorchNet("net_depth_concat", "", false, true, true, 0.0, lInf);
}
TEST_P(Test_Torch_layers, run_deconv)
{
runTorchNet("net_deconv");
}
TEST_P(Test_Torch_layers, run_batch_norm)
{
runTorchNet("net_batch_norm", "", false, true);
runTorchNet("net_batch_norm_train", "", false, true, false);
}
TEST_P(Test_Torch_layers, net_prelu)
{
runTorchNet("net_prelu");
}
TEST_P(Test_Torch_layers, net_cadd_table)
{
runTorchNet("net_cadd_table");
}
TEST_P(Test_Torch_layers, net_softmax)
{
runTorchNet("net_softmax");
runTorchNet("net_softmax_spatial");
}
TEST_P(Test_Torch_layers, net_logsoftmax)
{
runTorchNet("net_logsoftmax");
runTorchNet("net_logsoftmax_spatial");
}
TEST_P(Test_Torch_layers, net_lp_pooling_square)
{
runTorchNet("net_lp_pooling_square", "", false, true);
}
TEST_P(Test_Torch_layers, net_lp_pooling_power)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
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
runTorchNet("net_lp_pooling_power", "", false, true);
}
TEST_P(Test_Torch_layers, net_conv_gemm_lrn)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
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);
#endif
double l1 = 0.0, lInf = 0.0;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CPU_FP16)
{
l1 = 0.046;
lInf = 0.023;
}
else if (target == DNN_TARGET_MYRIAD)
{
l1 = 0.02;
lInf = 0.05;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
l1 = 0.0042;
lInf = 0.021;
}
// The OpenCL kernels use the native_ math functions which have
// implementation defined accuracy, so we use relaxed thresholds. See
// https://github.com/opencv/opencv/issues/9821 for more details.
else if (target == DNN_TARGET_OPENCL)
{
l1 = 0.02;
lInf = 0.02;
}
runTorchNet("net_conv_gemm_lrn", "", false, true, true, l1, lInf);
}
TEST_P(Test_Torch_layers, net_inception_block)
{
runTorchNet("net_inception_block", "", false, true);
}
TEST_P(Test_Torch_layers, net_normalize)
{
if(backend == DNN_BACKEND_CUDA)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); /* only L1 and L2 norms are supported */
runTorchNet("net_normalize", "", false, true);
}
TEST_P(Test_Torch_layers, net_padding)
{
runTorchNet("net_padding", "", false, true);
runTorchNet("net_spatial_zero_padding", "", false, true);
runTorchNet("net_spatial_reflection_padding", "", false, true);
}
TEST_P(Test_Torch_layers, net_non_spatial)
{
#if defined(INF_ENGINE_RELEASE) && ( \
INF_ENGINE_VER_MAJOR_EQ(2021030000) || \
INF_ENGINE_VER_MAJOR_EQ(2021040000) \
)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
// 2021.3: crash
// 2021.4: [ GENERAL_ERROR ] AssertionFailed: !out.networkInputs.empty()
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
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_NGRAPH); // exception
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); // exception
#endif
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 &&
(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_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
runTorchNet("net_non_spatial", "", false, true);
}
TEST_P(Test_Torch_layers, run_paralel)
{
if (backend != DNN_BACKEND_OPENCV || target != DNN_TARGET_CPU)
throw SkipTestException(""); // TODO: Check this
runTorchNet("net_parallel", "l5_torchMerge");
}
TEST_P(Test_Torch_layers, net_residual)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (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_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
runTorchNet("net_residual", "", false, true);
}
class Test_Torch_nets : public DNNTestLayer {};
TEST_P(Test_Torch_nets, OpenFace_accuracy)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
#endif
checkBackend();
const string model = findDataFile("dnn/openface_nn4.small2.v1.t7", false);
Net net = readNetFromTorch(model);
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat sample = imread(findDataFile("cv/shared/lena.png"));
Mat sampleF32(sample.size(), CV_32FC3);
sample.convertTo(sampleF32, sampleF32.type());
sampleF32 /= 255;
resize(sampleF32, sampleF32, Size(96, 96), 0, 0, INTER_NEAREST);
Mat inputBlob = blobFromImage(sampleF32, 1.0, Size(), Scalar(), /*swapRB*/true);
net.setInput(inputBlob);
Mat out = net.forward();
// Reference output values are in range [-0.17212, 0.263492]
// on Myriad problem layer: l4_Pooling - does not use pads_begin
float l1 = 1e-5, lInf = 1e-3;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
{
l1 = 2e-3;
lInf = 5e-3;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
l1 = 0.0004;
lInf = 0.0012;
}
Mat outRef = readTorchBlob(_tf("net_openface_output.dat"), true);
normAssert(out, outRef, "", l1, lInf);
}
static Mat getSegmMask(const Mat& scores)
{
const int rows = scores.size[2];
const int cols = scores.size[3];
const int numClasses = scores.size[1];
Mat maxCl = Mat::zeros(rows, cols, CV_8UC1);
Mat maxVal(rows, cols, CV_32FC1, Scalar(0));
for (int ch = 0; ch < numClasses; ch++)
{
for (int row = 0; row < rows; row++)
{
const float *ptrScore = scores.ptr<float>(0, ch, row);
uint8_t *ptrMaxCl = maxCl.ptr<uint8_t>(row);
float *ptrMaxVal = maxVal.ptr<float>(row);
for (int col = 0; col < cols; col++)
{
if (ptrScore[col] > ptrMaxVal[col])
{
ptrMaxVal[col] = ptrScore[col];
ptrMaxCl[col] = (uchar)ch;
}
}
}
}
return maxCl;
}
// Computer per-class intersection over union metric.
static void normAssertSegmentation(const Mat& ref, const Mat& test)
{
CV_Assert_N(ref.dims == 4, test.dims == 4);
const int numClasses = ref.size[1];
CV_Assert(numClasses == test.size[1]);
Mat refMask = getSegmMask(ref);
Mat testMask = getSegmMask(test);
EXPECT_EQ(countNonZero(refMask != testMask), 0);
}
TEST_P(Test_Torch_nets, ENet_accuracy)
{
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
checkBackend();
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("");
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
if (target == DNN_TARGET_CPU_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU_FP16);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#else
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
{
if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
throw SkipTestException("");
}
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2023000000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
#endif
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
{
if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
throw SkipTestException("");
}
Net net;
{
const string model = findDataFile("dnn/Enet-model-best.net", false);
net = readNetFromTorch(model, true);
ASSERT_TRUE(!net.empty());
}
net.enableWinograd(false);
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat sample = imread(_tf("street.png", false));
Mat inputBlob = blobFromImage(sample, 1./255, Size(), Scalar(), /*swapRB*/true);
net.setInput(inputBlob, "");
Mat out = net.forward();
Mat ref = blobFromNPY(_tf("torch_enet_prob.npy", false));
// Due to numerical instability in Pooling-Unpooling layers (indexes jittering)
// thresholds for ENet must be changed. Accuracy of results was checked on
// Cityscapes dataset and difference in mIOU with Torch is 10E-4%
normAssert(ref, out, "", 0.0005, /*target == DNN_TARGET_CPU ? 0.453 : */0.552);
normAssertSegmentation(ref, out);
const int N = 3;
for (int i = 0; i < N; i++)
{
net.setInput(inputBlob, "");
Mat out = net.forward();
normAssert(ref, out, "", 0.0005, /*target == DNN_TARGET_CPU ? 0.453 : */0.552);
normAssertSegmentation(ref, out);
}
}
// Check accuracy of style transfer models from https://github.com/jcjohnson/fast-neural-style
// th fast_neural_style.lua \
// -input_image ~/opencv_extra/testdata/dnn/googlenet_1.png \
// -output_image lena.png \
// -median_filter 0 \
// -image_size 0 \
// -model models/eccv16/starry_night.t7
// th fast_neural_style.lua \
// -input_image ~/opencv_extra/testdata/dnn/googlenet_1.png \
// -output_image lena.png \
// -median_filter 0 \
// -image_size 0 \
// -model models/instance_norm/feathers.t7
TEST_P(Test_Torch_nets, FastNeuralStyle_accuracy)
{
#if defined INF_ENGINE_RELEASE
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
if (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, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
#endif
checkBackend();
#if defined(INF_ENGINE_RELEASE)
#if INF_ENGINE_RELEASE <= 2018050000
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_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#endif
std::string models[] = {"dnn/fast_neural_style_eccv16_starry_night.t7",
"dnn/fast_neural_style_instance_norm_feathers.t7"};
std::string targets[] = {"dnn/lena_starry_night.png", "dnn/lena_feathers.png"};
for (int i = 0; i < 2; ++i)
{
const string model = findDataFile(models[i], false);
Net net = readNetFromTorch(model);
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat img = imread(findDataFile("dnn/googlenet_1.png"));
Mat inputBlob = blobFromImage(img, 1.0, Size(), Scalar(103.939, 116.779, 123.68), false);
net.setInput(inputBlob);
Mat out = net.forward();
// Deprocessing.
getPlane(out, 0, 0) += 103.939;
getPlane(out, 0, 1) += 116.779;
getPlane(out, 0, 2) += 123.68;
out = cv::min(cv::max(0, out), 255);
Mat ref = imread(findDataFile(targets[i]));
Mat refBlob = blobFromImage(ref, 1.0, Size(), Scalar(), false);
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{
double normL1 = cvtest::norm(refBlob, out, cv::NORM_L1) / refBlob.total();
if (target == DNN_TARGET_MYRIAD)
EXPECT_LE(normL1, 4.0f);
else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
EXPECT_LE(normL1, 1.0f);
else
EXPECT_LE(normL1, 0.6f);
}
else if(target == DNN_TARGET_CUDA_FP16)
{
normAssert(out, refBlob, "", 0.6, 26);
}
else if (target == DNN_TARGET_CPU_FP16)
{
normAssert(out, refBlob, "", 0.62, 25);
}
else
normAssert(out, refBlob, "", 0.5, 1.11);
}
}
INSTANTIATE_TEST_CASE_P(/**/, Test_Torch_nets, dnnBackendsAndTargets());
// Test a custom layer
// https://github.com/torch/nn/blob/master/doc/convolution.md#nn.SpatialUpSamplingNearest
class SpatialUpSamplingNearestLayer CV_FINAL : public Layer
{
public:
SpatialUpSamplingNearestLayer(const LayerParams &params) : Layer(params)
{
scale = params.get<int>("scale_factor");
}
static Ptr<Layer> create(LayerParams& params)
{
return Ptr<Layer>(new SpatialUpSamplingNearestLayer(params));
}
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
const int requiredOutputs,
std::vector<std::vector<int> > &outputs,
std::vector<std::vector<int> > &internals) const CV_OVERRIDE
{
std::vector<int> outShape(4);
outShape[0] = inputs[0][0]; // batch size
outShape[1] = inputs[0][1]; // number of channels
outShape[2] = scale * inputs[0][2];
outShape[3] = scale * inputs[0][3];
outputs.assign(1, outShape);
return false;
}
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays) CV_OVERRIDE
{
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
std::vector<Mat> inputs, outputs;
inputs_arr.getMatVector(inputs);
outputs_arr.getMatVector(outputs);
Mat& inp = inputs[0];
Mat& out = outputs[0];
const int outHeight = out.size[2];
const int outWidth = out.size[3];
for (size_t n = 0; n < inp.size[0]; ++n)
{
for (size_t ch = 0; ch < inp.size[1]; ++ch)
{
resize(getPlane(inp, n, ch), getPlane(out, n, ch),
Size(outWidth, outHeight), 0, 0, INTER_NEAREST);
}
}
}
private:
int scale;
};
TEST_P(Test_Torch_layers, upsampling_nearest)
{
#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); // TODO
#endif
// Test a custom layer.
CV_DNN_REGISTER_LAYER_CLASS(SpatialUpSamplingNearest, SpatialUpSamplingNearestLayer);
try
{
runTorchNet("net_spatial_upsampling_nearest", "", false, true);
}
catch (...)
{
LayerFactory::unregisterLayer("SpatialUpSamplingNearest");
throw;
}
LayerFactory::unregisterLayer("SpatialUpSamplingNearest");
// Test an implemented layer.
runTorchNet("net_spatial_upsampling_nearest", "", false, true);
}
INSTANTIATE_TEST_CASE_P(/**/, Test_Torch_layers, dnnBackendsAndTargets());
}

@ -148,7 +148,7 @@ video = {
} }
dnn = {'dnn_Net': ['setInput', 'forward', 'setPreferableBackend'], dnn = {'dnn_Net': ['setInput', 'forward', 'setPreferableBackend'],
'': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromTorch', 'readNetFromDarknet', '': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromDarknet',
'readNetFromONNX', 'readNetFromTFLite', 'readNet', 'blobFromImage']} 'readNetFromONNX', 'readNetFromTFLite', 'readNet', 'blobFromImage']}
features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptorSize', 'descriptorType', 'defaultNorm', 'empty', 'getDefaultName'], features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptorSize', 'descriptorType', 'defaultNorm', 'empty', 'getDefaultName'],

@ -16,7 +16,7 @@ def get_args_parser(func_args):
help='An optional path to file with preprocessing parameters.') help='An optional path to file with preprocessing parameters.')
parser.add_argument('--input', parser.add_argument('--input',
help='Path to input image or video file. Skip this argument to capture frames from a camera.') help='Path to input image or video file. Skip this argument to capture frames from a camera.')
parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'torch', 'darknet'], parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'darknet'],
help='Optional name of an origin framework of the model. ' help='Optional name of an origin framework of the model. '
'Detect it automatically if it does not set.') 'Detect it automatically if it does not set.')
parser.add_argument('--std', nargs='*', type=float, parser.add_argument('--std', nargs='*', type=float,

@ -77,7 +77,7 @@ std::string genPreprocArguments(const std::string& modelName, const std::string&
{ {
return genArgument("model", "Path to a binary file of model contains trained weights. " return genArgument("model", "Path to a binary file of model contains trained weights. "
"It could be a file with extensions .caffemodel (Caffe), " "It could be a file with extensions .caffemodel (Caffe), "
".pb (TensorFlow), .t7 or .net (Torch), .weights (Darknet), .bin (OpenVINO).", ".pb (TensorFlow), .weights (Darknet), .bin (OpenVINO).",
modelName, zooFile, 'm') + modelName, zooFile, 'm') +
genArgument("config", "Path to a text file of model contains network configuration. " genArgument("config", "Path to a text file of model contains network configuration. "
"It could be a file with extensions .prototxt (Caffe), .pbtxt (TensorFlow), .cfg (Darknet), .xml (OpenVINO).", "It could be a file with extensions .prototxt (Caffe), .pbtxt (TensorFlow), .cfg (Darknet), .xml (OpenVINO).",

@ -62,7 +62,7 @@ def add_preproc_args(zoo, parser, sample):
add_argument(zoo, parser, 'model', required=True, add_argument(zoo, parser, 'model', required=True,
help='Path to a binary file of model contains trained weights. ' help='Path to a binary file of model contains trained weights. '
'It could be a file with extensions .caffemodel (Caffe), ' 'It could be a file with extensions .caffemodel (Caffe), '
'.pb (TensorFlow), .t7 or .net (Torch), .weights (Darknet), .bin (OpenVINO)') '.pb (TensorFlow), .weights (Darknet), .bin (OpenVINO)')
add_argument(zoo, parser, 'config', add_argument(zoo, parser, 'config',
help='Path to a text file of model contains network configuration. ' help='Path to a text file of model contains network configuration. '
'It could be a file with extensions .prototxt (Caffe), .pbtxt or .config (TensorFlow), .cfg (Darknet), .xml (OpenVINO)') 'It could be a file with extensions .prototxt (Caffe), .pbtxt or .config (TensorFlow), .cfg (Darknet), .xml (OpenVINO)')

@ -151,21 +151,6 @@ googlenet:
# Semantic segmentation models. # Semantic segmentation models.
################################################################################ ################################################################################
# ENet road scene segmentation network from https://github.com/e-lab/ENet-training
# Works fine for different input sizes.
enet:
load_info:
url: "https://www.dropbox.com/s/tdde0mawbi5dugq/Enet-model-best.net?dl=1"
sha1: "b4123a73bf464b9ebe9cfc4ab9c2d5c72b161315"
model: "Enet-model-best.net"
mean: [0, 0, 0]
scale: 0.00392
width: 512
height: 256
rgb: true
classes: "enet-classes.txt"
sample: "segmentation"
fcn8s: fcn8s:
load_info: load_info:
url: "http://dl.caffe.berkeleyvision.org/fcn8s-heavy-pascal.caffemodel" url: "http://dl.caffe.berkeleyvision.org/fcn8s-heavy-pascal.caffemodel"

@ -24,7 +24,7 @@ parser.add_argument('--out_tf_graph', default='graph.pbtxt',
help='For models from TensorFlow Object Detection API, you may ' help='For models from TensorFlow Object Detection API, you may '
'pass a .config file which was used for training through --config ' 'pass a .config file which was used for training through --config '
'argument. This way an additional .pbtxt file with TensorFlow graph will be created.') 'argument. This way an additional .pbtxt file with TensorFlow graph will be created.')
parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'torch', 'darknet', 'dldt'], parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'darknet', 'dldt'],
help='Optional name of an origin framework of the model. ' help='Optional name of an origin framework of the model. '
'Detect it automatically if it does not set.') 'Detect it automatically if it does not set.')
parser.add_argument('--thr', type=float, default=0.5, help='Confidence threshold') parser.add_argument('--thr', type=float, default=0.5, help='Confidence threshold')

@ -14,7 +14,7 @@ parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--zoo', default=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models.yml'), parser.add_argument('--zoo', default=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models.yml'),
help='An optional path to file with preprocessing parameters.') help='An optional path to file with preprocessing parameters.')
parser.add_argument('--input', help='Path to input image or video file. Skip this argument to capture frames from a camera.') parser.add_argument('--input', help='Path to input image or video file. Skip this argument to capture frames from a camera.')
parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'torch', 'darknet'], parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'darknet'],
help='Optional name of an origin framework of the model. ' help='Optional name of an origin framework of the model. '
'Detect it automatically if it does not set.') 'Detect it automatically if it does not set.')
parser.add_argument('--colors', help='Optional path to a text file with colors for an every class. ' parser.add_argument('--colors', help='Optional path to a text file with colors for an every class. '

Loading…
Cancel
Save