mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
Merge pull request #9009 from alalek:fix_dnn_initialization
This commit is contained in:
commit
2ae849091c
@ -73,13 +73,6 @@ namespace dnn //! This namespace is used for dnn module functionlaity.
|
||||
DNN_TARGET_OPENCL
|
||||
};
|
||||
|
||||
/** @brief Initialize dnn module and built-in layers.
|
||||
*
|
||||
* This function automatically called on most of OpenCV builds,
|
||||
* but you need to call it manually on some specific configurations (iOS for example).
|
||||
*/
|
||||
CV_EXPORTS_W void initModule();
|
||||
|
||||
/** @brief This class provides all data needed to initialize layer.
|
||||
*
|
||||
* It includes dictionary with scalar params (which can be readed by using Dict interface),
|
||||
|
77
modules/dnn/include/opencv2/dnn/layer.details.hpp
Normal file
77
modules/dnn/include/opencv2/dnn/layer.details.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
#ifndef OPENCV_DNN_LAYER_DETAILS_HPP
|
||||
#define OPENCV_DNN_LAYER_DETAILS_HPP
|
||||
|
||||
#include <opencv2/dnn/layer.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace dnn
|
||||
{
|
||||
|
||||
/** @brief Registers layer constructor in runtime.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer.
|
||||
* @details This macros must be placed inside the function code.
|
||||
*/
|
||||
#define CV_DNN_REGISTER_LAYER_FUNC(type, constuctorFunc) \
|
||||
cv::dnn::LayerFactory::registerLayer(#type, constuctorFunc);
|
||||
|
||||
/** @brief Registers layer class in runtime.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param class C++ class, derived from Layer.
|
||||
* @details This macros must be placed inside the function code.
|
||||
*/
|
||||
#define CV_DNN_REGISTER_LAYER_CLASS(type, class) \
|
||||
cv::dnn::LayerFactory::registerLayer(#type, cv::dnn::details::_layerDynamicRegisterer<class>);
|
||||
|
||||
/** @brief Registers layer constructor on module load time.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer.
|
||||
* @details This macros must be placed outside the function code.
|
||||
*/
|
||||
#define CV_DNN_REGISTER_LAYER_FUNC_STATIC(type, constuctorFunc) \
|
||||
static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, constuctorFunc);
|
||||
|
||||
/** @brief Registers layer class on module load time.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param class C++ class, derived from Layer.
|
||||
* @details This macros must be placed outside the function code.
|
||||
*/
|
||||
#define CV_DNN_REGISTER_LAYER_CLASS_STATIC(type, class) \
|
||||
Ptr<Layer> __LayerStaticRegisterer_func_##type(LayerParams ¶ms) \
|
||||
{ return Ptr<Layer>(new class(params)); } \
|
||||
static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, __LayerStaticRegisterer_func_##type);
|
||||
|
||||
namespace details {
|
||||
|
||||
template<typename LayerClass>
|
||||
Ptr<Layer> _layerDynamicRegisterer(LayerParams ¶ms)
|
||||
{
|
||||
return Ptr<Layer>(LayerClass::create(params));
|
||||
}
|
||||
|
||||
//allows automatically register created layer on module load time
|
||||
class _LayerStaticRegisterer
|
||||
{
|
||||
String type;
|
||||
public:
|
||||
|
||||
_LayerStaticRegisterer(const String &layerType, LayerFactory::Constuctor layerConstuctor)
|
||||
{
|
||||
this->type = layerType;
|
||||
LayerFactory::registerLayer(layerType, layerConstuctor);
|
||||
}
|
||||
|
||||
~_LayerStaticRegisterer()
|
||||
{
|
||||
LayerFactory::unregisterLayer(type);
|
||||
}
|
||||
};
|
||||
|
||||
}}} //namespace
|
||||
|
||||
#endif
|
@ -61,88 +61,26 @@ public:
|
||||
//! Each Layer class must provide this function to the factory
|
||||
typedef Ptr<Layer>(*Constuctor)(LayerParams ¶ms);
|
||||
|
||||
//! Registers the layer class with typename @p type and specified @p constructor.
|
||||
//! Registers the layer class with typename @p type and specified @p constructor. Thread-safe.
|
||||
static void registerLayer(const String &type, Constuctor constructor);
|
||||
|
||||
//! Unregisters registered layer with specified type name.
|
||||
//! Unregisters registered layer with specified type name. Thread-safe.
|
||||
static void unregisterLayer(const String &type);
|
||||
|
||||
/** @brief Creates instance of registered layer.
|
||||
* @param type type name of creating layer.
|
||||
* @param params parameters which will be used for layer initialization.
|
||||
* @note Thread-safe.
|
||||
*/
|
||||
static Ptr<Layer> createLayerInstance(const String &type, LayerParams& params);
|
||||
|
||||
private:
|
||||
LayerFactory();
|
||||
|
||||
struct Impl;
|
||||
static Ptr<Impl> impl();
|
||||
};
|
||||
|
||||
/** @brief Registers layer constructor in runtime.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer.
|
||||
* @details This macros must be placed inside the function code.
|
||||
*/
|
||||
#define REG_RUNTIME_LAYER_FUNC(type, constuctorFunc) \
|
||||
cv::dnn::LayerFactory::registerLayer(#type, constuctorFunc);
|
||||
|
||||
/** @brief Registers layer class in runtime.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param class C++ class, derived from Layer.
|
||||
* @details This macros must be placed inside the function code.
|
||||
*/
|
||||
#define REG_RUNTIME_LAYER_CLASS(type, class) \
|
||||
cv::dnn::LayerFactory::registerLayer(#type, _layerDynamicRegisterer<class>);
|
||||
|
||||
/** @brief Registers layer constructor on module load time.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer.
|
||||
* @details This macros must be placed outside the function code.
|
||||
*/
|
||||
#define REG_STATIC_LAYER_FUNC(type, constuctorFunc) \
|
||||
static cv::dnn::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, constuctorFunc);
|
||||
|
||||
/** @brief Registers layer class on module load time.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param class C++ class, derived from Layer.
|
||||
* @details This macros must be placed outside the function code.
|
||||
*/
|
||||
#define REG_STATIC_LAYER_CLASS(type, class) \
|
||||
Ptr<Layer> __LayerStaticRegisterer_func_##type(LayerParams ¶ms) \
|
||||
{ return Ptr<Layer>(new class(params)); } \
|
||||
static _LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, __LayerStaticRegisterer_func_##type);
|
||||
|
||||
|
||||
//! @}
|
||||
//! @}
|
||||
|
||||
|
||||
template<typename LayerClass>
|
||||
Ptr<Layer> _layerDynamicRegisterer(LayerParams ¶ms)
|
||||
{
|
||||
return Ptr<Layer>(LayerClass::create(params));
|
||||
}
|
||||
|
||||
//allows automatically register created layer on module load time
|
||||
class _LayerStaticRegisterer
|
||||
{
|
||||
String type;
|
||||
public:
|
||||
|
||||
_LayerStaticRegisterer(const String &layerType, LayerFactory::Constuctor layerConstuctor)
|
||||
{
|
||||
this->type = layerType;
|
||||
LayerFactory::registerLayer(layerType, layerConstuctor);
|
||||
}
|
||||
|
||||
~_LayerStaticRegisterer()
|
||||
{
|
||||
LayerFactory::unregisterLayer(type);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1937,42 +1937,69 @@ bool Layer::getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct LayerFactory::Impl : public std::map<String, LayerFactory::Constuctor>
|
||||
static Mutex& getLayerFactoryMutex()
|
||||
{
|
||||
};
|
||||
static Mutex* volatile instance = NULL;
|
||||
if (instance == NULL)
|
||||
{
|
||||
cv::AutoLock lock(getInitializationMutex());
|
||||
if (instance == NULL)
|
||||
instance = new Mutex();
|
||||
}
|
||||
return *instance;
|
||||
}
|
||||
|
||||
Ptr<LayerFactory::Impl> LayerFactory::impl ()
|
||||
typedef std::map<String, LayerFactory::Constuctor> LayerFactory_Impl;
|
||||
|
||||
static LayerFactory_Impl& getLayerFactoryImpl_()
|
||||
{
|
||||
// allocate on first use
|
||||
static Ptr<LayerFactory::Impl> impl_(new LayerFactory::Impl());
|
||||
return impl_;
|
||||
static LayerFactory_Impl impl;
|
||||
return impl;
|
||||
}
|
||||
|
||||
static LayerFactory_Impl& getLayerFactoryImpl()
|
||||
{
|
||||
static LayerFactory_Impl* volatile instance = NULL;
|
||||
if (instance == NULL)
|
||||
{
|
||||
cv::AutoLock lock(getLayerFactoryMutex());
|
||||
if (instance == NULL)
|
||||
{
|
||||
instance = &getLayerFactoryImpl_();
|
||||
initializeLayerFactory();
|
||||
}
|
||||
}
|
||||
return *instance;
|
||||
}
|
||||
|
||||
void LayerFactory::registerLayer(const String &_type, Constuctor constructor)
|
||||
{
|
||||
cv::AutoLock lock(getLayerFactoryMutex());
|
||||
String type = _type.toLowerCase();
|
||||
Impl::iterator it = impl()->find(type);
|
||||
LayerFactory_Impl::const_iterator it = getLayerFactoryImpl().find(type);
|
||||
|
||||
if (it != impl()->end() && it->second != constructor)
|
||||
if (it != getLayerFactoryImpl().end() && it->second != constructor)
|
||||
{
|
||||
CV_Error(cv::Error::StsBadArg, "Layer \"" + type + "\" already was registered");
|
||||
}
|
||||
|
||||
impl()->insert(std::make_pair(type, constructor));
|
||||
getLayerFactoryImpl().insert(std::make_pair(type, constructor));
|
||||
}
|
||||
|
||||
void LayerFactory::unregisterLayer(const String &_type)
|
||||
{
|
||||
cv::AutoLock lock(getLayerFactoryMutex());
|
||||
String type = _type.toLowerCase();
|
||||
impl()->erase(type);
|
||||
getLayerFactoryImpl().erase(type);
|
||||
}
|
||||
|
||||
Ptr<Layer> LayerFactory::createLayerInstance(const String &_type, LayerParams& params)
|
||||
{
|
||||
cv::AutoLock lock(getLayerFactoryMutex());
|
||||
String type = _type.toLowerCase();
|
||||
Impl::const_iterator it = LayerFactory::impl()->find(type);
|
||||
LayerFactory_Impl::const_iterator it = getLayerFactoryImpl().find(type);
|
||||
|
||||
if (it != impl()->end())
|
||||
if (it != getLayerFactoryImpl().end())
|
||||
{
|
||||
return it->second(params);
|
||||
}
|
||||
|
@ -40,68 +40,62 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <opencv2/dnn/layer.details.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace dnn
|
||||
{
|
||||
|
||||
struct AutoInitializer
|
||||
static Mutex* __initialization_mutex = NULL;
|
||||
Mutex& getInitializationMutex()
|
||||
{
|
||||
bool status;
|
||||
if (__initialization_mutex == NULL)
|
||||
__initialization_mutex = new Mutex();
|
||||
return *__initialization_mutex;
|
||||
}
|
||||
// force initialization (single-threaded environment)
|
||||
Mutex* __initialization_mutex_initializer = &getInitializationMutex();
|
||||
|
||||
AutoInitializer() : status(false)
|
||||
{
|
||||
initModule();
|
||||
}
|
||||
};
|
||||
|
||||
static AutoInitializer init;
|
||||
|
||||
void initModule()
|
||||
void initializeLayerFactory()
|
||||
{
|
||||
if (init.status)
|
||||
return;
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Slice, SliceLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Split, SplitLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Concat, ConcatLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Reshape, ReshapeLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Flatten, FlattenLayer);
|
||||
|
||||
REG_RUNTIME_LAYER_CLASS(Slice, SliceLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Split, SplitLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Concat, ConcatLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Reshape, ReshapeLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Flatten, FlattenLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Convolution, ConvolutionLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Deconvolution, DeconvolutionLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Pooling, PoolingLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(LRN, LRNLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(InnerProduct, InnerProductLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Softmax, SoftmaxLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(MVN, MVNLayer);
|
||||
|
||||
REG_RUNTIME_LAYER_CLASS(Convolution, ConvolutionLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Deconvolution, DeconvolutionLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Pooling, PoolingLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(LRN, LRNLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(InnerProduct, InnerProductLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Softmax, SoftmaxLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(MVN, MVNLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(ReLU, ReLULayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(ChannelsPReLU, ChannelsPReLULayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Sigmoid, SigmoidLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(TanH, TanHLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(BNLL, BNLLLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(AbsVal, AbsLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Power, PowerLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(BatchNorm, BatchNormLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(MaxUnpool, MaxUnpoolLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Dropout, BlankLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Identity, BlankLayer);
|
||||
|
||||
REG_RUNTIME_LAYER_CLASS(ReLU, ReLULayer);
|
||||
REG_RUNTIME_LAYER_CLASS(ChannelsPReLU, ChannelsPReLULayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Sigmoid, SigmoidLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(TanH, TanHLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(BNLL, BNLLLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(AbsVal, AbsLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Power, PowerLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(BatchNorm, BatchNormLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(MaxUnpool, MaxUnpoolLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Dropout, BlankLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Identity, BlankLayer);
|
||||
|
||||
REG_RUNTIME_LAYER_CLASS(Crop, CropLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Eltwise, EltwiseLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Permute, PermuteLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(PriorBox, PriorBoxLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(DetectionOutput, DetectionOutputLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(NormalizeBBox, NormalizeBBoxLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Normalize, NormalizeBBoxLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Shift, ShiftLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Padding, PaddingLayer);
|
||||
REG_RUNTIME_LAYER_CLASS(Scale, ScaleLayer);
|
||||
|
||||
init.status = true;
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Crop, CropLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Eltwise, EltwiseLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Permute, PermuteLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(PriorBox, PriorBoxLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(DetectionOutput, DetectionOutputLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(NormalizeBBox, NormalizeBBoxLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Normalize, NormalizeBBoxLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Shift, ShiftLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Padding, PaddingLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Scale, ScaleLayer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}} //namespace
|
||||
|
@ -43,3 +43,8 @@
|
||||
#include "cvconfig.h"
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/dnn/all_layers.hpp>
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
Mutex& getInitializationMutex();
|
||||
void initializeLayerFactory();
|
||||
}} // namespace
|
||||
|
@ -84,8 +84,6 @@ static std::vector<String> readClassNames(const char *filename = "synset_words.t
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cv::dnn::initModule(); //Required if OpenCV is built as static libs
|
||||
|
||||
String modelTxt = "bvlc_googlenet.prototxt";
|
||||
String modelBin = "bvlc_googlenet.caffemodel";
|
||||
String imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";
|
||||
|
@ -85,8 +85,6 @@ static void colorizeSegmentation(const Mat &score, const vector<cv::Vec3b> &colo
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cv::dnn::initModule(); //Required if OpenCV is built as static libs
|
||||
|
||||
String modelTxt = fcnType + "-heavy-pascal.prototxt";
|
||||
String modelBin = fcnType + "-heavy-pascal.caffemodel";
|
||||
String imageFile = (argc > 1) ? argv[1] : "rgb.jpg";
|
||||
|
@ -53,8 +53,6 @@ static std::vector<std::string> readClassNames(const char *filename = "synset_wo
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
initModule(); // Required if OpenCV is built as static libs.
|
||||
|
||||
std::string modelTxt = "train_val.prototxt";
|
||||
std::string modelBin = "squeezenet_v1.1.caffemodel";
|
||||
std::string imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";
|
||||
|
@ -62,8 +62,6 @@ int main(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cv::dnn::initModule(); //Required if OpenCV is built as static libs
|
||||
|
||||
String modelConfiguration = parser.get<string>("proto");
|
||||
String modelBinary = parser.get<string>("model");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user