diff --git a/modules/dnn/CMakeLists.txt b/modules/dnn/CMakeLists.txt index c72b3fb79..d1eb3161c 100644 --- a/modules/dnn/CMakeLists.txt +++ b/modules/dnn/CMakeLists.txt @@ -3,7 +3,7 @@ set(OPENCV_MODULE_IS_PART_OF_WORLD OFF) option(WITH_PROTOBUF "Build with libprotobuf" ON) if(NOT WITH_PROTOBUF) - message(FATAL_ERROR "libprotobuf is required for dnn module") + message(FATAL_ERROR "libprotobuf is required for dnn module") endif() find_package( Protobuf REQUIRED ) @@ -14,9 +14,13 @@ else() message(FATAL_ERROR "Could not find PROTOBUF Compiler") endif() +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-shadow -Wno-parentheses) + file(GLOB PROTO_FILES src/*.proto) PROTOBUF_GENERATE_CPP(PROTO_HDRS PROTO_SRCS ${PROTO_FILES}) +include_directories(include src/caffe) + ocv_add_module(dnn opencv_imgproc opencv_core opencv_highgui WRAP python matlab) ocv_glob_module_sources(${PROTO_SRCS} ${PROTO_HDRS}) ocv_source_group("Src\\protobuf" FILES ${PROTO_SRCS} ${PROTO_HDRS}) @@ -27,4 +31,4 @@ ocv_create_module() target_link_libraries(opencv_dnn ${PROTOBUF_LIBRARIES}) ocv_add_accuracy_tests() ocv_add_perf_tests() -ocv_add_samples() \ No newline at end of file +ocv_add_samples() diff --git a/modules/dnn/include/opencv2/dnn.hpp b/modules/dnn/include/opencv2/dnn.hpp index fefd8373d..626433b18 100644 --- a/modules/dnn/include/opencv2/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn.hpp @@ -1,167 +1,13 @@ #ifndef __OPENCV_DNN_HPP__ #define __OPENCV_DNN_HPP__ -#include -#include -#include -#include "dnn/dict.hpp" +// This is an umbrealla header to include into you project. +// We are free to change headers layout in dnn subfolder, so please include +// this header for future compartibility -namespace cv -{ -namespace dnn -{ - class Layer; - class NetConfiguration; - class Net; - class Blob; - class LayerParams; +#include - //wrapper over cv::Mat and cv::UMat - CV_EXPORTS class Blob - { - Mat m; - public: - Blob(); - Blob(InputArray in); +#endif /* __OPENCV_DNN_HPP__ */ - void fill(InputArray in); - void fill(int ndims, const int *sizes, int type, void *data, bool deepCopy = true); - void create(int ndims, const int *sizes, int type = CV_32F); - bool empty() const; - - Mat& getMatRef(); - const Mat& getMatRef() const; - Mat getMat(); - Mat getMat(int num, int channel); - - int cols() const; - int rows() const; - Size size() const; - - int channels() const; - int num() const; - - Vec4i shape() const; - }; - - CV_EXPORTS class LayerParams : public Dict - { - public: - - std::vector learnedBlobs; - }; - - CV_EXPORTS class LayerRegister - { - public: - - typedef Layer* (*Constuctor)(); - - CV_EXPORTS static void registerLayer(const String &type, Constuctor constructor); - - CV_EXPORTS static void unregisterLayer(const String &type); - - CV_EXPORTS static Ptr createLayerInstance(const String &type); - - private: - LayerRegister(); - LayerRegister(const LayerRegister &lr); - - static std::map registeredLayers; - }; - - //this class allows to build new Layers - CV_EXPORTS class Layer - { - public: - - //TODO: this field must be declared as public if we want support possibility to change these params in runtime - std::vector learnedParams; - - virtual ~Layer(); - - //type of Layer - virtual String type() const; - - //setUp calls once (think that it's constructor) - virtual void setUp(LayerParams ¶ms); - - //maybe useless function - //shape of output blobs must be adjusted with respect to shape of input blobs - virtual void adjustShape(const std::vector &inputs, std::vector &outputs); - - virtual void forward(std::vector &inputs, std::vector &outputs); - - virtual int getNumInputs(); - virtual int getNumOutputs(); - //each input/output can be labeled to easily identify their using "layer_name.output_name" - virtual String getInputName(int inputNum); - virtual String getOutputName(int outputNum); - }; - - //containers for String and int - typedef DictValue LayerId; - typedef DictValue BlobId; - - CV_EXPORTS class Net - { - public: - - CV_EXPORTS Net(); - CV_EXPORTS ~Net(); - - CV_EXPORTS int addLayer(const String &name, const String &type, LayerParams ¶ms = LayerParams()); - CV_EXPORTS void deleteLayer(LayerId layer); - - //each output of each layer can be labeled by unique string label (as in Caffe) - //if label not specified then %layer_name%.%layer_output_id% can be used - void setOutputNames(LayerId layer, const std::vector &outputNames); - - CV_EXPORTS void connect(BlobId input, BlobId output); - CV_EXPORTS void connect(const std::vector &outputs, const std::vector &inputs); - CV_EXPORTS void connect(const std::vector &outputs, LayerId layer); - - int getOutputId(LayerId layer, int outputNum); - int getInputId(LayerId layer, int inputNum); - int getLayerId(LayerId layer); - - void forward(); - void forward(LayerId toLayer); - void forward(LayerId startLayer, LayerId toLayer); - void forward(const std::vector &startLayers, const std::vector &toLayers); - - //[Wished feature] Optimized smart forward(). Makes forward only for layers which wasn't changed after previous forward(). - void forwardOpt(LayerId toLayer); - void forwardOpt(const std::vector &toLayers); - - void setBlob(BlobId outputName, const Blob &blob); - Blob getBlob(BlobId outputName); - - void setParam(LayerId layer, int numParam, const Blob &blob); - void getParam(LayerId layer, int numParam); - - private: - - struct Impl; - Ptr impl; - }; - - CV_EXPORTS class Importer - { - public: - - virtual void populateNet(Net net) = 0; - - virtual ~Importer(); - }; - - CV_EXPORTS Ptr createCaffeImporter(const String &prototxt, const String &caffeModel); - -} -} - -#include "dnn/dnn.inl.hpp" - -#endif diff --git a/modules/dnn/include/opencv2/dnn/dict.hpp b/modules/dnn/include/opencv2/dnn/dict.hpp index 6740670ac..cd8be085c 100644 --- a/modules/dnn/include/opencv2/dnn/dict.hpp +++ b/modules/dnn/include/opencv2/dnn/dict.hpp @@ -35,7 +35,7 @@ struct DictValue DictValue &operator=(const DictValue &r); ~DictValue(); - + private: void release(); }; @@ -57,14 +57,14 @@ public: } template - const T &get(const String &name, const T &default) const + const T &get(const String &name, const T &default_value) const { _Dict::const_iterator i = dict.find(name); if (i != dict.end()) return i->second.get(); else - return default; + return default_value; } template @@ -154,7 +154,7 @@ inline DictValue & DictValue::operator=(const DictValue &r) { if (&r == this) return *this; - + release(); //how to copy anonymous union without memcpy? @@ -175,4 +175,4 @@ inline DictValue::DictValue(const DictValue &r) } } -} \ No newline at end of file +} diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp new file mode 100644 index 000000000..a8725b3fd --- /dev/null +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -0,0 +1,167 @@ +#ifndef __OPENCV_DNN_DNN_HPP__ +#define __OPENCV_DNN_DNN_HPP__ + +#include +#include +#include +#include + +namespace cv +{ +namespace dnn +{ + class Layer; + class NetConfiguration; + class Net; + class Blob; + class LayerParams; + + //wrapper over cv::Mat and cv::UMat + class CV_EXPORTS Blob + { + public: + Blob(); + Blob(InputArray in); + + void fill(InputArray in); + void fill(int ndims, const int *sizes, int type, void *data, bool deepCopy = true); + void create(int ndims, const int *sizes, int type = CV_32F); + + bool empty() const; + + Mat& getMatRef(); + const Mat& getMatRef() const; + Mat getMat(); + Mat getMat(int num, int channel); + + int cols() const; + int rows() const; + Size size() const; + + int channels() const; + int num() const; + + Vec4i shape() const; + + private: + Mat m; + }; + + class CV_EXPORTS LayerParams : public Dict + { + public: + + std::vector learnedBlobs; + }; + + class CV_EXPORTS LayerRegister + { + public: + + typedef Layer* (*Constuctor)(); + + static void registerLayer(const String &type, Constuctor constructor); + + static void unregisterLayer(const String &type); + + static Ptr createLayerInstance(const String &type); + + private: + LayerRegister(); + LayerRegister(const LayerRegister &lr); + + static std::map registeredLayers; + }; + + //this class allows to build new Layers + class CV_EXPORTS Layer + { + public: + //TODO: this field must be declared as public if we want support possibility to change these params in runtime + std::vector learnedParams; + + virtual ~Layer(); + + //type of Layer + virtual String type() const = 0; + + //setUp calls once (think that it's constructor) + virtual void setUp(LayerParams ¶ms) = 0; + + //maybe useless function + //shape of output blobs must be adjusted with respect to shape of input blobs + virtual void adjustShape(const std::vector &inputs, std::vector &outputs) = 0; + + virtual void forward(std::vector &inputs, std::vector &outputs) = 0; + + virtual int getNumInputs(); + virtual int getNumOutputs(); + //each input/output can be labeled to easily identify their using "layer_name.output_name" + virtual String getInputName(int inputNum); + virtual String getOutputName(int outputNum); + }; + + //containers for String and int + typedef DictValue LayerId; + typedef DictValue BlobId; + + class CV_EXPORTS Net + { + public: + + Net(); + ~Net(); + + int addLayer(const String &name, const String &type, LayerParams ¶ms = LayerParams()); + void deleteLayer(LayerId layer); + + //each output of each layer can be labeled by unique string label (as in Caffe) + //if label not specified then %layer_name%.%layer_output_id% can be used + void setOutputNames(LayerId layer, const std::vector &outputNames); + + void connect(BlobId input, BlobId output); + void connect(const std::vector &outputs, const std::vector &inputs); + void connect(const std::vector &outputs, LayerId layer); + + int getOutputId(LayerId layer, int outputNum); + int getInputId(LayerId layer, int inputNum); + int getLayerId(LayerId layer); + + void forward(); + void forward(LayerId toLayer); + void forward(LayerId startLayer, LayerId toLayer); + void forward(const std::vector &startLayers, const std::vector &toLayers); + + //[Wished feature] Optimized smart forward(). Makes forward only for layers which wasn't changed after previous forward(). + void forwardOpt(LayerId toLayer); + void forwardOpt(const std::vector &toLayers); + + void setBlob(BlobId outputName, const Blob &blob); + Blob getBlob(BlobId outputName); + + void setParam(LayerId layer, int numParam, const Blob &blob); + void getParam(LayerId layer, int numParam); + + private: + + struct Impl; + Ptr impl; + }; + + class CV_EXPORTS Importer + { + public: + + virtual void populateNet(Net net) = 0; + + virtual ~Importer(); + }; + + CV_EXPORTS Ptr createCaffeImporter(const String &prototxt, const String &caffeModel); + +} +} + +#include + +#endif /* __OPENCV_DNN_DNN_HPP__ */ diff --git a/modules/dnn/include/opencv2/dnn/dnn.inl.hpp b/modules/dnn/include/opencv2/dnn/dnn.inl.hpp index efd37af06..a03e05f34 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.inl.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.inl.hpp @@ -7,26 +7,23 @@ namespace cv { namespace dnn { - inline - Mat& Blob::getMatRef() + inline Mat& Blob::getMatRef() { return m; } - inline - const Mat& Blob::getMatRef() const + inline const Mat& Blob::getMatRef() const { return m; } - inline - Mat Blob::getMat() + inline Mat Blob::getMat() { return m; } - Mat Blob::getMat(int num, int channel) + inline Mat Blob::getMat(int num, int channel) { CV_Assert(false); return Mat(); diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index acfa00b47..538b42036 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -90,10 +90,31 @@ String toString(const T &v) return ss.str(); } +int Layer::getNumInputs() +{ + return 1; +} + +int Layer::getNumOutputs() +{ + return 1; +} + cv::String Layer::getInputName(int inputNum) { return "input" + toString(inputNum); } + +cv::String Layer::getOutputName(int outputNum) +{ + return "output" + toString(outputNum); +} + +Layer::~Layer() +{ + +} + } } \ No newline at end of file diff --git a/modules/dnn/src/precomp.hpp b/modules/dnn/src/precomp.hpp index 630af81d2..7dcb7282e 100644 --- a/modules/dnn/src/precomp.hpp +++ b/modules/dnn/src/precomp.hpp @@ -1,2 +1,2 @@ #include -#include \ No newline at end of file +#include