niblack_thresholding.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2014, Beat Kueng (beat-kueng@gmx.net), Lukas Vogel, Morten Lysgaard
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  22. // * Redistribution's in binary form must reproduce the above copyright notice,
  23. // this list of conditions and the following disclaimer in the documentation
  24. // and/or other materials provided with the distribution.
  25. //
  26. // * The name of the copyright holders may not be used to endorse or promote products
  27. // derived from this software without specific prior written permission.
  28. //
  29. // This software is provided by the copyright holders and contributors "as is" and
  30. // any express or implied warranties, including, but not limited to, the implied
  31. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  32. // In no event shall the Intel Corporation or contributors be liable for any direct,
  33. // indirect, incidental, special, exemplary, or consequential damages
  34. // (including, but not limited to, procurement of substitute goods or services;
  35. // loss of use, data, or profits; or business interruption) however caused
  36. // and on any theory of liability, whether in contract, strict liability,
  37. // or tort (including negligence or otherwise) arising in any way out of
  38. // the use of this software, even if advised of the possibility of such damage.
  39. //
  40. //M*/
  41. #include "precomp.hpp"
  42. #include <cmath>
  43. namespace cv {
  44. namespace ximgproc {
  45. void niBlackThreshold( InputArray _src, OutputArray _dst, double maxValue,
  46. int type, int blockSize, double k, int binarizationMethod, double r)
  47. {
  48. // Input grayscale image
  49. Mat src = _src.getMat();
  50. CV_Assert(src.channels() == 1);
  51. CV_Assert(blockSize % 2 == 1 && blockSize > 1);
  52. if (binarizationMethod == BINARIZATION_SAUVOLA) {
  53. CV_Assert(src.depth() == CV_8U);
  54. CV_Assert(r != 0);
  55. }
  56. type &= THRESH_MASK;
  57. // Compute local threshold (T = mean + k * stddev)
  58. // using mean and standard deviation in the neighborhood of each pixel
  59. // (intermediate calculations are done with floating-point precision)
  60. Mat thresh;
  61. {
  62. // note that: Var[X] = E[X^2] - E[X]^2
  63. Mat mean, sqmean, variance, stddev, sqrtVarianceMeanSum;
  64. double srcMin, stddevMax;
  65. boxFilter(src, mean, CV_32F, Size(blockSize, blockSize),
  66. Point(-1,-1), true, BORDER_REPLICATE);
  67. sqrBoxFilter(src, sqmean, CV_32F, Size(blockSize, blockSize),
  68. Point(-1,-1), true, BORDER_REPLICATE);
  69. variance = sqmean - mean.mul(mean);
  70. sqrt(variance, stddev);
  71. switch (binarizationMethod)
  72. {
  73. case BINARIZATION_NIBLACK:
  74. thresh = mean + stddev * static_cast<float>(k);
  75. break;
  76. case BINARIZATION_SAUVOLA:
  77. thresh = mean.mul(1. + static_cast<float>(k) * (stddev / r - 1.));
  78. break;
  79. case BINARIZATION_WOLF:
  80. minMaxIdx(src, &srcMin);
  81. minMaxIdx(stddev, NULL, &stddevMax);
  82. thresh = mean - static_cast<float>(k) * (mean - srcMin - stddev.mul(mean - srcMin) / stddevMax);
  83. break;
  84. case BINARIZATION_NICK:
  85. sqrt(variance + sqmean, sqrtVarianceMeanSum);
  86. thresh = mean + static_cast<float>(k) * sqrtVarianceMeanSum;
  87. break;
  88. default:
  89. CV_Error( Error::StsBadArg, "Unknown binarization method" );
  90. break;
  91. }
  92. thresh.convertTo(thresh, src.depth());
  93. }
  94. // Prepare output image
  95. _dst.create(src.size(), src.type());
  96. Mat dst = _dst.getMat();
  97. CV_Assert(src.data != dst.data); // no inplace processing
  98. // Apply thresholding: ( pixel > threshold ) ? foreground : background
  99. Mat mask;
  100. switch (type)
  101. {
  102. case THRESH_BINARY: // dst = (src > thresh) ? maxval : 0
  103. case THRESH_BINARY_INV: // dst = (src > thresh) ? 0 : maxval
  104. compare(src, thresh, mask, (type == THRESH_BINARY ? CMP_GT : CMP_LE));
  105. dst.setTo(0);
  106. dst.setTo(maxValue, mask);
  107. break;
  108. case THRESH_TRUNC: // dst = (src > thresh) ? thresh : src
  109. compare(src, thresh, mask, CMP_GT);
  110. src.copyTo(dst);
  111. thresh.copyTo(dst, mask);
  112. break;
  113. case THRESH_TOZERO: // dst = (src > thresh) ? src : 0
  114. case THRESH_TOZERO_INV: // dst = (src > thresh) ? 0 : src
  115. compare(src, thresh, mask, (type == THRESH_TOZERO ? CMP_GT : CMP_LE));
  116. dst.setTo(0);
  117. src.copyTo(dst, mask);
  118. break;
  119. default:
  120. CV_Error( Error::StsBadArg, "Unknown threshold type" );
  121. break;
  122. }
  123. }
  124. } // namespace ximgproc
  125. } // namespace cv