yaodix / Elastic-Distortion

Implementation of elastic distortion algorithm in C++ (Using OpenCV)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Elastic-Distortion

Implementation of elastic distortion algorithm in C++ (Using OpenCV)

This is naive implementation of Elastic Distortion algorithm discussed in [1] for image augmentation.

elastic

Code

void ElasticDeformations(cv::Mat& src,
                         cv::Mat& dst,
                         bool bNorm = false,
                         double sigma = 4.,
                         double alpha = 34.)
{
    if(src.empty()) return;
    if(dst.empty()) dst = cv::Mat::zeros(src.size(), src.type());

    cv::Mat dx(src.size(), CV_64FC1);
    cv::Mat dy(src.size(), CV_64FC1);

    double low = -1.0;
    double high = 1.0;

    //The image deformations were created by first generating
    //random displacement fields, that's dx(x,y) = rand(-1, +1) and dy(x,y) = rand(-1, +1)
    cv::randu(dx, cv::Scalar(low), cv::Scalar(high));
    cv::randu(dy, cv::Scalar(low), cv::Scalar(high));

    //The fields dx and dy are then convolved with a Gaussian of standard deviation sigma(in pixels)
    cv::Size kernel_size(sigma*6 + 1, sigma*6 + 1);
    cv::GaussianBlur(dx, dx, kernel_size, sigma);
    cv::GaussianBlur(dy, dy, kernel_size, sigma);

    //If we normalize the displacement field (to a norm of 1,
    //the field is then close to constant, with a random direction
    if(bNorm)
    {
        dx /= cv::norm(dx, cv::NORM_L1);
        dy /= cv::norm(dy, cv::NORM_L1);
    }

    //The displacement fields are then multiplied by a scaling factor alpha
    //that controls the intensity of the deformation.
    dx *= alpha;
    dy *= alpha;

    //Inverse(or Backward) Mapping to avoid gaps and overlaps.
    cv::Rect checkError(0, 0, src.cols, src.rows);
    int nCh = src.channels();

    for(int displaced_y = 0; displaced_y < src.rows; displaced_y++)
        for(int displaced_x = 0; displaced_x < src.cols; displaced_x++)
        {
            int org_x = displaced_x - dx.at<double>(displaced_y, displaced_x);
            int org_y = displaced_y - dy.at<double>(displaced_y, displaced_x);

            if(checkError.contains(cv::Point(org_x, org_y)))
            {
                for(int ch = 0; ch < nCh; ch++)
                {
                    dst.data[(displaced_y * src.cols + displaced_x) * nCh + ch] = src.data[(org_y * src.cols + org_x) * nCh + ch];
                }
            }
        }
}

References

[1] Best Practices for Convolutional Neural Networks Applied to Visual Document Analysis

About

Implementation of elastic distortion algorithm in C++ (Using OpenCV)


Languages

Language:C++ 100.0%