Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Gaussian blurring method to augmentations #41

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ci/linux-steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ..
Expand Down
82 changes: 79 additions & 3 deletions augmentation/augmentation.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @file augmentation.hpp
* @author Kartik Dutt
* @author Kartik Dutt, Sirish
*
* Definition of Augmentation class for augmenting data.
*
Expand Down Expand Up @@ -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<typename DatasetType>
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.
Expand All @@ -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.
*
Expand Down Expand Up @@ -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/ radius for gaussian blurring" <<
augmentation << std::endl;
}
else
{
sigma = std::stoi(*matches);
}
}

//! Locally held augmentations and transforms that need to be applied.
std::vector<std::string> augmentations;
Expand Down
73 changes: 70 additions & 3 deletions augmentation/augmentation_impl.hpp
Original file line number Diff line number Diff line change
@@ -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./**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty long comment

* @file augmentation_impl.hpp
* @author Kartik Dutt
* @author Kartik Dutt, Sirish
*
* Implementation of Augmentation class for augmenting data.
*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -70,4 +75,66 @@ void Augmentation::ResizeTransform(
dataset = std::move(output);
}

template<typename DatasetType>
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);

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
size_t rs = 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))
// Calculating sqaured distance
dsq = (ix - j) * (ix - j) + (iy - i) * (iy - i)
// 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);
}
#endif