Merge remote-tracking branch 'upstream/3.4' into merge-3.4
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Fri, 5 Apr 2019 19:02:24 +0000 (19:02 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Fri, 5 Apr 2019 19:08:23 +0000 (19:08 +0000)
12 files changed:
1  2 
doc/CMakeLists.txt
doc/tutorials/calib3d/camera_calibration_pattern/camera_calibration_pattern.markdown
doc/tutorials/gpu/gpu-basics-similarity/gpu_basics_similarity.markdown
doc/tutorials/introduction/android_binary_package/O4A_SDK.markdown
doc/tutorials/introduction/clojure_dev_intro/clojure_dev_intro.markdown
doc/tutorials/ml/introduction_to_svm/introduction_to_svm.markdown
doc/tutorials/ml/non_linear_svms/non_linear_svms.markdown
modules/dnn/src/tensorflow/tf_graph_simplifier.cpp
modules/dnn/src/tensorflow/tf_graph_simplifier.hpp
modules/dnn/src/tensorflow/tf_importer.cpp
modules/imgcodecs/src/grfmt_tiff.cpp
samples/cpp/matchmethod_orb_akaze_brisk.cpp

Simple merge
@@@ -71,7 -83,7 +71,7 @@@ The structure of package contents look
  
  -   `doc` folder contains various OpenCV documentation in PDF format. It's also available online at
      <http://docs.opencv.org>.
-     @note The most recent docs (nightly build) are at <http://docs.opencv.org/2.4>. Generally, it's more
 -    @note The most recent docs (nightly build) are at <http://docs.opencv.org/3.4>. Generally, it's more
++    @note The most recent docs (nightly build) are at <http://docs.opencv.org/master>. Generally, it's more
      up-to-date, but can refer to not-yet-released functionality.
      @todo I'm not sure that this is the best place to talk about OpenCV Manager
  
@@@ -302,7 -302,7 +302,7 @@@ Then you can start interacting with Ope
  classes.
  
  @note
- [Here](http://docs.opencv.org/java/) you can find the full OpenCV Java API.
 -[Here](https://docs.opencv.org/3.4/javadoc/index.html) you can find the full OpenCV Java API.
++[Here](https://docs.opencv.org/master/javadoc/index.html) you can find the full OpenCV Java API.
  
  @code{.clojure}
  user=> (org.opencv.core.Point. 0 0)
@@@ -94,11 -94,9 +94,9 @@@ the weight vector \f$\beta\f$ and the b
  Source Code
  -----------
  
- @note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html#introductiontosvms)
  @add_toggle_cpp
  -   **Downloadable code**: Click
 -    [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp)
 +    [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp)
  
  -   **Code at glance:**
      @include samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp
@@@ -87,14 -87,11 +87,11 @@@ Source Cod
  -----------
  
  You may also find the source code in `samples/cpp/tutorial_code/ml/non_linear_svms` folder of the OpenCV source library or
 -[download it from here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp).
 +[download it from here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp).
  
- @note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code
- using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/non_linear_svms/non_linear_svms.html#nonlinearsvms)
  @add_toggle_cpp
  -   **Downloadable code**: Click
 -    [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp)
 +    [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp)
  
  -   **Code at glance:**
      @include samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp
  #ifdef HAVE_PROTOBUF
  
  #include "tf_graph_simplifier.hpp"
+ #include <queue>
  
  namespace cv { namespace dnn {
 -CV__DNN_EXPERIMENTAL_NS_BEGIN
 +CV__DNN_INLINE_NS_BEGIN
  
  using ::google::protobuf::RepeatedField;
  using ::google::protobuf::MapPair;
@@@ -902,7 -902,86 +902,86 @@@ void sortByExecutionOrder(tensorflow::G
      permute(net.mutable_node(), permIds);
  }
  
 -CV__DNN_EXPERIMENTAL_NS_END
+ // Remove training switches (Switch and Merge nodes and corresponding subgraphs).
+ void removePhaseSwitches(tensorflow::GraphDef& net)
+ {
+     std::vector<int> nodesToRemove;
+     std::map<std::string, int> nodesMap;
+     std::map<std::string, int>::iterator nodesMapIt;
+     std::queue<int> mergeOpSubgraphNodes;
+     for (int i = 0; i < net.node_size(); ++i)
+     {
+         const tensorflow::NodeDef& node = net.node(i);
+         nodesMap.insert(std::make_pair(node.name(), i));
+         if (node.op() == "Switch" || node.op() == "Merge")
+         {
+             CV_Assert(node.input_size() > 0);
+             // Replace consumers' inputs.
+             for (int j = 0; j < net.node_size(); ++j)
+             {
+                 tensorflow::NodeDef* consumer = net.mutable_node(j);
+                 for (int k = 0; k < consumer->input_size(); ++k)
+                 {
+                     std::string inpName = consumer->input(k);
+                     inpName = inpName.substr(0, inpName.rfind(':'));
+                     if (inpName == node.name())
+                     {
+                         consumer->set_input(k, node.input(0));
+                     }
+                 }
+             }
+             nodesToRemove.push_back(i);
+             if (node.op() == "Merge")
+                 mergeOpSubgraphNodes.push(i);
+         }
+     }
+     std::vector<int> numConsumers(net.node_size(), 0);
+     for (int i = 0; i < net.node_size(); ++i)
+     {
+         const tensorflow::NodeDef& node = net.node(i);
+         for (int j = 0; j < node.input_size(); ++j)
+         {
+             std::string inpName = node.input(j);
+             inpName = inpName.substr(1 + (int)inpName.find('^'), inpName.rfind(':'));
+             nodesMapIt = nodesMap.find(inpName);
+             CV_Assert(nodesMapIt != nodesMap.end());
+             numConsumers[nodesMapIt->second] += 1;
+         }
+     }
+     // Remove subgraphs of unused nodes which are terminated by Merge nodes.
+     while (!mergeOpSubgraphNodes.empty())
+     {
+         const tensorflow::NodeDef& node = net.node(mergeOpSubgraphNodes.front());
+         mergeOpSubgraphNodes.pop();
+         for (int i = 0; i < node.input_size(); ++i)
+         {
+             std::string inpName = node.input(i);
+             inpName = inpName.substr(1 + (int)inpName.find('^'), inpName.rfind(':'));
+             nodesMapIt = nodesMap.find(inpName);
+             CV_Assert(nodesMapIt != nodesMap.end());
+             int inpNodeId = nodesMapIt->second;
+             if (numConsumers[inpNodeId] == 1)
+             {
+                 mergeOpSubgraphNodes.push(inpNodeId);
+                 nodesToRemove.push_back(inpNodeId);
+             }
+             else if (numConsumers[inpNodeId] > 0)
+                 numConsumers[inpNodeId] -= 1;
+         }
+     }
+     std::sort(nodesToRemove.begin(), nodesToRemove.end());
+     for (int i = nodesToRemove.size() - 1; i >= 0; --i)
+     {
+         if (nodesToRemove[i] < net.node_size())  // Ids might be repeated.
+             net.mutable_node()->DeleteSubrange(nodesToRemove[i], 1);
+     }
+ }
 +CV__DNN_INLINE_NS_END
  }}  // namespace dnn, namespace cv
  
  #endif  // HAVE_PROTOBUF
@@@ -27,7 -27,9 +27,9 @@@ void releaseTensor(tensorflow::TensorPr
  
  void sortByExecutionOrder(tensorflow::GraphDef& net);
  
 -CV__DNN_EXPERIMENTAL_NS_END
+ void removePhaseSwitches(tensorflow::GraphDef& net);
 +CV__DNN_INLINE_NS_END
  }}  // namespace dnn, namespace cv
  
  #endif  // HAVE_PROTOBUF
Simple merge
@@@ -24,11 -24,11 +24,11 @@@ int main(int argc, char *argv[]
      vector<String> typeAlgoMatch;
      vector<String> fileName;
      // This descriptor are going to be detect and compute
-     typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT");    // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
-     typeDesc.push_back("AKAZE");    // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
-     typeDesc.push_back("ORB");      // see http://docs.opencv.org/trunk/de/dbf/classcv_1_1BRISK.html
-     typeDesc.push_back("BRISK");    // see http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html
-     // This algorithm would be used to match descriptors see http://docs.opencv.org/trunk/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
 -    typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT");    // see https://docs.opencv.org/3.4/d8/d30/classcv_1_1AKAZE.html
 -    typeDesc.push_back("AKAZE");    // see http://docs.opencv.org/3.4/d8/d30/classcv_1_1AKAZE.html
 -    typeDesc.push_back("ORB");      // see http://docs.opencv.org/3.4/de/dbf/classcv_1_1BRISK.html
 -    typeDesc.push_back("BRISK");    // see http://docs.opencv.org/3.4/db/d95/classcv_1_1ORB.html
 -    // This algorithm would be used to match descriptors see http://docs.opencv.org/3.4/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
++    typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT");    // see https://docs.opencv.org/master/d8/d30/classcv_1_1AKAZE.html
++    typeDesc.push_back("AKAZE");    // see http://docs.opencv.org/master/d8/d30/classcv_1_1AKAZE.html
++    typeDesc.push_back("ORB");      // see http://docs.opencv.org/master/de/dbf/classcv_1_1BRISK.html
++    typeDesc.push_back("BRISK");    // see http://docs.opencv.org/master/db/d95/classcv_1_1ORB.html
++    // This algorithm would be used to match descriptors see http://docs.opencv.org/master/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
      typeAlgoMatch.push_back("BruteForce");
      typeAlgoMatch.push_back("BruteForce-L1");
      typeAlgoMatch.push_back("BruteForce-Hamming");