/*
 * cv_edgetaper.cpp - used in deblurring to remove ringing artifacts
 *
 *  Copyright (c) 2016-2017 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Andrey Parfenov <a1994ndrey@gmail.com>
 * Author: Wind Yuan <feng.yuan@intel.com>
 */

#include "cv_edgetaper.h"

namespace XCam {

void
CVEdgetaper::create_weights (const cv::Mat &image, const cv::Mat &psf, cv::Mat &coefficients)
{
    cv::Mat rows_proj, cols_proj;
    cv::Mat rows_proj_border, cols_proj_border;
    cv::Mat rows_cor, cols_cor;
    // get psf rows and cols projections
    cv::reduce (psf, rows_proj, 1, cv::REDUCE_SUM, -1);
    cv::reduce (psf, cols_proj, 0, cv::REDUCE_SUM, -1);
    // calculate correlation for psf projections
    cv::copyMakeBorder (rows_proj, rows_proj_border, (psf.rows - 1) / 2, (psf.rows - 1) / 2, 0, 0, cv::BORDER_CONSTANT, cv::Scalar::all (0));
    cv::copyMakeBorder (cols_proj, cols_proj_border, 0, 0,  (psf.cols - 1) / 2, (psf.cols - 1) / 2, cv::BORDER_CONSTANT, cv::Scalar::all (0));
    cv::matchTemplate (rows_proj_border, rows_proj, rows_cor, cv::TM_CCORR);
    cv::matchTemplate (cols_proj_border, cols_proj, cols_cor, cv::TM_CCORR);
    // make it symmetric on both sides
    cv::Mat rows_add = cv::Mat_<float>(1, 1) << rows_proj.at<float> (0, 0);
    cv::Mat cols_add = cv::Mat_<float>(1, 1) << cols_proj.at<float> (0, 0);
    cv::vconcat (rows_cor, rows_add, rows_cor);
    cv::hconcat (cols_cor, cols_add, cols_cor);
    double min, max;
    cv::minMaxLoc (rows_cor, &min, &max);
    rows_cor /= max;
    cv::minMaxLoc (cols_cor, &min, &max);
    cols_cor /= max;
    // get matrix from projections
    cv::Mat alpha = (cv::Scalar (1) - rows_proj) * (cv::Scalar (1) - cols_proj);
    // expand it to the image size
    int nc = image.cols / psf.cols + 1;
    int nr = image.rows / psf.rows + 1;
    cv::Mat expanded;
    cv::repeat (alpha, nr, nc, expanded);
    cv::Mat weights = expanded (cv::Rect (expanded.cols / 2 - image.cols / 2, expanded.rows / 2 - image.rows / 2, image.cols, image.rows));
    coefficients = weights.clone ();
}

void
CVEdgetaper::edgetaper (const cv::Mat &img, const cv::Mat &psf, cv::Mat &output)
{
    cv::Mat blurred = cv::Mat::zeros (img.rows, img.cols, CV_32FC1);
    // flip PSF to perform convolution
    cv::Mat psf_flipped;
    cv::flip (psf, psf_flipped, -1);
    cv::filter2D (img, blurred, CV_32FC1, psf_flipped, cv::Point (-1, -1), 0, cv::BORDER_CONSTANT);
    cv::Mat coefficients;
    create_weights (img, psf, coefficients);
    cv::Mat result;
    img.convertTo (result, CV_32FC1);
    result = result.mul (coefficients) + blurred.mul (cv::Scalar (1.0f) - coefficients);
    output = result.clone ();
}

}
