From 7420b5206e1ca21763568a72d28feaad1701a061 Mon Sep 17 00:00:00 2001 From: Sirish Date: Sat, 12 Dec 2020 12:12:46 +0530 Subject: [PATCH 1/4] Included gaussian blurring to augmentation --- augmentation/augmentation.hpp | 82 ++++++++++++++++++++++++++++-- augmentation/augmentation_impl.hpp | 56 ++++++++++++++++++-- 2 files changed, 132 insertions(+), 6 deletions(-) diff --git a/augmentation/augmentation.hpp b/augmentation/augmentation.hpp index de85c7b7..6112782b 100644 --- a/augmentation/augmentation.hpp +++ b/augmentation/augmentation.hpp @@ -1,6 +1,6 @@ /** * @file augmentation.hpp - * @author Kartik Dutt + * @author Kartik Dutt, Sirish * * Definition of Augmentation class for augmenting data. * @@ -105,6 +105,29 @@ class Augmentation const size_t datapointDepth, const std::string& augmentation); + + /** + * Applies gaussian blurring to the entire dataset. + * + * @tparam DatasetType Datatype on which augmentation will be done. + * + * @param dataset Dataset on which augmentation will be applied. + * @param datapointWidth Width of a single data point i.e. + * Since each column represents a seperate data + * point. + * @param datapointHeight Height of a single data point. + * @param datapointDepth Depth of a single data point. For one 2-dimensional + * data point, set it to 1. Defaults to 1. + * @param augmentation String containing the transform. + */ + + template + void GaussianBlurTransform(DatasetType& dataset, + const size_t datapointWidth, + const size_t datapointHeight, + const size_t datapointDepth, + const std::string& augmentation); + private: /** * Function to determine if augmentation has Resize function. @@ -119,10 +142,31 @@ class Augmentation // Search in augmentation vector. - return augmentations.size() <= 0 ? false : - augmentations[0].find("resize") != std::string::npos; + for(size_t i = 0; i < argumentation.size(); i++) + { + if (argumentation[i].find("resize") != std::string::npos) + return true + } + return false + } + /* + * Function to determine whether blurring is needed or not + Will check if the string has blurring. + */ + bool HasBlurring(const std::string& augmentation = "") + { + if (augmentation.length()) + return augmentation.find("gaussian-blur") != std::string::npos; + + for(size_t i = 0; i < argumentation.size(); i++) + { + if(argumentation[i].find("gaussian-blur") != std::string::npos) + return true + } + return false } + /** * Sets size of output width and output height of the new data. * @@ -169,6 +213,38 @@ class Augmentation outHeight = std::stoi(*matches); } } + /** + * Sets size of radius/ sigma of the gaussian kernel. + * + * @param sigma is the radius of the gaussian kernel specified by user. + */ + void GetBlurParam(size_t& sigma, const std::string& augmentation) + { + if (!HasBlurring(augmentation)) + return; + + sigma = 0; + + // Use regex to find one number. + // Input should be of form sigma. + boost::regex regex{"[0-9]+"}; + + // Create an iterator to find matches. + boost::sregex_token_iterator matches(augmentation.begin(), + augmentation.end(), regex, 0), end; + + size_t matchesCount = std::distance(matches, end); + + if (matchesCount != 1) + { + mlpack::Log::Fatal << "Invalid sigma for gaussian blurring" << + augmentation << std::endl; + } + else + { + sigma = std::stoi(*matches); + } + } //! Locally held augmentations and transforms that need to be applied. std::vector augmentations; diff --git a/augmentation/augmentation_impl.hpp b/augmentation/augmentation_impl.hpp index c4494a35..db527041 100644 --- a/augmentation/augmentation_impl.hpp +++ b/augmentation/augmentation_impl.hpp @@ -1,6 +1,6 @@ -/** +/**Adding support for more data types to mlpack, it would be preferable to add the support upstream to Armadillo instead, so that may be a better direction to go first. Then very little code modification for mlpack will be necessary./** * @file augmentation_impl.hpp - * @author Kartik Dutt + * @author Kartik Dutt, Sirish * * Implementation of Augmentation class for augmenting data. * @@ -38,7 +38,12 @@ void Augmentation::Transform(DatasetType& dataset, this->ResizeTransform(dataset, datapointWidth, datapointHeight, datapointDepth, augmentations[i]); } - else + else if(this->HasBlurring(augmentations[i])) + { + this->GaussianBlurTransform(dataset, datapointWidth, datapointHeight, + datapointDepth, augmentations[i]); + } + else { mlpack::Log::Warn << "Unknown augmentation : \'" << augmentations[i] << "\' not found!" << std::endl; @@ -70,4 +75,49 @@ void Augmentation::ResizeTransform( dataset = std::move(output); } +template +void Augmentation::GaussianBlurTransform( + DatasetType& dataset, + const size_t datapointWidth, + const size_t datapointHeight, + const size_t datapointDepth, + const std::string& augmentation) +{ + //Implementing using http://blog.ivank.net/fastest-gaussian-blur.html + size_t sigma = 0; + GetBlurParam(sigma,augmentation); + + DatasetType bImage(datapointHeight, datapointWidth, datapointDepth); + dataset = arma::resize(dataset,datapointHeight,datapointWidth,datapointDepth); + + //Significant radius + sradius = arma::ceil(sigma * 2.57); + + for (size_t k = 0; k < datapointDepth; k++) + { + for (size_t i = 0; i < datapointHeight; i++) + { + for (size_t j = 0; j < datapointWidth; j++) + { + size_t val = 0; + size_t wsum = 0; + for (size_t iy = i - rs; iy <= i + rs; iy++) + { + for (size_t ix = j - rs; ix <= j + rs; ix++) + { + size_t x,y; + x = arma::min(datapointWidth - 1, arma::max(0, ix)) + y = arma::min(datapointHeight - 1, arma::max(0, iy)) + dsq = (ix - j) * (ix - j) + (iy - i) * (iy - i) + weight = arma::exp(-dsq / (2 * r * r)) / (datum::pi * 2 * r * r) + val += dataset(y,x,k)* weight + wsum += weight + } + } + bImage(i,j,k) = arma::round(val / wsum) + } + } + dataset = std::move(bImage); +} + #endif From 3eebacf158d99936ca73e080bb060cacad37c515 Mon Sep 17 00:00:00 2001 From: Sirish Date: Sat, 12 Dec 2020 12:29:00 +0530 Subject: [PATCH 2/4] Corrected variable names in the files --- augmentation/augmentation.hpp | 2 +- augmentation/augmentation_impl.hpp | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/augmentation/augmentation.hpp b/augmentation/augmentation.hpp index 6112782b..b5f6cc65 100644 --- a/augmentation/augmentation.hpp +++ b/augmentation/augmentation.hpp @@ -237,7 +237,7 @@ class Augmentation if (matchesCount != 1) { - mlpack::Log::Fatal << "Invalid sigma for gaussian blurring" << + mlpack::Log::Fatal << "Invalid sigma/ radius for gaussian blurring" << augmentation << std::endl; } else diff --git a/augmentation/augmentation_impl.hpp b/augmentation/augmentation_impl.hpp index db527041..45de70f7 100644 --- a/augmentation/augmentation_impl.hpp +++ b/augmentation/augmentation_impl.hpp @@ -87,11 +87,20 @@ void Augmentation::GaussianBlurTransform( size_t sigma = 0; GetBlurParam(sigma,augmentation); + size_t rows, cols, depth; + // Storing initial matrix dimensions + rows = dataset.n_rows; + cols = dataset.n_cols; + depth = dataset.depth; + + // Creating empty object bImage DatasetType bImage(datapointHeight, datapointWidth, datapointDepth); + + // Reshaping the matrix for ease of calculation dataset = arma::resize(dataset,datapointHeight,datapointWidth,datapointDepth); //Significant radius - sradius = arma::ceil(sigma * 2.57); + size_t rs = arma::ceil(sigma * 2.57); for (size_t k = 0; k < datapointDepth; k++) { @@ -101,6 +110,7 @@ void Augmentation::GaussianBlurTransform( { size_t val = 0; size_t wsum = 0; + for (size_t iy = i - rs; iy <= i + rs; iy++) { for (size_t ix = j - rs; ix <= j + rs; ix++) @@ -108,15 +118,21 @@ void Augmentation::GaussianBlurTransform( size_t x,y; x = arma::min(datapointWidth - 1, arma::max(0, ix)) y = arma::min(datapointHeight - 1, arma::max(0, iy)) + // Calculating sqaured distance dsq = (ix - j) * (ix - j) + (iy - i) * (iy - i) - weight = arma::exp(-dsq / (2 * r * r)) / (datum::pi * 2 * r * r) + // Weight of gaussian kernel + weight = arma::exp(-dsq / (2 * sigma * sigma)) / (datum::pi * 2 * sigma * sigma) + // Summing all weighted contributions val += dataset(y,x,k)* weight wsum += weight } } + // Blurred image bImage(i,j,k) = arma::round(val / wsum) } } + //Restoring the blurred image to original dimensions as that of input + bImage = arma::resize(bImage,rows,cols,depth); dataset = std::move(bImage); } From 77fb706ed44242a7cf3b447f20519419a717822a Mon Sep 17 00:00:00 2001 From: Sirish Date: Sat, 12 Dec 2020 12:35:05 +0530 Subject: [PATCH 3/4] Error in for loop fixed --- augmentation/augmentation_impl.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/augmentation/augmentation_impl.hpp b/augmentation/augmentation_impl.hpp index 45de70f7..2cf29cd7 100644 --- a/augmentation/augmentation_impl.hpp +++ b/augmentation/augmentation_impl.hpp @@ -125,15 +125,16 @@ void Augmentation::GaussianBlurTransform( // Summing all weighted contributions val += dataset(y,x,k)* weight wsum += weight + } } - } // Blurred image bImage(i,j,k) = arma::round(val / wsum) + } } } + //Restoring the blurred image to original dimensions as that of input bImage = arma::resize(bImage,rows,cols,depth); dataset = std::move(bImage); } - #endif From f0ef4080db440ba3d41c3c139f59a77dd77d0f70 Mon Sep 17 00:00:00 2001 From: Sirish <45446751+Sirish07@users.noreply.github.com> Date: Sun, 13 Dec 2020 14:33:27 +0530 Subject: [PATCH 4/4] Update linux-steps.yaml --- .ci/linux-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/linux-steps.yaml b/.ci/linux-steps.yaml index 3b660741..a53b2efa 100644 --- a/.ci/linux-steps.yaml +++ b/.ci/linux-steps.yaml @@ -20,7 +20,7 @@ steps: unset BOOST_ROOT echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT - sudo apt-get install -y --allow-unauthenticated liblapack-dev g++ libboost1.70-dev libarmadillo-dev xz-utils + sudo apt-get install -y --allow-unauthenticated liblapack-dev g++ libboost1.70-dev libcereal-dev libarmadillo-dev xz-utils curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo* cmake . && make && sudo make install && cd ..