_InputArray(const UMat& um);
_InputArray(const std::vector<UMat>& umv);
-#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _Nm> _InputArray(const std::array<_Tp, _Nm>& arr);
template<std::size_t _Nm> _InputArray(const std::array<Mat, _Nm>& arr);
-#endif
-#ifdef CV_CXX_STD_ARRAY
+ template<typename _Tp> static _InputArray rawIn(const std::vector<_Tp>& vec);
-#endif
+ template<typename _Tp, std::size_t _Nm> static _InputArray rawIn(const std::array<_Tp, _Nm>& arr);
+
Mat getMat(int idx=-1) const;
Mat getMat_(int idx=-1) const;
UMat getUMat(int idx=-1) const;
_OutputArray(const UMat& m);
_OutputArray(const std::vector<UMat>& vec);
--#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _Nm> _OutputArray(std::array<_Tp, _Nm>& arr);
template<typename _Tp, std::size_t _Nm> _OutputArray(const std::array<_Tp, _Nm>& arr);
template<std::size_t _Nm> _OutputArray(std::array<Mat, _Nm>& arr);
template<std::size_t _Nm> _OutputArray(const std::array<Mat, _Nm>& arr);
--#endif
+
+ template<typename _Tp> static _OutputArray rawOut(std::vector<_Tp>& vec);
-#ifdef CV_CXX_STD_ARRAY
+ template<typename _Tp, std::size_t _Nm> static _OutputArray rawOut(std::array<_Tp, _Nm>& arr);
-#endif
bool fixedSize() const;
bool fixedType() const;
_InputOutputArray(const UMat& m);
_InputOutputArray(const std::vector<UMat>& vec);
--#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _Nm> _InputOutputArray(std::array<_Tp, _Nm>& arr);
template<typename _Tp, std::size_t _Nm> _InputOutputArray(const std::array<_Tp, _Nm>& arr);
template<std::size_t _Nm> _InputOutputArray(std::array<Mat, _Nm>& arr);
template<std::size_t _Nm> _InputOutputArray(const std::array<Mat, _Nm>& arr);
--#endif
+
+ template<typename _Tp> static _InputOutputArray rawInOut(std::vector<_Tp>& vec);
-#ifdef CV_CXX_STD_ARRAY
+ template<typename _Tp, std::size_t _Nm> _InputOutputArray rawInOut(std::array<_Tp, _Nm>& arr);
-#endif
};
/** @overload
*/
template<typename _Tp> explicit Mat(const std::initializer_list<int> sizes, const std::initializer_list<_Tp> list);
-#endif
--#ifdef CV_CXX_STD_ARRAY
/** @overload
*/
template<typename _Tp, size_t _Nm> explicit Mat(const std::array<_Tp, _Nm>& arr, bool copyData=false);
--#endif
/** @overload
*/
template<typename _Tp, int n> operator Vec<_Tp, n>() const;
template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
--#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _Nm> operator std::array<_Tp, _Nm>() const;
--#endif
/** @brief Reports whether the matrix is continuous or not.
explicit Mat_(const Point3_<typename DataType<_Tp>::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<int> sizes, const std::initializer_list<_Tp> values);
-#endif
--#ifdef CV_CXX_STD_ARRAY
template <std::size_t _Nm> explicit Mat_(const std::array<_Tp, _Nm>& arr, bool copyData=false);
--#endif
Mat_& operator = (const Mat& m);
Mat_& operator = (const Mat_& m);
//! conversion to vector.
operator std::vector<_Tp>() const;
--#ifdef CV_CXX_STD_ARRAY
//! conversion to array.
template<std::size_t _Nm> operator std::array<_Tp, _Nm>() const;
--#endif
//! conversion to Vec
template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
{ init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
-#ifdef CV_CXX_STD_ARRAY
+ template<typename _Tp> 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;
+ }
+
-#endif
+ template<typename _Tp, std::size_t _Nm> 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;
+ }
+
inline _InputArray::~_InputArray() {}
inline Mat _InputArray::getMat(int i) const
inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
-#ifdef CV_CXX_STD_ARRAY
+ template<typename _Tp> 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;
+ }
+
-#endif
+ template<typename _Tp, std::size_t _Nm> 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;
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////
inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
-#ifdef CV_CXX_STD_ARRAY
+ template<typename _Tp> 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;
+ }
+
-#endif
+ template<typename _Tp, std::size_t _Nm> 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;
+ }
+
+
+ template<typename _Tp> static inline _InputArray rawIn(_Tp& v) { return _InputArray::rawIn(v); }
+ template<typename _Tp> static inline _OutputArray rawOut(_Tp& v) { return _OutputArray::rawOut(v); }
+ template<typename _Tp> static inline _InputOutputArray rawInOut(_Tp& v) { return _InputOutputArray::rawInOut(v); }
+
CV__DEBUG_NS_END
//////////////////////////////////////////// Mat //////////////////////////////////////////
}
}
-CV__DNN_EXPERIMENTAL_NS_END
+ static void permute(google::protobuf::RepeatedPtrField<tensorflow::NodeDef>* data,
+ const std::vector<int>& indices)
+ {
+ const int num = data->size();
+ CV_Assert(num == indices.size());
+
+ std::vector<int> elemIdToPos(num);
+ std::vector<int> 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<std::string, int> nodesMap;
+ std::map<std::string, int>::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<std::vector<int> > edges(nodesMap.size());
+ std::vector<int> numRefsToAdd(nodesMap.size(), 0);
+ std::vector<int> 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<int> 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_INLINE_NS_END
}} // namespace dnn, namespace cv
#endif // HAVE_PROTOBUF
void releaseTensor(tensorflow::TensorProto* tensor);
-CV__DNN_EXPERIMENTAL_NS_END
+ void sortByExecutionOrder(tensorflow::GraphDef& net);
+
+CV__DNN_INLINE_NS_END
}} // namespace dnn, namespace cv
#endif // HAVE_PROTOBUF
bufferConfigPtr, bufferConfig.size());
}
-CV__DNN_EXPERIMENTAL_NS_END
+ 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<tensorflow::NodeDef>::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_INLINE_NS_END
}} // namespace
#ifndef __OPENCV_TEST_COMMON_HPP__
#define __OPENCV_TEST_COMMON_HPP__
-CV__DNN_EXPERIMENTAL_NS_BEGIN
+ #ifdef HAVE_OPENCL
+ #include "opencv2/core/ocl.hpp"
+ #endif
+
+ namespace cv { namespace dnn {
-CV__DNN_EXPERIMENTAL_NS_END
++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<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
+ {
+ PrintTo(get<0>(v), os);
+ *os << "/";
+ PrintTo(get<1>(v), os);
+ }
+
++CV__DNN_INLINE_NS_END
+ }} // namespace
+
+
static inline const std::string &getOpenCVExtraDir()
{
return cvtest::TS::ptr()->get_data_path();