mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 11:45:30 +08:00
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)
This commit is contained in:
parent
97620c053f
commit
b71be65f57
@ -1,76 +1,44 @@
|
||||
{
|
||||
"torch": [
|
||||
"onnx": [
|
||||
{
|
||||
"model": "candy.t7",
|
||||
"model": "mosaic-9.onnx",
|
||||
"inputSize": "224, 224",
|
||||
"mean": "104, 117, 123",
|
||||
"mean": "0, 0, 0",
|
||||
"std": "1",
|
||||
"swapRB": "false",
|
||||
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/candy.t7"
|
||||
"swapRB": "true",
|
||||
"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",
|
||||
"mean": "104, 117, 123",
|
||||
"mean": "0, 0, 0",
|
||||
"std": "1",
|
||||
"swapRB": "false",
|
||||
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/composition_vii.t7"
|
||||
"swapRB": "true",
|
||||
"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",
|
||||
"mean": "104, 117, 123",
|
||||
"mean": "0, 0, 0",
|
||||
"std": "1",
|
||||
"swapRB": "false",
|
||||
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/feathers.t7"
|
||||
"swapRB": "true",
|
||||
"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",
|
||||
"mean": "104, 117, 123",
|
||||
"mean": "0, 0, 0",
|
||||
"std": "1",
|
||||
"swapRB": "false",
|
||||
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/la_muse.t7"
|
||||
"swapRB": "true",
|
||||
"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",
|
||||
"mean": "104, 117, 123",
|
||||
"mean": "0, 0, 0",
|
||||
"std": "1",
|
||||
"swapRB": "false",
|
||||
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/mosaic.t7"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
"swapRB": "true",
|
||||
"modelUrl": "https://media.githubusercontent.com/media/onnx/models/main/vision/style_transfer/fast_neural_style/model/pointilism-9.onnx"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,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_utils.cpp$|/src/dnn_read.cpp$|/src/registry.cpp$|/src/backend.cpp$"
|
||||
# importers
|
||||
"/src/(caffe|darknet|onnx|tensorflow|torch)/"
|
||||
"/src/(caffe|darknet|onnx|tensorflow)/"
|
||||
# executors
|
||||
"/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.
|
||||
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:
|
||||
- Convolution
|
||||
- Deconvolution
|
||||
|
@ -934,41 +934,12 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
*/
|
||||
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.
|
||||
* @param[in] model Binary file contains trained weights. The following file
|
||||
* extensions are expected for models from different frameworks:
|
||||
* * `*.caffemodel` (Caffe, http://caffe.berkeleyvision.org/)
|
||||
* * `*.pb` (TensorFlow, https://www.tensorflow.org/)
|
||||
* * `*.t7` | `*.net` (Torch, http://torch.ch/)
|
||||
* * `*.weights` (Darknet, https://pjreddie.com/darknet/)
|
||||
* * `*.bin` (DLDT, https://software.intel.com/openvino-toolkit)
|
||||
* * `*.onnx` (ONNX, https://onnx.ai/)
|
||||
@ -982,8 +953,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,
|
||||
* @ref readNetFromTorch or @ref readNetFromDarknet. An order of @p model and @p config
|
||||
* 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.
|
||||
*/
|
||||
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,
|
||||
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.
|
||||
* @param[in] xml XML configuration file with network's topology.
|
||||
* @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");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -33,10 +33,6 @@ Net readNet(const String& _model, const String& _config, const String& _framewor
|
||||
{
|
||||
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 (modelExt == "cfg" || configExt == "weights")
|
||||
@ -66,8 +62,6 @@ Net readNet(const String& _framework, const std::vector<uchar>& bufferModel,
|
||||
return readNetFromTensorflow(bufferModel, bufferConfig);
|
||||
else if (framework == "darknet")
|
||||
return readNetFromDarknet(bufferConfig, bufferModel);
|
||||
else if (framework == "torch")
|
||||
CV_Error(Error::StsNotImplemented, "Reading Torch models from buffers");
|
||||
else if (framework == "dldt")
|
||||
return readNetFromModelOptimizer(bufferConfig, bufferModel);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
@ -380,21 +360,6 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
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)
|
||||
{
|
||||
Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
|
||||
@ -482,9 +447,9 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
#endif
|
||||
|
||||
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);
|
||||
// Output image has values in range [-143.526, 148.539].
|
||||
float l1 = 2e-4, lInf = 2.4e-3;
|
||||
Mat inp = blobFromImage(img, 1.0, Size(224, 224), Scalar(0.0, 0.0, 0.0), true, false);
|
||||
// Output image has values in range [0.0, 255.0].
|
||||
float l1 = 5e-4, lInf = 1e-2;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.4;
|
||||
@ -492,13 +457,13 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.3;
|
||||
lInf = 7.6;
|
||||
l1 = 0.9;
|
||||
lInf = 16;
|
||||
}
|
||||
else if (target == DNN_TARGET_CPU_FP16)
|
||||
{
|
||||
l1 = 0.4;
|
||||
lInf = 19.;
|
||||
lInf = 26.;
|
||||
}
|
||||
else if (target == DNN_TARGET_VULKAN)
|
||||
{
|
||||
@ -519,7 +484,7 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
#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)
|
||||
expectNoFallbacksFromIE(net);
|
||||
#endif
|
||||
|
@ -150,8 +150,6 @@ TEST(readNet, Regression)
|
||||
net = readNet(findDataFile("dnn/opencv_face_detector.caffemodel", false),
|
||||
findDataFile("dnn/opencv_face_detector.prototxt"));
|
||||
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"),
|
||||
findDataFile("dnn/tiny-yolo-voc.weights", false));
|
||||
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 ¶ms) : 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'],
|
||||
'': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromTorch', 'readNetFromDarknet',
|
||||
'': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromDarknet',
|
||||
'readNetFromONNX', 'readNetFromTFLite', 'readNet', 'blobFromImage']}
|
||||
|
||||
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.')
|
||||
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. '
|
||||
'Detect it automatically if it does not set.')
|
||||
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. "
|
||||
"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') +
|
||||
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).",
|
||||
|
@ -62,7 +62,7 @@ def add_preproc_args(zoo, parser, sample):
|
||||
add_argument(zoo, parser, 'model', required=True,
|
||||
help='Path to a binary file of model contains trained weights. '
|
||||
'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',
|
||||
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)')
|
||||
|
@ -151,21 +151,6 @@ googlenet:
|
||||
# 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:
|
||||
load_info:
|
||||
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 '
|
||||
'pass a .config file which was used for training through --config '
|
||||
'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. '
|
||||
'Detect it automatically if it does not set.')
|
||||
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'),
|
||||
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('--framework', choices=['caffe', 'tensorflow', 'torch', 'darknet'],
|
||||
parser.add_argument('--framework', choices=['caffe', 'tensorflow', 'darknet'],
|
||||
help='Optional name of an origin framework of the model. '
|
||||
'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. '
|
||||
|
Loading…
Reference in New Issue
Block a user