// Copyright (C) 2019  Joseph Artsimovich <joseph.artsimovich@gmail.com>, 4lex4 <4lex49@zoho.com>
// Use of this source code is governed by the GNU GPLv3 license that can be found in the LICENSE file.

#ifndef SCANTAILOR_IMAGEPROC_BINARIZE_H_
#define SCANTAILOR_IMAGEPROC_BINARIZE_H_

#include <QSize>

class QImage;

namespace imageproc {
class BinaryImage;

/**
 * \brief Image binarization using Otsu's global thresholding method.
 *
 * N. Otsu (1979). "A threshold selection method from gray-level histograms".
 * http://en.wikipedia.org/wiki/Otsu%27s_method
 */
BinaryImage binarizeOtsu(const QImage& src);

/**
 * \brief Image binarization using Mokji's global thresholding method.
 *
 * M. M. Mokji, S. A. R. Abu-Bakar: Adaptive Thresholding Based on
 * Co-occurrence Matrix Edge Information. Asia International Conference on
 * Modelling and Simulation 2007: 444-450
 * http://www.academypublisher.com/jcp/vol02/no08/jcp02084452.pdf
 *
 * \param src The source image.  May be in any format.
 * \param maxEdgeWidth The maximum gradient length to consider.
 * \param minEdgeMagnitude The minimum color difference in a gradient.
 * \return A black and white image.
 */
BinaryImage binarizeMokji(const QImage& src, unsigned maxEdgeWidth = 3, unsigned minEdgeMagnitude = 20);

/**
 * \brief Image binarization using Sauvola's local thresholding method.
 *
 * Sauvola, J. and M. Pietikainen. 2000. "Adaptive document image binarization".
 * http://www.mediateam.oulu.fi/publications/pdf/24.pdf
 */
BinaryImage binarizeSauvola(const QImage& src, QSize windowSize, double k = 0.34, double delta = 0.0);

/**
 * \brief Image binarization using Wolf's local thresholding method.
 *
 * C. Wolf, J.M. Jolion, F. Chassaing. "Text localization, enhancement and
 * binarization in multimedia documents."
 * http://liris.cnrs.fr/christian.wolf/papers/icpr2002v.pdf
 *
 * \param src The image to binarize.
 * \param windowSize The dimensions of a pixel neighborhood to consider.
 * \param lowerBound The minimum possible gray level that can be made white.
 * \param upperBound The maximum possible gray level that can be made black.
 */
BinaryImage binarizeWolf(const QImage& src,
                         QSize windowSize,
                         unsigned char lowerBound = 1,
                         unsigned char upperBound = 254,
                         double k = 0.3,
                         double delta = 0.0);

/**
 * \brief Image binarization using Fox's local thresholding method.
 *
 * Modification of the Wolf threshold using the Singh optimization
 * of the Sauvola threshold.
 *
 * C. Wolf, J.M. Jolion, F. Chassaing. "Text localization, enhancement and
 * binarization in multimedia documents."
 * http://liris.cnrs.fr/christian.wolf/papers/icpr2002v.pdf
 *
 * Singh, O. I., Sinam, T., James, O., & Singh, T. R. (2012).
 * Local contrast and mean based thresholding technique in image binarization.
 * International Journal of Computer Applications, 51, 5-10.
 * https://research.ijcaonline.org/volume51/number6/pxc3881362.pdf
 *
 * \param src The image to binarize.
 * \param windowSize The dimensions of a pixel neighborhood to consider.
 * \param lowerBound The minimum possible gray level that can be made white.
 * \param upperBound The maximum possible gray level that can be made black.
 */
BinaryImage binarizeFox(const QImage& src,
                        QSize windowSize,
                        unsigned char lowerBound = 1,
                        unsigned char upperBound = 254,
                        double k = 0.3,
                        double delta = 0.0);

/**
 * \brief Image binarization using Dynamic Window based thresholding method.
 *
 * Bataineh, B., Abdullah, S. N. H. S., & Omar, K. (2011).
 * An adaptive local binarization method for document images based
 * on a novel thresholding method and  dynamic windows.
 * Pattern Recognition Letters, 32(14), 1805–1813.
 *
 * \param src The image to binarize.
 * \param windowSize The dimensions of a pixel neighborhood to consider.
 * \param lowerBound The minimum possible gray level that can be made white.
 * \param upperBound The maximum possible gray level that can be made black.
 */
BinaryImage binarizeWindow(const QImage& src,
                           QSize windowSize,
                           unsigned char lowerBound = 1,
                           unsigned char upperBound = 254,
                           double k = 0.33,
                           double delta = 0.0);

/**
 * \brief Image binarization using Bradley's adaptive thresholding method.
 *
 * Derek Bradley, Gerhard Roth. 2005. "Adaptive Thresholding Using the Integral Image".
 * http://www.scs.carleton.ca/~roth/iit-publications-iti/docs/gerh-50002.pdf
 */
BinaryImage binarizeBradley(const QImage& src, QSize windowSize, double k = 0.34, double delta = 0.0);

/**
 * \brief Image binarization using Grad local/global thresholding method.
 *
 * Grad (aka "Gradient snip"), zvezdochiot 2024. "Adaptive/global document image binarization".
 */
BinaryImage binarizeGrad(const QImage& src,
                         QSize windowSize,
                         unsigned char lowerBound = 1,
                         unsigned char upperBound = 254,
                         double k = 0.3,
                         double delta = 0.0);

/**
 * \brief Image binarization using EdgeDiv (EdgePlus & BlurDiv) local/global thresholding method.
 *
 * EdgeDiv, zvezdochiot 2023. "Adaptive/global document image binarization".
 */
BinaryImage binarizeEdgeDiv(const QImage& src,
                            QSize windowSize,
                            double kep = 0.0,
                            double kdb = 0.0,
                            double delta = 0.0);

BinaryImage peakThreshold(const QImage& image);
}  // namespace imageproc
#endif
