Merge pull request #9305 from dkurt:public_dnn_importer_is_deprecated
authorVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Mon, 18 Sep 2017 09:35:35 +0000 (09:35 +0000)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Mon, 18 Sep 2017 09:35:35 +0000 (09:35 +0000)
17 files changed:
modules/dnn/include/opencv2/dnn/all_layers.hpp
modules/dnn/include/opencv2/dnn/dnn.hpp
modules/dnn/misc/java/test/DnnTensorFlowTest.java
modules/dnn/src/caffe/caffe_importer.cpp
modules/dnn/src/tensorflow/tf_importer.cpp
modules/dnn/src/torch/torch_importer.cpp
modules/dnn/test/test_caffe_importer.cpp
modules/dnn/test/test_layers.cpp
modules/dnn/test/test_tf_importer.cpp
modules/dnn/test/test_torch_importer.cpp
modules/java/CMakeLists.txt
modules/python/python2/CMakeLists.txt
modules/python/python3/CMakeLists.txt
modules/python/src2/hdr_parser.py
samples/dnn/fcn_semsegm.cpp
samples/dnn/ssd_object_detection.cpp
samples/dnn/tf_inception.cpp

index 120981d..cf47c70 100644 (file)
@@ -55,7 +55,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
 
   Classes listed here, in fact, provides C++ API for creating intances of bult-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 convinient for native C++ programming and basically designed for use inside importers (see @ref Importer, @ref createCaffeImporter(), @ref createTorchImporter()).
+  You can use both API, but factory API is less convinient for native C++ programming and basically designed for use inside importers (see @ref readNetFromCaffe(), @ref readNetFromTorch(), @ref readNetFromTensorflow()).
 
   Bult-in layers partially reproduce functionality of corresponding Caffe and Torch7 layers.
   In partuclar, the following layers and Caffe @ref Importer were tested to reproduce <a href="http://caffe.berkeleyvision.org/tutorial/layers.html">Caffe</a> functionality:
index 20bea89..bd79669 100644 (file)
@@ -598,23 +598,27 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
         Ptr<Impl> impl;
     };
 
-    /** @brief Small interface class for loading trained serialized models of different dnn-frameworks. */
+    /**
+     * @deprecated Deprecated as external interface. Will be for internal needs only.
+     * @brief Small interface class for loading trained serialized models of different dnn-frameworks. */
     class CV_EXPORTS_W Importer : public Algorithm
     {
     public:
 
         /** @brief Adds loaded layers into the @p net and sets connections between them. */
-        CV_WRAP virtual void populateNet(Net net) = 0;
+        CV_DEPRECATED CV_WRAP virtual void populateNet(Net net) = 0;
 
         virtual ~Importer();
     };
 
-    /** @brief Creates the importer of <a href="http://caffe.berkeleyvision.org">Caffe</a> framework network.
+    /**
+     *  @deprecated Use @ref readNetFromCaffe instead.
+     *  @brief Creates the importer of <a href="http://caffe.berkeleyvision.org">Caffe</a> framework network.
      *  @param prototxt   path to the .prototxt file with text description of the network architecture.
      *  @param caffeModel path to the .caffemodel file with learned network.
      *  @returns Pointer to the created importer, NULL in failure cases.
      */
-    CV_EXPORTS_W Ptr<Importer> createCaffeImporter(const String &prototxt, const String &caffeModel = String());
+    CV_DEPRECATED CV_EXPORTS_W Ptr<Importer> createCaffeImporter(const String &prototxt, const String &caffeModel = String());
 
     /** @brief Reads a network model stored in Caffe model files.
       * @details This is shortcut consisting from createCaffeImporter and Net::populateNet calls.
@@ -631,13 +635,17 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
       */
     CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true);
 
-    /** @brief Creates the importer of <a href="http://www.tensorflow.org">TensorFlow</a> framework network.
+    /**
+     *  @deprecated Use @ref readNetFromTensorflow instead.
+     *  @brief Creates the importer of <a href="http://www.tensorflow.org">TensorFlow</a> framework network.
      *  @param model   path to the .pb file with binary protobuf description of the network architecture.
      *  @returns Pointer to the created importer, NULL in failure cases.
      */
