libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNImageGray.h
Go to the documentation of this file.
1 /* Copyright 2006-2016 Yann LEYDIER, CoReNum, INSA-Lyon, ENS-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNImageGray.h
19  * \author Yann LEYDIER
20  */
21 
22 #ifndef CRNIMAGEGRAY_HEADER
23 #define CRNIMAGEGRAY_HEADER
24 
25 #include <CRNImage/CRNImage.h>
27 #include <CRNAI/CRNkMeans.h>
29 
34 namespace crn
35 {
38 
39  /*************************************************************************************
40  * Edition
41  ************************************************************************************/
42 
44  void Sqrt(ImageDoubleGray &img) noexcept;
45 
47  template<typename T> void Abs(Image<T> &img, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr) noexcept
48  {
49  for (auto &px : img)
50  px = Abs(px);
51  }
52 
54  void AutoContrast(ImageGray &img);
55 
56  /*************************************************************************************
57  * Characterization
58  ************************************************************************************/
59 
64  template<typename T> Histogram MakeHistogram(const Image<T> &img, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
65  {
66  const auto mM = MinMax(img);
67  auto h = Histogram(size_t(mM.second - mM.first + 1));
68  for (auto v : img)
69  h.IncBin(size_t(v - mM.first));
70  return h;
71  }
72 
74  Histogram MakeHistogram(const ImageGray &img);
75 
77  Histogram HorizontalProjection(const ImageGray &img);
79  Histogram VerticalProjection(const ImageGray &img);
80 
81  /*****************************************************************************/
90  template<typename T> size_t StrokesWidth(const Image<T> &img, size_t maxval = 50, size_t defaultval = 0, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
91  {
92  auto strokeswidth = size_t(0);
93  auto pacc = SumType<T>(0);
94  for (strokeswidth = 1; strokeswidth < Min(maxval, img.GetWidth()); strokeswidth++)
95  {
96  auto acc = SumType<T>(0);
97  for (size_t y = 0; y < img.GetHeight(); y++)
98  {
99  auto yoffset = y * img.GetWidth();
100  auto tacc = SumType<T>(0);
101  for (size_t x = 0; x < img.GetWidth(); x++)
102  {
103  auto tx = int(x) - int(strokeswidth);
104  if (tx < 0) tx += int(img.GetWidth());
105  if (tx >= int(img.GetWidth())) tx -= int(img.GetWidth());
106  tacc += Abs(img.At(x + yoffset) - img.At(tx + yoffset));
107  }
108  acc += tacc;
109  }
110  if (pacc != 0)
111  {
112  if ((DecimalType<T>(Abs(acc - pacc)) / DecimalType<T>(pacc)) < 0.1)
113  {
114  return strokeswidth;
115  }
116  }
117  pacc = acc;
118  }
119  return defaultval;
120  }
121 
122  /*****************************************************************************/
131  template<typename T> size_t StrokesHeight(const Image<T> &img, size_t maxval = 50, size_t defaultval = 0, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
132  {
133  auto strokesheight = size_t(0);
134  auto pacc = SumType<T>(0);
135  for (strokesheight = 1; strokesheight < Min(maxval, img.GetHeight()); strokesheight++)
136  {
137  auto acc = SumType<T>(0);
138  for (size_t y = 0; y < img.GetHeight(); y++)
139  {
140  auto tacc = SumType<T>(0);
141  for (size_t x = 0; x < img.GetWidth(); x++)
142  {
143  auto ty = int(y) - int(strokesheight);
144  if (ty < 0) ty += int(img.GetHeight());
145  if (ty >= int(img.GetHeight())) ty -= int(img.GetHeight());
146  tacc += Abs(img.At(x, y) - img.At(x, ty));
147  }
148  acc += tacc;
149  }
150  if (pacc != 0)
151  {
152  if ((DecimalType<T>(Abs(acc - pacc)) / DecimalType<T>(pacc)) < 0.1)
153  {
154  return strokesheight;
155  }
156  }
157  pacc = acc;
158  }
159  return defaultval;
160  }
161 
163  size_t EstimateLinesXHeight(const ImageGray &img, unsigned int xdiv = 16);
165  size_t EstimateLeading(const ImageGray &img);
167  Angle<Radian> EstimateSkew(const ImageGray &img);
168 
169  /*************************************************************************************
170  * Conversion
171  ************************************************************************************/
172 
177  template<typename T> ImageRGB RandomColors(const Image<T> &img, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
178  {
179  auto irgb = ImageRGB(img.GetWidth(), img.GetHeight());
180  for (auto tmp : Range(img))
181  {
182  auto v = img.At(tmp);
183  if (v)
184  {
185  irgb.At(tmp) = {
186  uint8_t(int(32 + v * 33) & 0xFF),
187  uint8_t(int(32 + v * 55) & 0xFF),
188  uint8_t(int(32 + v * 77) & 0xFF)
189  };
190  }
191  }
192  return irgb;
193  }
194 
195  /****************************************************************************/
204  template<typename T, typename CMP = std::less<T>> ImageBW Threshold(const Image<T> &img, T thresh, CMP cmp = std::less<T>{})
205  {
206  auto out = ImageBW(img.GetWidth(), img.GetHeight());
207  for (auto i : Range(img))
208  out.At(i) = cmp(img.At(i), thresh) ? pixel::BWBlack : pixel::BWWhite;
209  return out;
210  }
211 
212  /****************************************************************************/
229  template<typename T> ImageBW Niblack(const Image<T> &img, size_t halfwin, double k = 0.5, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
230  {
231  auto out = ImageBW(img.GetWidth(), img.GetHeight());
232  FOREACHPIXEL(x, y, img)
233  {
234  // adjust window
235  auto x1 = (x < halfwin) ? 0 : x - halfwin;
236  auto y1 = (y < halfwin) ? 0 : y - halfwin;
237  auto x2 = x + halfwin;
238  if (x2 >= img.GetWidth()) x2 = img.GetWidth() - 1;
239  auto y2 = y + halfwin;
240  if (y2 >= img.GetHeight()) y2 = img.GetHeight() - 1;
241 
242  // compute stats
243  auto sum = DecimalType<T>(0.0);
244  auto sqrsum = DecimalType<T>(0.0);
245  for (auto ty = y1; ty <= y2; ty++)
246  for (auto tx = x1; tx <= x2; tx++)
247  {
248  auto p = DecimalType<T>(img.At(tx, ty));
249  sum += p;
250  sqrsum += Sqr(p);
251  }
252  auto size = (x2 - x1 + 1) * (y2 - y1 + 1);
253  auto m = sum / double(size); // mean
254  auto sd = sqrt(sqrsum / double(size) - Sqr(m)); // std deviation
255 
256  // compute threshold
257  auto t = m + k * sd ; // original formula
258 
259  out.At(x, y) = (img.At(x, y) < T(t)) ? pixel::BWBlack : pixel::BWWhite;
260  }
261  return out;
262  }
263 
264  /****************************************************************************/
282  template<typename T> ImageBW Sauvola(const Image<T> &img, size_t halfwin, double k = 0.5, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
283  {
284  // compute range
285  const auto mM = MinMax(img);
286  const auto dynRge = (DecimalType<T>(mM.second) - DecimalType<T>(mM.first)) * 0.5;
287 
288  auto out = ImageBW(img.GetWidth(), img.GetHeight());
289  FOREACHPIXEL(x, y, img)
290  {
291  // adjust window
292  auto x1 = (x < halfwin) ? 0 : x - halfwin;
293  auto y1 = (y < halfwin) ? 0 : y - halfwin;
294  auto x2 = x + halfwin;
295  if (x2 >= img.GetWidth()) x2 = img.GetWidth() - 1;
296  auto y2 = y + halfwin;
297  if (y2 >= img.GetHeight()) y2 = img.GetHeight() - 1;
298 
299  // compute stats
300  //auto mGL = std::numeric_limits<double>::max(); // min gray
301  auto sum = DecimalType<T>(0.0);
302  auto sqrsum = DecimalType<T>(0.0);
303  for (auto ty = y1; ty <= y2; ty++)
304  for (auto tx = x1; tx <= x2; tx++)
305  {
306  auto p = DecimalType<T>(img.At(tx, ty));
307  sum += p;
308  sqrsum += Sqr(p);
309  //if (p < mGL) mGL = p;
310  }
311  auto size = (x2 - x1 + 1) * (y2 - y1 + 1);
312  auto m = sum / double(size); // mean
313  auto sd = sqrt(sqrsum / double(size) - Sqr(m)); // std deviation
314 
315  // compute threshold
316  //auto t = m - k * (1 - sd / dynRge) * (m - mGL); // Wolf's formula
317  auto t = m * (1 + k * (sd / dynRge - 1)); // original formula
318 
319  out.At(x, y) = (img.At(x, y) < T(t)) ? pixel::BWBlack : pixel::BWWhite;
320  }
321 
322  return out;
323  }
324 
325  /****************************************************************************/
335  template<typename T> ImageBW kMeansHisto(const Image<T> &img, size_t classes, size_t black_classes, size_t maxcnt = 10000, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
336  {
337  if (classes < 2 || black_classes < 1)
338  throw ExceptionDomain{"kMeansHisto(): invalid number of classes."};
339 
340  auto histo = MakeHistogram(img);
341  if (histo.Size() < 3)
342  return Fisher(img);
343 
344  auto protos = std::vector<int>(classes);
345  for (auto tmp : Range(protos))
346  {
347  protos[tmp] = int(tmp * (histo.Size() - 1) / (classes));
348  }
349  auto ok = false;
350  while (!ok)
351  {
352  auto cumul = std::vector<int>(classes, 0);
353  auto cnt = std::vector<int>(classes, 0);
354  // for each bin
355  for (auto tmp : Range(histo))
356  {
357  // find nearest prototype
358  auto c = 0;
359  auto d = Abs(int(tmp) - protos[0]);
360  for (auto tmpc = size_t(1); tmpc < classes; ++tmpc)
361  {
362  const auto td = Abs(int(tmp) - protos[tmpc]);
363  if (td < d)
364  {
365  d = td;
366  c = int(tmpc);
367  }
368  }
369  cumul[c] += int(tmp);
370  cnt[c] += int(histo[tmp]);
371  }
372  for (auto tmp : Range(cumul))
373  if (cnt[tmp])
374  cumul[tmp] /= cnt[tmp];
375  ok = (protos == cumul);
376  cumul.swap(protos);
377  if (maxcnt == 0)
378  break;
379  maxcnt -= 1;
380  }
381 
382  ImageBW out = ImageBW(img.GetWidth(), img.GetHeight(), pixel::BWBlack);
383  double threshold = double(protos[black_classes - 1] + protos[black_classes]) / 2.0;
384 
385  for (auto tmp : Range(img))
386  {
387  if (double(img.At(tmp)) > threshold)
388  out.At(tmp) = pixel::BWWhite;
389  else
390  out.At(tmp) = pixel::BWBlack;
391  }
392 
393  return out;
394  }
395 
396  /****************************************************************************/
404  template<typename T> ImageBW LocalMin(const Image<T> &img, size_t area = 1, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
405  {
406  auto ibw = ImageBW(img.GetWidth(), img.GetHeight(), pixel::BWBlack);
407  // find plateaux
408  auto offset = size_t(0);
409  for (int y = 0; y < int(img.GetHeight()); y++)
410  for (int x = 0; x < int(img.GetWidth()); x++)
411  {
412  auto val = img.At(offset);
413  for (int ty = Max(y - int(area), 0); ty <= Min(int(img.GetHeight()) - 1, y + int(area)); ty++)
414  for (int tx = Max(x - int(area), 0); tx <= Min(int(img.GetWidth()) - 1, x + int(area)); tx++)
415  {
416  if (img.At(tx, ty) < val)
417  {
418  ibw.At(offset) = pixel::BWWhite;
419  break; // slightly useless...
420  }
421  }
422  offset += 1;
423  }
424  // propagate
425  auto mod = false;
426  do
427  {
428  mod = false;
429  auto offset = size_t(0);
430  for (int y = 0; y < int(img.GetHeight()); y++)
431  for (int x = 0; x < int(img.GetWidth()); x++)
432  {
433  if (ibw.At(offset) == pixel::BWBlack)
434  {
435  auto val = img.At(offset);
436  for (int ty = Max(y - int(area), 0); ty <= Min(int(img.GetHeight()) - 1, y + int(area)); ty++)
437  for (int tx = Max(x - int(area), 0); tx <= Min(int(img.GetWidth()) - 1, x + int(area)); tx++)
438  {
439  if ((ibw.At(tx, ty) == pixel::BWWhite) &&
440  (img.At(tx, ty) == val))
441  {
442  ibw.At(offset) = pixel::BWWhite;
443  mod = true;
444  break; // slightly useless...
445  }
446  }
447  }
448  offset += 1;
449  }
450  } while (mod);
451 
452  return ibw;
453  }
454 
455  /****************************************************************************/
463  template<typename T> ImageBW LocalMax(const Image<T> &img, size_t area = 1, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
464  {
465  ImageBW ibw = ImageBW(img.GetWidth(), img.GetHeight(), pixel::BWBlack);
466  // find plateaux
467  auto offset = size_t(0);
468  for (int y = 0; y < int(img.GetHeight()); y++)
469  for (int x = 0; x < int(img.GetWidth()); x++)
470  {
471  auto val = img.At(offset);
472  for (int ty = Max(y - int(area), 0); ty <= Min(int(img.GetHeight()) - 1, y + int(area)); ty++)
473  for (int tx = Max(x - int(area), 0); tx <= Min(int(img.GetWidth()) - 1, x + int(area)); tx++)
474  {
475  if (img.At(tx, ty) > val)
476  {
477  ibw.At(offset) = pixel::BWWhite;
478  break; // slightly useless...
479  }
480  }
481  offset += 1;
482  }
483  // propagate
484  auto mod = false;
485  do
486  {
487  mod = false;
488  auto offset = size_t(0);
489  for (int y = 0; y < int(img.GetHeight()); y++)
490  for (int x = 0; x < int(img.GetWidth()); x++)
491  {
492  if (ibw.At(offset) == pixel::BWBlack)
493  {
494  auto val = img.At(offset);
495  for (int ty = Max(y - int(area), 0); ty <= Min(int(img.GetHeight()) - 1, y + int(area)); ty++)
496  for (int tx = Max(x - int(area), 0); tx <= Min(int(img.GetWidth()) - 1, x + int(area)); tx++)
497  {
498  if ((ibw.At(tx, ty) == pixel::BWWhite) &&
499  (img.At(tx, ty) == val))
500  {
501  ibw.At(offset) = pixel::BWWhite;
502  mod = true;
503  break; // slightly useless...
504  }
505  }
506  }
507  offset += 1;
508  }
509  } while (mod);
510 
511  return ibw;
512  }
513 
514  /****************************************************************************/
521  template<typename T> ImageBW Fisher(const Image<T> &img, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
522  {
523  const auto mM = MinMax(img);
524  auto scaled = false;
525  auto h = Histogram{};
526  if (mM.second < 10)
527  {
528  auto clone = img;
529  clone *= 100.0;
530  h = MakeHistogram(clone);
531  scaled = true;
532  }
533  else
534  {
535  h = MakeHistogram(img);
536  }
537  const auto t = h.Fisher();
538  auto thresh = T{};
539  if (scaled)
540  thresh = T(mM.first + T(double(t) / 100.0));
541  else
542  thresh = T(mM.first + T(t));
543  return Threshold(img, thresh);
544  }
545 
546  /****************************************************************************/
553  template<typename T> ImageBW Entropy(const Image<T> &img, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
554  {
555  const auto mM = MinMax(img);
556  bool scaled = false;
557  auto h = Histogram{};
558  if (mM.second < 10)
559  {
560  auto clone = img;
561  clone *= 100.0;
562  h = MakeHistogram(clone);
563  scaled = true;
564  }
565  else
566  {
567  h = MakeHistogram(img);
568  }
569  const auto t = h.EntropyThreshold();
570  auto thresh = T{};
571  if (scaled)
572  thresh = T(mM.first + T(double(t) / 100.0));
573  else
574  thresh = T(mM.first + T(t));
575  return Threshold(img, thresh);
576  }
577 
578  /****************************************************************************/
585  template<typename T> ImageBW Otsu(const Image<T> &img, typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy = nullptr)
586  {
587  auto h = MakeHistogram(img);
588 
589  const auto hsize = h.Size();
590  auto mu = std::vector<double>(hsize, 0.0);
591  auto w = std::vector<double>(hsize, 0.0);
592  auto s2 = std::vector<double>(hsize, 0.0);
593  auto hnorm = std::vector<double>(hsize, 0.0);
594 
595  const auto cumul = double(h.CumulateBins());
596  for (size_t k = 0; k < hsize; ++k)
597  {
598  hnorm[k] = double(h.GetBin(k))/ cumul;
599  }
600 
601  for (size_t k = 0; k < hsize; ++k)
602  {
603  for (size_t j = 0; j < k; ++j)
604  {
605  mu[k] += double(j) * hnorm[j];
606  w[k] += hnorm[j];
607  }
608  }
609  for (size_t k = 0; k < hsize; ++k)
610  {
611  s2[k] = w[k] * (1 - w[k]) * (mu[hsize-1] * w[k] - mu[k]) * (mu[hsize-1] * w[k] - mu[k]);
612  }
613 
614  auto thresh = T{};
615  auto maxs2 = 0.0;
616  for (size_t k = 0;k < hsize; k++)
617  {
618  if (s2[k] > maxs2)
619  {
620  maxs2 = s2[k];
621  thresh = T(k);
622  }
623  }
624 
625  return Threshold(img, thresh);
626  }
627 
631  class Gray2BW: public Action
632  {
633  public:
634  virtual ~Gray2BW() override { }
636  virtual ImageBW Binarize(const ImageGray &img) = 0;
637  };
638 
642  class Gray2BWThreshold: public Gray2BW
643  {
644  public:
646  Gray2BWThreshold(uint8_t t = 127);
647  virtual ~Gray2BWThreshold() override { }
648  virtual StringUTF8 GetClassName() const override { return "Gray2BWThreshold"; }
649  virtual ImageBW Binarize(const ImageGray &img) override;
652  };
653 
657  class Gray2BWNiblack: public Gray2BW
658  {
659  public:
661  Gray2BWNiblack(size_t halfwin = 3, double k = 0.5);
662  virtual ~Gray2BWNiblack() override { }
663  virtual StringUTF8 GetClassName() const override { return "Gray2BWNiblack"; }
664  virtual ImageBW Binarize(const ImageGray &img) override;
667  };
668 
672  class Gray2BWSauvola: public Gray2BW
673  {
674  public:
676  Gray2BWSauvola(size_t halfwin = 3, double k = 0.5);
677  virtual ~Gray2BWSauvola() override { }
678  virtual StringUTF8 GetClassName() const override { return "Gray2BWSauvola"; }
679  virtual ImageBW Binarize(const ImageGray &img) override;
682  };
683 
687  class Gray2BWkMeansHisto: public Gray2BW
688  {
689  public:
691  Gray2BWkMeansHisto(size_t classes = 5, size_t black_classes = 3);
692  virtual ~Gray2BWkMeansHisto() override { }
693  virtual StringUTF8 GetClassName() const override { return "Gray2BWkMeansHisto"; }
694  virtual ImageBW Binarize(const ImageGray &img) override;
697  };
698 
702  class Gray2BWLocalMin: public Gray2BW
703  {
704  public:
706  Gray2BWLocalMin(size_t area = 1);
707  virtual ~Gray2BWLocalMin() override { }
708  virtual StringUTF8 GetClassName() const override { return "Gray2BWLocalMin"; }
709  virtual ImageBW Binarize(const ImageGray &img) override;
712  };
713 
717  class Gray2BWLocalMax: public Gray2BW
718  {
719  public:
721  Gray2BWLocalMax(size_t area = 1);
722  virtual ~Gray2BWLocalMax() override { }
723  virtual StringUTF8 GetClassName() const override { return "Gray2BWLocalMax"; }
724  virtual ImageBW Binarize(const ImageGray &img) override;
727  };
728 
732  class Gray2BWFisher: public Gray2BW
733  {
734  public:
736  Gray2BWFisher();
737  virtual ~Gray2BWFisher() override { }
738  virtual StringUTF8 GetClassName() const override { return "Gray2BWFisher"; }
739  virtual ImageBW Binarize(const ImageGray &img) override;
742  };
743 
747  class Gray2BWEntropy: public Gray2BW
748  {
749  public:
751  Gray2BWEntropy();
752  virtual ~Gray2BWEntropy() override { }
753  virtual StringUTF8 GetClassName() const override { return "Gray2BWEntropy"; }
754  virtual ImageBW Binarize(const ImageGray &img) override;
757  };
758 
762  class Gray2BWOtsu: public Gray2BW
763  {
764  public:
766  Gray2BWOtsu();
767  virtual ~Gray2BWOtsu() override { }
768  virtual StringUTF8 GetClassName() const override { return "Gray2BWOtsu"; }
769  virtual ImageBW Binarize(const ImageGray &img) override;
772  };
773 
774  template<> struct IsSerializable<Gray2BW> : public std::true_type {};
775  template<> struct IsSerializable<Gray2BWThreshold> : public std::true_type {};
776  template<> struct IsSerializable<Gray2BWNiblack> : public std::true_type {};
777  template<> struct IsSerializable<Gray2BWSauvola> : public std::true_type {};
778  template<> struct IsSerializable<Gray2BWkMeansHisto> : public std::true_type {};
779  template<> struct IsSerializable<Gray2BWLocalMin> : public std::true_type {};
780  template<> struct IsSerializable<Gray2BWLocalMax> : public std::true_type {};
781  template<> struct IsSerializable<Gray2BWFisher> : public std::true_type {};
782  template<> struct IsSerializable<Gray2BWEntropy> : public std::true_type {};
783  template<> struct IsSerializable<Gray2BWOtsu> : public std::true_type {};
784 
785  CRN_ALIAS_SMART_PTR(Gray2BW)
786 
787  ImageBW MakeImageBW(const ImageGray &img);
790 }
791 #endif
typename TypeInfo< T >::SumType SumType
Definition: CRNType.h:185
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:768
void AutoContrast(ImageGray &img)
Abstract class for images.
Definition: CRNImage.h:141
ImageBW Sauvola(const Image< T > &img, size_t halfwin, double k=0.5, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:282
ImageBW Entropy(const Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:553
Image< pixel::BW > ImageBW
Black and white image class.
ScalarRange< T > Range(T b, T e)
Creates a range [[b, e[[.
Definition: CRNType.h:257
#define CRN_SERIALIZATION_CONSTRUCTOR(classname)
Defines a default constructor from xml element.
Definition: CRNObject.h:165
ImageBW Fisher(const Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:521
ImageBW MakeImageBW(const ImageGray &img)
virtual ~Gray2BWEntropy() override
Definition: CRNImageGray.h:752
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:663
Fisher binarization action.
Definition: CRNImageGray.h:732
std::vector< pixel_type >::reference At(size_t x, size_t y) noexcept
Returns a reference to a pixel.
Definition: CRNImage.h:224
size_t GetHeight() const noexcept
Definition: CRNImage.h:74
Image< uint8_t > ImageGray
Grayscale image class.
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:708
const T & Max(const T &a, const T &b)
Returns the max of two values.
Definition: CRNMath.h:47
Image< pixel::RGB< uint8_t >> ImageRGB
Color image class.
virtual ~Gray2BWSauvola() override
Definition: CRNImageGray.h:677
virtual ImageBW Binarize(const ImageGray &img) override
Action = binarize a gray image.
Binarization action.
Definition: CRNImageGray.h:631
virtual ~Gray2BWkMeansHisto() override
Definition: CRNImageGray.h:692
Niblack binarization action.
Definition: CRNImageGray.h:657
Otsu binarization action.
Definition: CRNImageGray.h:762
ImageBW kMeansHisto(const Image< T > &img, size_t classes, size_t black_classes, size_t maxcnt=10000, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:335
#define FOREACHPIXEL(x, y, img)
Convenience macro to sweep an image.
Definition: CRNImage.h:37
void Sqrt(ImageDoubleGray &img) noexcept
Replaces the pixels with their square root.
ImageBW LocalMin(const Image< T > &img, size_t area=1, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:404
virtual ~Gray2BWLocalMax() override
Definition: CRNImageGray.h:722
size_t EstimateLeading(const ImageGray &img)
Computes the median distance between two baselines.
A generic domain error.
Definition: CRNException.h:83
ImageBW Niblack(const Image< T > &img, size_t halfwin, double k=0.5, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:229
Base functor class.
size_t StrokesHeight(const Image< T > &img, size_t maxval=50, size_t defaultval=0, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:131
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:723
virtual ~Gray2BWThreshold() override
Definition: CRNImageGray.h:647
virtual ~Gray2BWOtsu() override
Definition: CRNImageGray.h:767
Image< double > ImageDoubleGray
double Grayscale image class
ImageBW Otsu(const Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:585
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
Definition: CRNMath.h:61
Threshold binarization action.
Definition: CRNImageGray.h:642
virtual ~Gray2BWLocalMin() override
Definition: CRNImageGray.h:707
ImageBW Threshold(const Image< T > &img, T thresh, CMP cmp=std::less< T >{})
Definition: CRNImageGray.h:204
virtual ~Gray2BWFisher() override
Definition: CRNImageGray.h:737
typename TypeInfo< T >::DecimalType DecimalType
Definition: CRNType.h:187
virtual ~Gray2BWNiblack() override
Definition: CRNImageGray.h:662
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:648
void Abs(Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr) noexcept
Replaces each pixel by its absolute value.
Definition: CRNImageGray.h:47
const T & Min(const T &a, const T &b)
Returns the min of two values.
Definition: CRNMath.h:49
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:678
virtual ImageBW Binarize(const ImageGray &img)=0
Action = binarize a gray image.
size_t EstimateLinesXHeight(const ImageGray &img, unsigned int xdiv=16)
Computes the mean text line x-height.
Mother class for integer histograms.
Definition: CRNHistogram.h:44
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:753
Entropy binarization action.
Definition: CRNImageGray.h:747
Local max binarization action.
Definition: CRNImageGray.h:717
ImageBW LocalMax(const Image< T > &img, size_t area=1, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:463
std::pair< T, T > MinMax(const Image< T > &img, CMP cmp=CMP{})
Returns min and max pixel values.
Definition: CRNImage.hpp:1447
size_t GetWidth() const noexcept
Definition: CRNImage.h:72
Angle< Radian > EstimateSkew(const ImageGray &img)
Estimates the mean skew of the document's lines.
virtual ~Gray2BW() override
Definition: CRNImageGray.h:634
#define CRN_DECLARE_CLASS_CONSTRUCTOR(classname)
Declares a class constructor.
Definition: CRNObject.h:173
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:693
virtual StringUTF8 GetClassName() const override
Definition: CRNImageGray.h:738
size_t StrokesWidth(const Image< T > &img, size_t maxval=50, size_t defaultval=0, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:90
Histogram HorizontalProjection(const ImageBW &img)
Computes the horizontal projection.
Definition: CRNImageBW.cpp:574
CRN_ALIAS_SMART_PTR(ImageBW)
A character string class.
Definition: CRNStringUTF8.h:49
Sauvola binarization action.
Definition: CRNImageGray.h:672
k-means histo binarization action
Definition: CRNImageGray.h:687
ImageRGB RandomColors(const Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:177
Histogram MakeHistogram(const Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr)
Definition: CRNImageGray.h:64
Histogram VerticalProjection(const ImageBW &img)
Computes the vertical projection.
Definition: CRNImageBW.cpp:591
Local min binarization action.
Definition: CRNImageGray.h:702
Gray2BWThreshold(uint8_t t=127)
Default constructor.