From: Alexander Alekhin Date: Tue, 4 Sep 2018 16:35:38 +0000 (+0300) Subject: Merge remote-tracking branch 'upstream/3.4' into merge-3.4 X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~1^2~568 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d74b98c3d9264f9623b27a8d4e0fc92ac97b71d0;p=platform%2Fupstream%2Fopencv.git Merge remote-tracking branch 'upstream/3.4' into merge-3.4 --- d74b98c3d9264f9623b27a8d4e0fc92ac97b71d0 diff --cc modules/core/include/opencv2/core/mat.hpp index 1884abd,c0893b3..d918ee9 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@@ -196,9 -204,16 +202,12 @@@ public _InputArray(const UMat& um); _InputArray(const std::vector& umv); -#ifdef CV_CXX_STD_ARRAY template _InputArray(const std::array<_Tp, _Nm>& arr); template _InputArray(const std::array& arr); -#endif + template static _InputArray rawIn(const std::vector<_Tp>& vec); -#ifdef CV_CXX_STD_ARRAY + template static _InputArray rawIn(const std::array<_Tp, _Nm>& arr); -#endif + Mat getMat(int idx=-1) const; Mat getMat_(int idx=-1) const; UMat getUMat(int idx=-1) const; @@@ -328,12 -343,17 +337,13 @@@ public _OutputArray(const UMat& m); _OutputArray(const std::vector& vec); --#ifdef CV_CXX_STD_ARRAY template _OutputArray(std::array<_Tp, _Nm>& arr); template _OutputArray(const std::array<_Tp, _Nm>& arr); template _OutputArray(std::array& arr); template _OutputArray(const std::array& arr); --#endif + + template static _OutputArray rawOut(std::vector<_Tp>& vec); -#ifdef CV_CXX_STD_ARRAY + template static _OutputArray rawOut(std::array<_Tp, _Nm>& arr); -#endif bool fixedSize() const; bool fixedType() const; @@@ -397,12 -417,17 +407,13 @@@ public _InputOutputArray(const UMat& m); _InputOutputArray(const std::vector& vec); --#ifdef CV_CXX_STD_ARRAY template _InputOutputArray(std::array<_Tp, _Nm>& arr); template _InputOutputArray(const std::array<_Tp, _Nm>& arr); template _InputOutputArray(std::array& arr); template _InputOutputArray(const std::array& arr); --#endif + + template static _InputOutputArray rawInOut(std::vector<_Tp>& vec); -#ifdef CV_CXX_STD_ARRAY + template _InputOutputArray rawInOut(std::array<_Tp, _Nm>& arr); -#endif }; @@@ -990,12 -1023,13 +1008,10 @@@ public /** @overload */ template explicit Mat(const std::initializer_list sizes, const std::initializer_list<_Tp> list); -#endif --#ifdef CV_CXX_STD_ARRAY /** @overload */ template explicit Mat(const std::array<_Tp, _Nm>& arr, bool copyData=false); --#endif /** @overload */ @@@ -1630,9 -1664,9 +1646,7 @@@ template operator Vec<_Tp, n>() const; template operator Matx<_Tp, m, n>() const; --#ifdef CV_CXX_STD_ARRAY template operator std::array<_Tp, _Nm>() const; --#endif /** @brief Reports whether the matrix is continuous or not. @@@ -2211,12 -2247,14 +2225,10 @@@ public explicit Mat_(const Point3_::channel_type>& pt, bool copyData=true); explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); -#ifdef CV_CXX11 Mat_(std::initializer_list<_Tp> values); explicit Mat_(const std::initializer_list sizes, const std::initializer_list<_Tp> values); -#endif --#ifdef CV_CXX_STD_ARRAY template explicit Mat_(const std::array<_Tp, _Nm>& arr, bool copyData=false); --#endif Mat_& operator = (const Mat& m); Mat_& operator = (const Mat_& m); @@@ -2314,10 -2352,10 +2326,8 @@@ //! conversion to vector. operator std::vector<_Tp>() const; --#ifdef CV_CXX_STD_ARRAY //! conversion to array. template operator std::array<_Tp, _Nm>() const; --#endif //! conversion to Vec template operator Vec::channel_type, n>() const; diff --cc modules/core/include/opencv2/core/mat.inl.hpp index 609f4bd,a2e7923..d28a625 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@@ -134,6 -150,27 +144,25 @@@ inline _InputArray::_InputArray(const o inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem) { init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); } + template inline + _InputArray _InputArray::rawIn(const std::vector<_Tp>& vec) + { + _InputArray v; + v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_READ; + v.obj = (void*)&vec; + return v; + } + -#ifdef CV_CXX_STD_ARRAY + template inline + _InputArray _InputArray::rawIn(const std::array<_Tp, _Nm>& arr) + { + _InputArray v; + v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_READ; + v.obj = (void*)arr.data(); + v.sz = Size(1, _Nm); + return v; + } -#endif + inline _InputArray::~_InputArray() {} inline Mat _InputArray::getMat(int i) const @@@ -261,6 -310,27 +290,25 @@@ inline _OutputArray::_OutputArray(cons inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem) { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); } + template inline + _OutputArray _OutputArray::rawOut(std::vector<_Tp>& vec) + { + _OutputArray v; + v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_WRITE; + v.obj = (void*)&vec; + return v; + } + -#ifdef CV_CXX_STD_ARRAY + template inline + _OutputArray _OutputArray::rawOut(std::array<_Tp, _Nm>& arr) + { + _OutputArray v; + v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE; + v.obj = (void*)arr.data(); + v.sz = Size(1, _Nm); + return v; + } -#endif + /////////////////////////////////////////////////////////////////////////////////////////// inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); } @@@ -370,6 -447,32 +418,30 @@@ inline _InputOutputArray::_InputOutputA inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem) { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } + template inline + _InputOutputArray _InputOutputArray::rawInOut(std::vector<_Tp>& vec) + { + _InputOutputArray v; + v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_RW; + v.obj = (void*)&vec; + return v; + } + -#ifdef CV_CXX_STD_ARRAY + template inline + _InputOutputArray _InputOutputArray::rawInOut(std::array<_Tp, _Nm>& arr) + { + _InputOutputArray v; + v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW; + v.obj = (void*)arr.data(); + v.sz = Size(1, _Nm); + return v; + } -#endif + + + template static inline _InputArray rawIn(_Tp& v) { return _InputArray::rawIn(v); } + template static inline _OutputArray rawOut(_Tp& v) { return _OutputArray::rawOut(v); } + template static inline _InputOutputArray rawInOut(_Tp& v) { return _InputOutputArray::rawInOut(v); } + CV__DEBUG_NS_END //////////////////////////////////////////// Mat ////////////////////////////////////////// diff --cc modules/dnn/src/tensorflow/tf_graph_simplifier.cpp index 51a249e,2a34c25..28c0f4d --- a/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp +++ b/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp @@@ -782,7 -782,109 +782,109 @@@ void releaseTensor(tensorflow::TensorPr } } + static void permute(google::protobuf::RepeatedPtrField* data, + const std::vector& indices) + { + const int num = data->size(); + CV_Assert(num == indices.size()); + + std::vector elemIdToPos(num); + std::vector posToElemId(num); + for (int i = 0; i < num; ++i) + { + elemIdToPos[i] = i; + posToElemId[i] = i; + } + for (int i = 0; i < num; ++i) + { + int elemId = indices[i]; + int pos = elemIdToPos[elemId]; + if (pos != i) + { + data->SwapElements(i, pos); + const int swappedElemId = posToElemId[i]; + elemIdToPos[elemId] = i; + elemIdToPos[swappedElemId] = pos; + + posToElemId[i] = elemId; + posToElemId[pos] = swappedElemId; + } + } + } + + // Is based on tensorflow::graph_transforms::SortByExecutionOrder + void sortByExecutionOrder(tensorflow::GraphDef& net) + { + // Maps node's name to index at net.node() list. + std::map nodesMap; + std::map::iterator nodesMapIt; + for (int i = 0; i < net.node_size(); ++i) + { + const tensorflow::NodeDef& node = net.node(i); + nodesMap.insert(std::make_pair(node.name(), i)); + } + + // Indices of nodes which use specific node as input. + std::vector > edges(nodesMap.size()); + std::vector numRefsToAdd(nodesMap.size(), 0); + std::vector nodesToAdd; + 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(0, inpName.rfind(':')); + inpName = inpName.substr(inpName.find('^') + 1); + + nodesMapIt = nodesMap.find(inpName); + CV_Assert(nodesMapIt != nodesMap.end()); + edges[nodesMapIt->second].push_back(i); + } + if (node.input_size() == 0) + nodesToAdd.push_back(i); + else + { + if (node.op() == "Merge" || node.op() == "RefMerge") + { + int numControlEdges = 0; + for (int j = 0; j < node.input_size(); ++j) + numControlEdges += node.input(j)[0] == '^'; + numRefsToAdd[i] = numControlEdges + 1; + } + else + numRefsToAdd[i] = node.input_size(); + } + } + + std::vector permIds; + permIds.reserve(net.node_size()); + while (!nodesToAdd.empty()) + { + int nodeToAdd = nodesToAdd.back(); + nodesToAdd.pop_back(); + + permIds.push_back(nodeToAdd); + // std::cout << net.node(nodeToAdd).name() << '\n'; + + for (int i = 0; i < edges[nodeToAdd].size(); ++i) + { + int consumerId = edges[nodeToAdd][i]; + if (numRefsToAdd[consumerId] > 0) + { + if (numRefsToAdd[consumerId] == 1) + nodesToAdd.push_back(consumerId); + else + CV_Assert(numRefsToAdd[consumerId] >= 0); + numRefsToAdd[consumerId] -= 1; + } + } + } + CV_Assert(permIds.size() == net.node_size()); + permute(net.mutable_node(), permIds); + } + -CV__DNN_EXPERIMENTAL_NS_END +CV__DNN_INLINE_NS_END }} // namespace dnn, namespace cv #endif // HAVE_PROTOBUF diff --cc modules/dnn/src/tensorflow/tf_graph_simplifier.hpp index 8b76052,24c4bd5..a9c16c7 --- a/modules/dnn/src/tensorflow/tf_graph_simplifier.hpp +++ b/modules/dnn/src/tensorflow/tf_graph_simplifier.hpp @@@ -25,7 -25,9 +25,9 @@@ Mat getTensorContent(const tensorflow:: void releaseTensor(tensorflow::TensorProto* tensor); + void sortByExecutionOrder(tensorflow::GraphDef& net); + -CV__DNN_EXPERIMENTAL_NS_END +CV__DNN_INLINE_NS_END }} // namespace dnn, namespace cv #endif // HAVE_PROTOBUF diff --cc modules/dnn/src/tensorflow/tf_importer.cpp index 86596c1,6af22ea..145af36 --- a/modules/dnn/src/tensorflow/tf_importer.cpp +++ b/modules/dnn/src/tensorflow/tf_importer.cpp @@@ -1950,5 -1950,34 +1950,34 @@@ Net readNetFromTensorflow(const std::ve bufferConfigPtr, bufferConfig.size()); } + void writeTextGraph(const String& _model, const String& output) + { + String model = _model; + const std::string modelExt = model.substr(model.rfind('.') + 1); + if (modelExt != "pb") + CV_Error(Error::StsNotImplemented, "Only TensorFlow models support export to text file"); + + tensorflow::GraphDef net; + ReadTFNetParamsFromBinaryFileOrDie(model.c_str(), &net); + + sortByExecutionOrder(net); + + RepeatedPtrField::iterator it; + for (it = net.mutable_node()->begin(); it != net.mutable_node()->end(); ++it) + { + if (it->op() == "Const") + { + it->mutable_attr()->at("value").mutable_tensor()->clear_tensor_content(); + } + } + + std::string content; + google::protobuf::TextFormat::PrintToString(net, &content); + + std::ofstream ofs(output.c_str()); + ofs << content; + ofs.close(); + } + -CV__DNN_EXPERIMENTAL_NS_END +CV__DNN_INLINE_NS_END }} // namespace diff --cc modules/dnn/test/test_common.hpp index ec43f3e,2df422b..d3707a2 --- a/modules/dnn/test/test_common.hpp +++ b/modules/dnn/test/test_common.hpp @@@ -42,6 -42,47 +42,47 @@@ #ifndef __OPENCV_TEST_COMMON_HPP__ #define __OPENCV_TEST_COMMON_HPP__ + #ifdef HAVE_OPENCL + #include "opencv2/core/ocl.hpp" + #endif + + namespace cv { namespace dnn { -CV__DNN_EXPERIMENTAL_NS_BEGIN ++CV__DNN_INLINE_NS_BEGIN + static inline void PrintTo(const cv::dnn::Backend& v, std::ostream* os) + { + switch (v) { + case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return; + case DNN_BACKEND_HALIDE: *os << "HALIDE"; return; + case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE"; return; + case DNN_BACKEND_OPENCV: *os << "OCV"; return; + } // don't use "default:" to emit compiler warnings + *os << "DNN_BACKEND_UNKNOWN(" << v << ")"; + } + + static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os) + { + switch (v) { + case DNN_TARGET_CPU: *os << "CPU"; return; + case DNN_TARGET_OPENCL: *os << "OCL"; return; + case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return; + case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return; + } // don't use "default:" to emit compiler warnings + *os << "DNN_TARGET_UNKNOWN(" << v << ")"; + } + + using opencv_test::tuple; + using opencv_test::get; + static inline void PrintTo(const tuple v, std::ostream* os) + { + PrintTo(get<0>(v), os); + *os << "/"; + PrintTo(get<1>(v), os); + } + -CV__DNN_EXPERIMENTAL_NS_END ++CV__DNN_INLINE_NS_END + }} // namespace + + static inline const std::string &getOpenCVExtraDir() { return cvtest::TS::ptr()->get_data_path();