-    CV_EXPORTS_W Ptr<Importer> createTensorflowImporter(const String &model);
+    CV_DEPRECATED CV_EXPORTS_W Ptr<Importer> createTensorflowImporter(const String &model);
 
-    /** @brief Creates the importer of <a href="http://torch.ch">Torch7</a> framework network.
+    /**
+     *  @deprecated Use @ref readNetFromTorch instead.
+     *  @brief Creates the importer of <a href="http://torch.ch">Torch7</a> framework network.
      *  @param filename 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.
      *  @returns Pointer to the created importer, NULL in failure cases.
@@ -663,7 +671,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
      *
      * Also some equivalents of these classes from cunn, cudnn, and fbcunn may be successfully imported.
      */
-    CV_EXPORTS_W Ptr<Importer> createTorchImporter(const String &filename, bool isBinary = true);
+    CV_DEPRECATED CV_EXPORTS_W Ptr<Importer> createTorchImporter(const String &filename, bool isBinary = true);
 
     /** @brief Loads blob which was serialized as torch.Tensor object of Torch7 framework.
      *  @warning This function has the same limitations as createTorchImporter().
index b4116e8..388237d 100644 (file)
@@ -51,12 +51,7 @@ public class DnnTensorFlowTest extends OpenCVTestCase {
         sourceImageFile = f.toString();
         if(!f.exists()) throw new Exception("Test image is missing: " + sourceImageFile);
 
-        net = new Net();
-        if(net.empty()) {
-            Importer importer = Dnn.createTensorflowImporter(modelFileName);
-            importer.populateNet(net);
-        }
-
+        net = Dnn.readNetFromTensorflow(modelFileName);
     }
 
     public void testGetLayerTypes() {
index 7d2711c..9923cf3 100644 (file)
@@ -385,24 +385,15 @@ Ptr<Importer> createCaffeImporter(const String &prototxt, const String &caffeMod
     return Ptr<Importer>(new CaffeImporter(prototxt.c_str(), caffeModel.c_str()));
 }
 
-#else //HAVE_PROTOBUF
-
-Ptr<Importer> createCaffeImporter(const String&, const String&)
-{
-    CV_Error(cv::Error::StsNotImplemented, "libprotobuf required to import data from Caffe models");
-    return Ptr<Importer>();
-}
-
-#endif //HAVE_PROTOBUF
-
 Net readNetFromCaffe(const String &prototxt, const String &caffeModel /*= String()*/)
 {
-    Ptr<Importer> caffeImporter = createCaffeImporter(prototxt, caffeModel);
+    CaffeImporter caffeImporter(prototxt.c_str(), caffeModel.c_str());
     Net net;
-    if (caffeImporter)
-        caffeImporter->populateNet(net);
+    caffeImporter.populateNet(net);
     return net;
 }
 
+#endif //HAVE_PROTOBUF
+
 CV__DNN_EXPERIMENTAL_NS_END
 }} // namespace
index b33d836..8e1f18e 100644 (file)
@@ -1098,10 +1098,9 @@ Ptr<Importer> createTensorflowImporter(const String&)
 
 Net readNetFromTensorflow(const String &model)
 {
-    Ptr<Importer> importer = createTensorflowImporter(model);
+    TFImporter importer(model.c_str());
     Net net;
-    if (importer)
-        importer->populateNet(net);
+    importer.populateNet(net);
     return net;
 }
 
index 1cb1b48..56c55d6 100644 (file)
@@ -1150,10 +1150,9 @@ Net readNetFromTorch(const String &model, bool isBinary)
 {
     CV_TRACE_FUNCTION();
 
-    Ptr<Importer> importer = createTorchImporter(model, isBinary);
+    TorchImporter importer(model, isBinary);
     Net net;
-    if (importer)
-        importer->populateNet(net);
+    importer.populateNet(net);
     return net;
 }
 
