From 6d3cb8080c8d9f54b8af23a08b78e56a1609cbce Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Thu, 16 Jun 2016 21:03:51 +0300 Subject: [PATCH] Refinement of BlobShape API explicit BlobShape(int,int) constructor was removed BlobShape::all(int, int) substitutes explicit BlobShape(int,int) added new intuitive constructors: BlobShape(s0); BlobShape(s0, s1)... added corresponding tests --- modules/dnn/include/opencv2/dnn/blob.hpp | 12 +++++-- modules/dnn/include/opencv2/dnn/blob.inl.hpp | 34 ++++++++++++++++++-- modules/dnn/src/blob.cpp | 2 +- modules/dnn/src/caffe/caffe_importer.cpp | 4 +-- modules/dnn/src/layers/op_blas.cpp | 5 +-- modules/dnn/src/layers/reshape_layer.cpp | 6 ++-- modules/dnn/test/test_layers.cpp | 16 ++++----- modules/dnn/test/test_main.cpp | 28 ++++++++++++++++ 8 files changed, 87 insertions(+), 20 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/blob.hpp b/modules/dnn/include/opencv2/dnn/blob.hpp index bc582c83b..ee67990c2 100644 --- a/modules/dnn/include/opencv2/dnn/blob.hpp +++ b/modules/dnn/include/opencv2/dnn/blob.hpp @@ -55,13 +55,21 @@ namespace dnn /** @brief Lightweight class for storing and processing a shape of blob (or anything else). */ struct BlobShape { - explicit BlobShape(int ndims = 4, int fill = 1); //!< Creates n-dim shape and fill its by @p fill + BlobShape(); //!< Returns @ref all(4, 1) + BlobShape(int s0); //!< Creates 1-dim shape [@p s0] + BlobShape(int s0, int s1); //!< @overload + BlobShape(int s0, int s1, int s2); //!< @overload BlobShape(int num, int cn, int rows, int cols); //!< Creates 4-dim shape [@p num, @p cn, @p rows, @p cols] - BlobShape(int ndims, const int *sizes); //!< Creates n-dim shape from the @p sizes array + + //! Creates n-dim shape from the @p sizes array; if @p sizes is NULL then shape will contain unspecified data + BlobShape(int ndims, const int *sizes); BlobShape(const std::vector &sizes); //!< Creates n-dim shape from the @p sizes vector template BlobShape(const Vec &shape); //!< Creates n-dim shape from @ref cv::Vec + //! Creates n-dim shape and fill its by @p fill + static BlobShape all(int ndims, int fill = 1); + /** @brief Returns number of dimensions. */ int dims() const; diff --git a/modules/dnn/include/opencv2/dnn/blob.inl.hpp b/modules/dnn/include/opencv2/dnn/blob.inl.hpp index 4a6de4804..e1e719393 100644 --- a/modules/dnn/include/opencv2/dnn/blob.inl.hpp +++ b/modules/dnn/include/opencv2/dnn/blob.inl.hpp @@ -48,20 +48,50 @@ namespace cv namespace dnn { -inline BlobShape::BlobShape(int ndims, int fill) : sz( (size_t)std::max(ndims, 0) ) +inline BlobShape::BlobShape() +{ + sz.allocate(4); + for (size_t i = 0; i < sz.size(); i++) + sz[i] = 1; +} + +inline BlobShape BlobShape::all(int ndims, int fill) { CV_Assert(ndims >= 0); + BlobShape res; + res.sz.allocate(ndims); for (int i = 0; i < ndims; i++) - sz[i] = fill; + res.sz[i] = fill; + return res; } inline BlobShape::BlobShape(int ndims, const int *sizes) : sz( (size_t)std::max(ndims, 0) ) { CV_Assert(ndims >= 0); + if (!sizes) + return; for (int i = 0; i < ndims; i++) sz[i] = sizes[i]; } +inline BlobShape::BlobShape(int s0) : sz(1) +{ + sz[0] = s0; +} + +inline BlobShape::BlobShape(int s0, int s1) : sz(2) +{ + sz[0] = s0; + sz[1] = s1; +} + +inline BlobShape::BlobShape(int s0, int s1, int s2) : sz(3) +{ + sz[0] = s0; + sz[1] = s1; + sz[2] = s2; +} + inline BlobShape::BlobShape(int num, int cn, int rows, int cols) : sz(4) { sz[0] = num; diff --git a/modules/dnn/src/blob.cpp b/modules/dnn/src/blob.cpp index 9aa803f8c..fe86d4300 100644 --- a/modules/dnn/src/blob.cpp +++ b/modules/dnn/src/blob.cpp @@ -59,7 +59,7 @@ namespace dnn static BlobShape getBlobShape(std::vector &vmat, int requestedCn = -1) { - BlobShape shape(4); + BlobShape shape(BlobShape::all(4)); int cnSum = 0, matCn; CV_Assert(vmat.size() > 0); diff --git a/modules/dnn/src/caffe/caffe_importer.cpp b/modules/dnn/src/caffe/caffe_importer.cpp index 59a656f5c..551c93771 100644 --- a/modules/dnn/src/caffe/caffe_importer.cpp +++ b/modules/dnn/src/caffe/caffe_importer.cpp @@ -191,7 +191,7 @@ namespace else if (pbBlob.has_shape()) { const caffe::BlobShape &_shape = pbBlob.shape(); - BlobShape shape(_shape.dim_size()); + BlobShape shape = BlobShape::all(_shape.dim_size()); for (int i = 0; i < _shape.dim_size(); i++) shape[i] = (int)_shape.dim(i); @@ -201,7 +201,7 @@ namespace else { CV_Error(Error::StsError, "Unknown shape of input blob"); - return BlobShape(-1); + return BlobShape(); } } diff --git a/modules/dnn/src/layers/op_blas.cpp b/modules/dnn/src/layers/op_blas.cpp index 2995017d1..86f33fb2e 100644 --- a/modules/dnn/src/layers/op_blas.cpp +++ b/modules/dnn/src/layers/op_blas.cpp @@ -76,9 +76,10 @@ void setBlasThreads(int numThreads) openblas_set_num_threads(numThreads); goto_set_num_threads(numThreads); #else - numThreads = 0; //suppress compiler's warning + (void)numThreads; //suppress compilers' warning + numThreads = 0; #endif } } -} \ No newline at end of file +} diff --git a/modules/dnn/src/layers/reshape_layer.cpp b/modules/dnn/src/layers/reshape_layer.cpp index f5d4b1c21..d302c2414 100644 --- a/modules/dnn/src/layers/reshape_layer.cpp +++ b/modules/dnn/src/layers/reshape_layer.cpp @@ -58,12 +58,12 @@ ReshapeLayer::ReshapeLayer(LayerParams ¶ms) : Layer(params) if (!params.has("dim")) { - shapeDesc = BlobShape(0); + shapeDesc = BlobShape::all(0); return; } DictValue paramShape = params.get("dim"); - shapeDesc = BlobShape(paramShape.size()); + shapeDesc = BlobShape::all(paramShape.size()); for (int i = 0; i < paramShape.size(); i++) { @@ -97,7 +97,7 @@ void ReshapeLayer::allocate(const std::vector &inputs, std::vector CV_Assert(0 <= endAxis && endAxis <= inpShape.dims()); int newDims = inpShape.dims() - (endAxis - startAxis) + shapeDesc.dims(); - BlobShape outShape(newDims); + BlobShape outShape = BlobShape::all(newDims); computeOutputShape(startAxis, endAxis, inpShape, outShape); diff --git a/modules/dnn/test/test_layers.cpp b/modules/dnn/test/test_layers.cpp index 59f7bed01..d1e0cfe85 100644 --- a/modules/dnn/test/test_layers.cpp +++ b/modules/dnn/test/test_layers.cpp @@ -190,9 +190,9 @@ public: Nx = _Nx; Nc = _Nc; - Wh = Blob(BlobShape(Vec2i(4 * Nc, Nc))); - Wx = Blob(BlobShape(Vec2i(4 * Nc, Nx))); - b = Blob(BlobShape(Vec2i(4 * Nc, 1))); + Wh = Blob(BlobShape(4 * Nc, Nc)); + Wx = Blob(BlobShape(4 * Nc, Nx)); + b = Blob(BlobShape(4 * Nc, 1)); layer = LSTMLayer::create(); layer->setWeights(Wh, Wx, b); @@ -248,11 +248,11 @@ public: Nh = _Nh; No = _No; - Whh = Blob(BlobShape(Vec2i(Nh, Nh))); - Wxh = Blob(BlobShape(Vec2i(Nh, Nx))); - bh = Blob(BlobShape(Vec2i(Nh, 1))); - Who = Blob(BlobShape(Vec2i(No, Nh))); - bo = Blob(BlobShape(Vec2i(No, 1))); + Whh = Blob(BlobShape(Nh, Nh)); + Wxh = Blob(BlobShape(Nh, Nx)); + bh = Blob(BlobShape(Nh, 1)); + Who = Blob(BlobShape(No, Nh)); + bo = Blob(BlobShape(No, 1)); layer = RNNLayer::create(); layer->setWeights(Whh, Wxh, bh, Who, bo); diff --git a/modules/dnn/test/test_main.cpp b/modules/dnn/test/test_main.cpp index 6f9ac2e0d..42917f299 100644 --- a/modules/dnn/test/test_main.cpp +++ b/modules/dnn/test/test_main.cpp @@ -1,3 +1,31 @@ #include "test_precomp.hpp" CV_TEST_MAIN("") + +namespace cvtest +{ + +using namespace cv; +using namespace cv::dnn; + +TEST(BlobShape_SimpleConstr, Regression) +{ + BlobShape sd; + + BlobShape s1(0); + EXPECT_EQ(s1.dims(), 1); + EXPECT_EQ(s1[0], 0); + + BlobShape s2(0, 0); + EXPECT_EQ(s2.dims(), 2); + EXPECT_EQ(s2[0], 0); + EXPECT_EQ(s2[1], 0); +} + +TEST(BlobShape_EmptyFill, Regression) +{ + BlobShape s(10, (int*)NULL); + EXPECT_EQ(s.dims(), 10); +} + +}