You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

niBlackThreshold.h 4.0 kB

7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // Created by 庾金科 on 26/10/2017.
  3. //
  4. #ifndef SWIFTPR_NIBLACKTHRESHOLD_H
  5. #define SWIFTPR_NIBLACKTHRESHOLD_H
  6. #include <opencv2/opencv.hpp>
  7. using namespace cv;
  8. enum LocalBinarizationMethods{
  9. BINARIZATION_NIBLACK = 0, //!< Classic Niblack binarization. See @cite Niblack1985 .
  10. BINARIZATION_SAUVOLA = 1, //!< Sauvola's technique. See @cite Sauvola1997 .
  11. BINARIZATION_WOLF = 2, //!< Wolf's technique. See @cite Wolf2004 .
  12. BINARIZATION_NICK = 3 //!< NICK technique. See @cite Khurshid2009 .
  13. };
  14. void niBlackThreshold( InputArray _src, OutputArray _dst, double maxValue,
  15. int type, int blockSize, double k, int binarizationMethod )
  16. {
  17. // Input grayscale image
  18. Mat src = _src.getMat();
  19. CV_Assert(src.channels() == 1);
  20. CV_Assert(blockSize % 2 == 1 && blockSize > 1);
  21. if (binarizationMethod == BINARIZATION_SAUVOLA) {
  22. CV_Assert(src.depth() == CV_8U);
  23. }
  24. type &= THRESH_MASK;
  25. // Compute local threshold (T = mean + k * stddev)
  26. // using mean and standard deviation in the neighborhood of each pixel
  27. // (intermediate calculations are done with floating-point precision)
  28. Mat test;
  29. Mat thresh;
  30. {
  31. // note that: Var[X] = E[X^2] - E[X]^2
  32. Mat mean, sqmean, variance, stddev, sqrtVarianceMeanSum;
  33. double srcMin, stddevMax;
  34. boxFilter(src, mean, CV_32F, Size(blockSize, blockSize),
  35. Point(-1,-1), true, BORDER_REPLICATE);
  36. sqrBoxFilter(src, sqmean, CV_32F, Size(blockSize, blockSize),
  37. Point(-1,-1), true, BORDER_REPLICATE);
  38. variance = sqmean - mean.mul(mean);
  39. sqrt(variance, stddev);
  40. switch (binarizationMethod)
  41. {
  42. case BINARIZATION_NIBLACK:
  43. thresh = mean + stddev * static_cast<float>(k);
  44. break;
  45. case BINARIZATION_SAUVOLA:
  46. thresh = mean.mul(1. + static_cast<float>(k) * (stddev / 128.0 - 1.));
  47. break;
  48. case BINARIZATION_WOLF:
  49. minMaxIdx(src, &srcMin,NULL);
  50. minMaxIdx(stddev, NULL, &stddevMax);
  51. thresh = mean - static_cast<float>(k) * (mean - srcMin - stddev.mul(mean - srcMin) / stddevMax);
  52. break;
  53. case BINARIZATION_NICK:
  54. sqrt(variance + sqmean, sqrtVarianceMeanSum);
  55. thresh = mean + static_cast<float>(k) * sqrtVarianceMeanSum;
  56. break;
  57. default:
  58. CV_Error( CV_StsBadArg, "Unknown binarization method" );
  59. break;
  60. }
  61. thresh.convertTo(thresh, src.depth());
  62. thresh.convertTo(test, src.depth());
  63. //
  64. // cv::imshow("imagex",test);
  65. // cv::waitKey(0);
  66. }
  67. // Prepare output image
  68. _dst.create(src.size(), src.type());
  69. Mat dst = _dst.getMat();
  70. CV_Assert(src.data != dst.data); // no inplace processing
  71. // Apply thresholding: ( pixel > threshold ) ? foreground : background
  72. Mat mask;
  73. switch (type)
  74. {
  75. case THRESH_BINARY: // dst = (src > thresh) ? maxval : 0
  76. case THRESH_BINARY_INV: // dst = (src > thresh) ? 0 : maxval
  77. compare(src, thresh, mask, (type == THRESH_BINARY ? CMP_GT : CMP_LE));
  78. dst.setTo(0);
  79. dst.setTo(maxValue, mask);
  80. break;
  81. case THRESH_TRUNC: // dst = (src > thresh) ? thresh : src
  82. compare(src, thresh, mask, CMP_GT);
  83. src.copyTo(dst);
  84. thresh.copyTo(dst, mask);
  85. break;
  86. case THRESH_TOZERO: // dst = (src > thresh) ? src : 0
  87. case THRESH_TOZERO_INV: // dst = (src > thresh) ? 0 : src
  88. compare(src, thresh, mask, (type == THRESH_TOZERO ? CMP_GT : CMP_LE));
  89. dst.setTo(0);
  90. src.copyTo(dst, mask);
  91. break;
  92. default:
  93. CV_Error( CV_StsBadArg, "Unknown threshold type" );
  94. break;
  95. }
  96. }
  97. #endif //SWIFTPR_NIBLACKTHRESHOLD_H