index f85eddd..b0741f6 100644 (file)
@@ -57,22 +57,14 @@ static std::string _tf(TString filename)
 
 TEST(Test_Caffe, read_gtsrb)
 {
-    Net net;
-    {
-        Ptr<Importer> importer = createCaffeImporter(_tf("gtsrb.prototxt"), "");
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
-    }
+    Net net = readNetFromCaffe(_tf("gtsrb.prototxt"));
+    ASSERT_FALSE(net.empty());
 }
 
 TEST(Test_Caffe, read_googlenet)
 {
-    Net net;
-    {
-        Ptr<Importer> importer = createCaffeImporter(_tf("bvlc_googlenet.prototxt"), "");
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
-    }
+    Net net = readNetFromCaffe(_tf("bvlc_googlenet.prototxt"));
+    ASSERT_FALSE(net.empty());
 }
 
 TEST(Reproducibility_AlexNet, Accuracy)
@@ -81,9 +73,8 @@ TEST(Reproducibility_AlexNet, Accuracy)
     {
         const string proto = findDataFile("dnn/bvlc_alexnet.prototxt", false);
         const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false);
-        Ptr<Importer> importer = createCaffeImporter(proto, model);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromCaffe(proto, model);
+        ASSERT_FALSE(net.empty());
     }
 
     Mat sample = imread(_tf("grace_hopper_227.png"));
@@ -107,9 +98,8 @@ TEST(Reproducibility_FCN, Accuracy)
     {
         const string proto = findDataFile("dnn/fcn8s-heavy-pascal.prototxt", false);
         const string model = findDataFile("dnn/fcn8s-heavy-pascal.caffemodel", false);
-        Ptr<Importer> importer = createCaffeImporter(proto, model);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromCaffe(proto, model);
+        ASSERT_FALSE(net.empty());
     }
 
     Mat sample = imread(_tf("street.png"));
@@ -136,9 +126,8 @@ TEST(Reproducibility_SSD, Accuracy)
     {
         const string proto = findDataFile("dnn/ssd_vgg16.prototxt", false);
         const string model = findDataFile("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", false);
-        Ptr<Importer> importer = createCaffeImporter(proto, model);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromCaffe(proto, model);
+        ASSERT_FALSE(net.empty());
     }
 
     Mat sample = imread(_tf("street.png"));
