From b67523550f7c130332e5b5e538397897b195cb98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Ratajczak?= Date: Mon, 12 Feb 2018 12:51:07 +0100 Subject: [PATCH] dnn : Added an imagesFromBlob method to the dnn module (#10607) * Added the imagesFromBlob method to the dnn module. * Rewritten imagesFromBlob based on first dkurt comments * Updated code with getPlane() * Modify comment of imagesFromBlob() in dnn module * modified comments, removed useless assertions & added OutputArrayOfArray * replaced tabs with whitespaces & put vectorOfChannels instantiation outside the loop * Changed pre-commit.sample to pre-commit in .git/hooks/ * Added a test for imagesFromBlob in test_misc.cpp (dnn) * Changed nbOfImages, robustified test with cv::randu, modified assertion --- modules/dnn/include/opencv2/dnn/dnn.hpp | 9 +++++++++ modules/dnn/src/dnn.cpp | 25 +++++++++++++++++++++++++ modules/dnn/test/test_misc.cpp | 21 +++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index a31730c57f..15c41b3079 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -735,6 +735,15 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN double scalefactor=1.0, Size size = Size(), const Scalar& mean = Scalar(), bool swapRB=true, bool crop=true); + /** @brief Parse a 4D blob and output the images it contains as 2D arrays through a simpler data structure + * (std::vector). + * @param[in] blob_ 4 dimensional array (images, channels, height, width) in floating point precision (CV_32F) from + * which you would like to extract the images. + * @param[out] images_ array of 2D Mat containing the images extracted from the blob in floating point precision + * (CV_32F). They are non normalized neither mean added. The number of returned images equals the first dimension + * of the blob (batch size). Every image has a number of channels equals to the second dimension of the blob (depth). + */ + CV_EXPORTS_W void imagesFromBlob(const cv::Mat& blob_, OutputArrayOfArrays images_); /** @brief Convert all weights of Caffe network to half precision floating point. * @param src Path to origin model from Caffe framework contains single diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 7cc44da2b5..be4767b28a 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -192,6 +192,31 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef } } +void imagesFromBlob(const cv::Mat& blob_, OutputArrayOfArrays images_) +{ + CV_TRACE_FUNCTION(); + + //A blob is a 4 dimensional matrix in floating point precision + //blob_[0] = batchSize = nbOfImages + //blob_[1] = nbOfChannels + //blob_[2] = height + //blob_[3] = width + CV_Assert(blob_.depth() == CV_32F); + CV_Assert(blob_.dims == 4); + + images_.create(cv::Size(1, blob_.size[0]), blob_.depth()); + + std::vector vectorOfChannels(blob_.size[1]); + for (int n = 0; n < blob_.size[0]; ++n) + { + for (int c = 0; c < blob_.size[1]; ++c) + { + vectorOfChannels[c] = getPlane(blob_, n, c); + } + cv::merge(vectorOfChannels, images_.getMatRef(n)); + } +} + class OpenCLBackendWrapper : public BackendWrapper { public: diff --git a/modules/dnn/test/test_misc.cpp b/modules/dnn/test/test_misc.cpp index 5241c441bb..57aa7a9c0f 100644 --- a/modules/dnn/test/test_misc.cpp +++ b/modules/dnn/test/test_misc.cpp @@ -36,4 +36,25 @@ TEST(blobFromImage, allocated) ASSERT_EQ(blobData, blob.data); } +TEST(imagesFromBlob, Regression) +{ + int nbOfImages = 8; + + std::vector inputImgs(nbOfImages); + for (int i = 0; i < nbOfImages; i++) + { + inputImgs[i] = cv::Mat::ones(100, 100, CV_32FC3); + cv::randu(inputImgs[i], cv::Scalar::all(0), cv::Scalar::all(1)); + } + + cv::Mat blob = cv::dnn::blobFromImages(inputImgs, 1., cv::Size(), cv::Scalar(), false, false); + std::vector outputImgs; + cv::dnn::imagesFromBlob(blob, outputImgs); + + for (int i = 0; i < nbOfImages; i++) + { + ASSERT_EQ(cv::countNonZero(inputImgs[i] != outputImgs[i]), 0); + } +} + }} // namespace