index 4ca06ef..ff33be5 100644 (file)
@@ -108,12 +108,8 @@ void testLayerUsingCaffeModels(String basename, bool useCaffeModel = false, bool
 
     cv::setNumThreads(cv::getNumberOfCPUs());
 
-    Net net;
-    {
-        Ptr<Importer> importer = createCaffeImporter(prototxt, (useCaffeModel) ? caffemodel : String());
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
-    }
+    Net net = readNetFromCaffe(prototxt, (useCaffeModel) ? caffemodel : String());
+    ASSERT_FALSE(net.empty());
 
     Mat inp = blobFromNPY(inpfile);
     Mat ref = blobFromNPY(outfile);
@@ -252,12 +248,8 @@ TEST(Layer_Test_Concat, Accuracy)
 
 static void test_Reshape_Split_Slice_layers()
 {
-    Net net;
-    {
-        Ptr<Importer> importer = createCaffeImporter(_tf("reshape_and_slice_routines.prototxt"));
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
-    }
+    Net net = readNetFromCaffe(_tf("reshape_and_slice_routines.prototxt"));
+    ASSERT_FALSE(net.empty());
 
     Mat input(6, 12, CV_32F);
     RNG rng(0);
@@ -276,12 +268,9 @@ TEST(Layer_Test_Reshape_Split_Slice, Accuracy)
 
 TEST(Layer_Conv_Elu, Accuracy)
 {
-    Net net;
-    {
-        Ptr<Importer> importer = createTensorflowImporter(_tf("layer_elu_model.pb"));
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
-    }
+    Net net = readNetFromTensorflow(_tf("layer_elu_model.pb"));
+    ASSERT_FALSE(net.empty());
+
     Mat inp = blobFromNPY(_tf("layer_elu_in.npy"));
     Mat ref = blobFromNPY(_tf("layer_elu_out.npy"));
 
index 8da59be..f296fc4 100644 (file)
@@ -29,9 +29,8 @@ TEST(Test_TensorFlow, read_inception)
     Net net;
     {
         const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
-        Ptr<Importer> importer = createTensorflowImporter(model);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromTensorflow(model);
+        ASSERT_FALSE(net.empty());
     }
 
     Mat sample = imread(_tf("grace_hopper_227.png"));
@@ -53,9 +52,8 @@ TEST(Test_TensorFlow, inception_accuracy)
     Net net;
     {
         const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
-        Ptr<Importer> importer = createTensorflowImporter(model);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromTensorflow(model);
+        ASSERT_FALSE(net.empty());
     }
 
     Mat sample = imread(_tf("grace_hopper_227.png"));
index c46f3a9..fa444ed 100644 (file)
@@ -66,11 +66,8 @@ static std::string _tf(TStr filename, bool inTorchDir = true)
 TEST(Torch_Importer, simple_read)
 {
     Net net;
-    Ptr<Importer> importer;
-
-    ASSERT_NO_THROW( importer = createTorchImporter(_tf("net_simple_net.txt"), false) );
-    ASSERT_TRUE( importer != NULL );
-    importer->populateNet(net);
+    ASSERT_NO_THROW(net = readNetFromTorch(_tf("net_simple_net.txt"), false));
+    ASSERT_FALSE(net.empty());
 }
 
 static void runTorchNet(String prefix, String outLayerName = "",
@@ -78,10 +75,8 @@ static void runTorchNet(String prefix, String outLayerName = "",
 {
     String suffix = (isBinary) ? ".dat" : ".txt";
 
-    Net net;
-    Ptr<Importer> importer = createTorchImporter(_tf(prefix + "_net" + suffix), isBinary);
-    ASSERT_TRUE(importer != NULL);
-    importer->populateNet(net);
+    Net net = readNetFromTorch(_tf(prefix + "_net" + suffix), isBinary);
+    ASSERT_FALSE(net.empty());
 
     Mat inp, outRef;
     ASSERT_NO_THROW( inp = readTorchBlob(_tf(prefix + "_input" + suffix), isBinary) );
@@ -200,9 +195,8 @@ TEST(Torch_Importer, ENet_accuracy)
     Net net;
     {
         const string model = findDataFile("dnn/Enet-model-best.net", false);
-        Ptr<Importer> importer = createTorchImporter(model, true);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromTorch(model, true);
+        ASSERT_FALSE(net.empty());
     }
 
     Mat sample = imread(_tf("street.png", false));
index 2f49eb2..37c4af2 100644 (file)
@@ -413,7 +413,12 @@ endif(ANDROID)
 
 # workarounding lack of `__attribute__ ((visibility("default")))` in jni_md.h/JNIEXPORT
 string(REPLACE "-fvisibility=hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-const-variable -Wundef)
+if(MSVC)
+  ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4996)
+else()
+  ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-const-variable -Wundef -Wdeprecated-declarations)
+endif()
+
 
 ocv_add_library(${the_module} SHARED ${handwritten_h_sources} ${handwritten_cpp_sources} ${generated_cpp_sources}
                                  ${copied_files}
index 37e20fe..bf55ef8 100644 (file)
@@ -13,3 +13,9 @@ include(../common.cmake)
 
 unset(MODULE_NAME)
 unset(MODULE_INSTALL_SUBDIR)
+
+if(MSVC)
+  ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4996)
+else()
+  ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-declarations)
+endif()
index da86ba5..b3a7253 100644 (file)
@@ -12,3 +12,9 @@ include(../common.cmake)
 
 unset(MODULE_NAME)
 unset(MODULE_INSTALL_SUBDIR)
+
+if(MSVC)
+  ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4996)
+else()
+  ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-declarations)
+endif()
index 0999a43..61afe6a 100755 (executable)
@@ -410,7 +410,8 @@ class CppHeaderParser(object):
         # note that we do not strip "static" prefix, which does matter;
         # it means class methods, not instance methods
         decl_str = self.batch_replace(decl_str, [("virtual", ""), ("static inline", ""), ("inline", ""),\
-            ("CV_EXPORTS_W", ""), ("CV_EXPORTS", ""), ("CV_CDECL", ""), ("CV_WRAP ", " "), ("CV_INLINE", "")]).strip()
+            ("CV_EXPORTS_W", ""), ("CV_EXPORTS", ""), ("CV_CDECL", ""), ("CV_WRAP ", " "), ("CV_INLINE", ""),
+            ("CV_DEPRECATED", "")]).strip()
 
         static_method = False
         context = top[0]
index e8ae04e..94ff267 100644 (file)
@@ -91,19 +91,11 @@ int main(int argc, char **argv)
 
     vector<cv::Vec3b> colors = readColors();
 
-    //! [Create the importer of Caffe model]
-    Ptr<dnn::Importer> importer;
-    try                                     //Try to import Caffe GoogleNet model
-    {
-        importer = dnn::createCaffeImporter(modelTxt, modelBin);
-    }
-    catch (const cv::Exception &err)        //Importer can throw errors, we will catch them
-    {
-        cerr << err.msg << endl;
-    }
-    //! [Create the importer of Caffe model]
+    //! [Initialize network]
+    dnn::Net net = readNetFromCaffe(modelTxt, modelBin);
+    //! [Initialize network]
 
-    if (!importer)
+    if (net.empty())
     {
         cerr << "Can't load network by using the following files: " << endl;
         cerr << "prototxt:   " << modelTxt << endl;
@@ -113,12 +105,6 @@ int main(int argc, char **argv)
         exit(-1);
     }
 
-    //! [Initialize network]
-    dnn::Net net;
-    importer->populateNet(net);
-    importer.release();                     //We don't need importer anymore
-    //! [Initialize network]
-
     //! [Prepare blob]
     Mat img = imread(imageFile);
     if (img.empty())
index 7a51d3d..214dd91 100644 (file)
@@ -65,21 +65,11 @@ int main(int argc, char** argv)
     String modelConfiguration = parser.get<string>("proto");
     String modelBinary = parser.get<string>("model");
 
-    //! [Create the importer of Caffe model]
-    Ptr<dnn::Importer> importer;
-
-    // Import Caffe SSD model
-    try
-    {
-        importer = dnn::createCaffeImporter(modelConfiguration, modelBinary);
-    }
-    catch (const cv::Exception &err) //Importer can throw errors, we will catch them
-    {
-        cerr << err.msg << endl;
-    }
-    //! [Create the importer of Caffe model]
+    //! [Initialize network]
+    dnn::Net net = readNetFromCaffe(modelConfiguration, modelBinary);
+    //! [Initialize network]
 
-    if (!importer)
+    if (net.empty())
     {
         cerr << "Can't load network by using the following files: " << endl;
         cerr << "prototxt:   " << modelConfiguration << endl;
@@ -89,12 +79,6 @@ int main(int argc, char** argv)
         exit(-1);
     }
 
-    //! [Initialize network]
-    dnn::Net net;
-    importer->populateNet(net);
-    importer.release();          //We don't need importer anymore
-    //! [Initialize network]
-
     cv::Mat frame = cv::imread(parser.get<string>("image"), -1);
 
     if (frame.channels() == 4)
index 44af4ce..f184d39 100644 (file)
@@ -59,31 +59,17 @@ int main(int argc, char **argv)
     String classNamesFile = parser.get<String>("c_names");
     String resultFile = parser.get<String>("result");
 
-    //! [Create the importer of TensorFlow model]
-    Ptr<dnn::Importer> importer;
-    try                                     //Try to import TensorFlow AlexNet model
-    {
-        importer = dnn::createTensorflowImporter(modelFile);
-    }
-    catch (const cv::Exception &err)        //Importer can throw errors, we will catch them
-    {
-        std::cerr << err.msg << std::endl;
-    }
-    //! [Create the importer of Caffe model]
+    //! [Initialize network]
+    dnn::Net net = readNetFromTensorflow(modelFile);
+    //! [Initialize network]
 
-    if (!importer)
+    if (net.empty())
     {
         std::cerr << "Can't load network by using the mode file: " << std::endl;
         std::cerr << modelFile << std::endl;
         exit(-1);
     }
 
-    //! [Initialize network]
-    dnn::Net net;
-    importer->populateNet(net);
-    importer.release();                     //We don't need importer anymore
-    //! [Initialize network]
-
     //! [Prepare blob]
     Mat img = imread(imageFile);
     if (img.empty())