Tesseract  3.02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tesseract::MasterTrainer Class Reference

#include <mastertrainer.h>

Public Member Functions

 MasterTrainer (NormalizationMode norm_mode, bool shape_analysis, bool replicate_samples, int debug_level)
 
 ~MasterTrainer ()
 
bool Serialize (FILE *fp) const
 
bool DeSerialize (bool swap, FILE *fp)
 
void LoadUnicharset (const char *filename)
 
void SetFeatureSpace (const IntFeatureSpace &fs)
 
void ReadTrainingSamples (FILE *fp, const FEATURE_DEFS_STRUCT &feature_defs, bool verification)
 
void AddSample (bool verification, const char *unichar_str, TrainingSample *sample)
 
void LoadPageImages (const char *filename)
 
void PostLoadCleanup ()
 
void PreTrainingSetup ()
 
void SetupMasterShapes ()
 
void IncludeJunk ()
 
void ReplicateAndRandomizeSamplesIfRequired ()
 
bool LoadFontInfo (const char *filename)
 
bool LoadXHeights (const char *filename)
 
bool AddSpacingInfo (const char *filename)
 
int GetFontInfoId (const char *font_name)
 
int GetBestMatchingFontInfoId (const char *filename)
 
void SetupFlatShapeTable (ShapeTable *shape_table)
 
CLUSTERERSetupForClustering (const ShapeTable &shape_table, const FEATURE_DEFS_STRUCT &feature_defs, int shape_id, int *num_samples)
 
void WriteInttempAndPFFMTable (const UNICHARSET &unicharset, const UNICHARSET &shape_set, const ShapeTable &shape_table, CLASS_STRUCT *float_classes, const char *inttemp_file, const char *pffmtable_file)
 
const UNICHARSETunicharset () const
 
TrainingSampleSetGetSamples ()
 
const ShapeTablemaster_shapes () const
 
void DebugCanonical (const char *unichar_str1, const char *unichar_str2)
 
void DisplaySamples (const char *unichar_str1, int cloud_font, const char *unichar_str2, int canonical_font)
 
void TestClassifierOnSamples (int report_level, bool replicate_samples, ShapeClassifier *test_classifier, STRING *report_string)
 
double TestClassifier (int report_level, bool replicate_samples, TrainingSampleSet *samples, ShapeClassifier *test_classifier, STRING *report_string)
 
float ShapeDistance (const ShapeTable &shapes, int s1, int s2)
 

Detailed Description

Definition at line 68 of file mastertrainer.h.

Constructor & Destructor Documentation

tesseract::MasterTrainer::MasterTrainer ( NormalizationMode  norm_mode,
bool  shape_analysis,
bool  replicate_samples,
int  debug_level 
)

Definition at line 51 of file mastertrainer.cpp.

55  : norm_mode_(norm_mode), samples_(fontinfo_table_),
56  junk_samples_(fontinfo_table_), verify_samples_(fontinfo_table_),
57  charsetsize_(0),
58  enable_shape_anaylsis_(shape_analysis),
59  enable_replication_(replicate_samples),
60  fragments_(NULL), prev_unichar_id_(-1), debug_level_(debug_level) {
61  fontinfo_table_.set_compare_callback(
63  fontinfo_table_.set_clear_callback(
65 }
bool CompareFontInfo(const FontInfo &fi1, const FontInfo &fi2)
Definition: fontinfo.cpp:25
#define NULL
Definition: host.h:144
void FontInfoDeleteCallback(FontInfo f)
Definition: fontinfo.cpp:44
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
tesseract::MasterTrainer::~MasterTrainer ( )

Definition at line 67 of file mastertrainer.cpp.

67  {
68  delete [] fragments_;
69  for (int p = 0; p < page_images_.size(); ++p)
70  pixDestroy(&page_images_[p]);
71 }
int size() const
Definition: genericvector.h:59

Member Function Documentation

void tesseract::MasterTrainer::AddSample ( bool  verification,
const char *  unichar_str,
TrainingSample sample 
)

Definition at line 184 of file mastertrainer.cpp.

185  {
186  if (verification) {
187  verify_samples_.AddSample(unichar, sample);
188  prev_unichar_id_ = -1;
189  } else if (unicharset_.contains_unichar(unichar)) {
190  if (prev_unichar_id_ >= 0)
191  fragments_[prev_unichar_id_] = -1;
192  prev_unichar_id_ = samples_.AddSample(unichar, sample);
193  if (flat_shapes_.FindShape(prev_unichar_id_, sample->font_id()) < 0)
194  flat_shapes_.AddShape(prev_unichar_id_, sample->font_id());
195  } else {
196  int junk_id = junk_samples_.AddSample(unichar, sample);
197  if (prev_unichar_id_ >= 0) {
199  if (frag != NULL && frag->is_natural()) {
200  if (fragments_[prev_unichar_id_] == 0)
201  fragments_[prev_unichar_id_] = junk_id;
202  else if (fragments_[prev_unichar_id_] != junk_id)
203  fragments_[prev_unichar_id_] = -1;
204  }
205  delete frag;
206  }
207  prev_unichar_id_ = -1;
208  }
209 }
int AddShape(int unichar_id, int font_id)
Definition: shapetable.cpp:249
bool is_natural() const
Definition: unicharset.h:95
Definition: cluster.h:32
#define NULL
Definition: host.h:144
int AddSample(const char *unichar, TrainingSample *sample)
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:543
static CHAR_FRAGMENT * parse_from_string(const char *str)
Definition: unicharset.cpp:902
int FindShape(int unichar_id, int font_id) const
Definition: shapetable.cpp:290
bool tesseract::MasterTrainer::AddSpacingInfo ( const char *  filename)

Definition at line 422 of file mastertrainer.cpp.

422  {
423  FILE* fontinfo_file = fopen(filename, "rb");
424  if (fontinfo_file == NULL)
425  return true; // We silently ignore missing files!
426  // Find the fontinfo_id.
427  int fontinfo_id = GetBestMatchingFontInfoId(filename);
428  if (fontinfo_id < 0) {
429  tprintf("No font found matching fontinfo filename %s\n", filename);
430  fclose(fontinfo_file);
431  return false;
432  }
433  tprintf("Reading spacing from %s for font %d...\n", filename, fontinfo_id);
434  // TODO(rays) scale should probably be a double, but keep as an int for now
435  // to duplicate current behavior.
436  int scale = kBlnXHeight / xheights_[fontinfo_id];
437  int num_unichars;
438  char uch[UNICHAR_LEN];
439  char kerned_uch[UNICHAR_LEN];
440  int x_gap, x_gap_before, x_gap_after, num_kerned;
441  ASSERT_HOST(fscanf(fontinfo_file, "%d\n", &num_unichars) == 1);
442  FontInfo *fi = fontinfo_table_.get_mutable(fontinfo_id);
443  fi->init_spacing(unicharset_.size());
444  FontSpacingInfo *spacing = NULL;
445  for (int l = 0; l < num_unichars; ++l) {
446  if (fscanf(fontinfo_file, "%s %d %d %d",
447  uch, &x_gap_before, &x_gap_after, &num_kerned) != 4) {
448  tprintf("Bad format of font spacing file %s\n", filename);
449  fclose(fontinfo_file);
450  return false;
451  }
452  bool valid = unicharset_.contains_unichar(uch);
453  if (valid) {
454  spacing = new FontSpacingInfo();
455  spacing->x_gap_before = static_cast<inT16>(x_gap_before * scale);
456  spacing->x_gap_after = static_cast<inT16>(x_gap_after * scale);
457  }
458  for (int k = 0; k < num_kerned; ++k) {
459  if (fscanf(fontinfo_file, "%s %d", kerned_uch, &x_gap) != 2) {
460  tprintf("Bad format of font spacing file %s\n", filename);
461  fclose(fontinfo_file);
462  return false;
463  }
464  if (!valid || !unicharset_.contains_unichar(kerned_uch)) continue;
465  spacing->kerned_unichar_ids.push_back(
466  unicharset_.unichar_to_id(kerned_uch));
467  spacing->kerned_x_gaps.push_back(static_cast<inT16>(x_gap * scale));
468  }
469  if (valid) fi->add_spacing(unicharset_.unichar_to_id(uch), spacing);
470  }
471  fclose(fontinfo_file);
472  return true;
473 }
const int kBlnXHeight
Definition: normalis.h:27
const UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:176
int size() const
Definition: unicharset.h:264
#define NULL
Definition: host.h:144
int GetBestMatchingFontInfoId(const char *filename)
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:543
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
short inT16
Definition: host.h:100
#define UNICHAR_LEN
Definition: unichar.h:28
#define ASSERT_HOST(x)
Definition: errcode.h:84
void tesseract::MasterTrainer::DebugCanonical ( const char *  unichar_str1,
const char *  unichar_str2 
)

Definition at line 640 of file mastertrainer.cpp.

641  {
642  int class_id1 = unicharset_.unichar_to_id(unichar_str1);
643  int class_id2 = unicharset_.unichar_to_id(unichar_str2);
644  if (class_id2 == INVALID_UNICHAR_ID)
645  class_id2 = class_id1;
646  if (class_id1 == INVALID_UNICHAR_ID) {
647  tprintf("No unicharset entry found for %s\n", unichar_str1);
648  return;
649  } else {
650  tprintf("Font ambiguities for unichar %d = %s and %d = %s\n",
651  class_id1, unichar_str1, class_id2, unichar_str2);
652  }
653  int num_fonts = samples_.NumFonts();
654  const IntFeatureMap& feature_map = feature_map_;
655  // Iterate the fonts to get the similarity with other fonst of the same
656  // class.
657  tprintf(" ");
658  for (int f = 0; f < num_fonts; ++f) {
659  if (samples_.NumClassSamples(f, class_id2, false) == 0)
660  continue;
661  tprintf("%6d", f);
662  }
663  tprintf("\n");
664  for (int f1 = 0; f1 < num_fonts; ++f1) {
665  // Map the features of the canonical_sample.
666  if (samples_.NumClassSamples(f1, class_id1, false) == 0)
667  continue;
668  tprintf("%4d ", f1);
669  for (int f2 = 0; f2 < num_fonts; ++f2) {
670  if (samples_.NumClassSamples(f2, class_id2, false) == 0)
671  continue;
672  float dist = samples_.ClusterDistance(f1, class_id1, f2, class_id2,
673  feature_map);
674  tprintf(" %5.3f", dist);
675  }
676  tprintf("\n");
677  }
678  // Build a fake ShapeTable containing all the sample types.
679  ShapeTable shapes(unicharset_);
680  for (int f = 0; f < num_fonts; ++f) {
681  if (samples_.NumClassSamples(f, class_id1, true) > 0)
682  shapes.AddShape(class_id1, f);
683  if (class_id1 != class_id2 &&
684  samples_.NumClassSamples(f, class_id2, true) > 0)
685  shapes.AddShape(class_id2, f);
686  }
687 }
const UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:176
float ClusterDistance(int font_id1, int class_id1, int font_id2, int class_id2, const IntFeatureMap &feature_map)
#define f(xc, yc)
Definition: imgscale.cpp:39
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
int NumClassSamples(int font_id, int class_id, bool randomize) const
bool tesseract::MasterTrainer::DeSerialize ( bool  swap,
FILE *  fp 
)

Definition at line 95 of file mastertrainer.cpp.

95  {
96  if (fread(&norm_mode_, sizeof(norm_mode_), 1, fp) != 1) return false;
97  if (swap) {
98  ReverseN(&norm_mode_, sizeof(norm_mode_));
99  }
100  if (!unicharset_.load_from_file(fp)) return false;
101  charsetsize_ = unicharset_.size();
102  if (!feature_space_.DeSerialize(swap, fp)) return false;
103  feature_map_.Init(feature_space_);
104  if (!samples_.DeSerialize(swap, fp)) return false;
105  if (!junk_samples_.DeSerialize(swap, fp)) return false;
106  if (!verify_samples_.DeSerialize(swap, fp)) return false;
107  if (!master_shapes_.DeSerialize(swap, fp)) return false;
108  if (!flat_shapes_.DeSerialize(swap, fp)) return false;
109  if (!fontinfo_table_.read(fp, NewPermanentTessCallback(read_info), swap))
110  return false;
111  if (!fontinfo_table_.read(fp, NewPermanentTessCallback(read_spacing_info),
112  swap))
113  return false;
114  if (!xheights_.DeSerialize(swap, fp)) return false;
115  return true;
116 }
bool DeSerialize(bool swap, FILE *fp)
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:126
int size() const
Definition: unicharset.h:264
virtual bool DeSerialize(bool swap, FILE *fp)
bool load_from_file(const char *const filename, bool skip_fragments)
Definition: unicharset.h:298
bool read_info(FILE *f, FontInfo *fi, bool swap)
Definition: fontinfo.cpp:57
bool DeSerialize(bool swap, FILE *fp)
Definition: shapetable.cpp:188
bool DeSerialize(bool swap, FILE *fp)
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
void Init(const IntFeatureSpace &feature_space)
bool read_spacing_info(FILE *f, FontInfo *fi, bool swap)
Definition: fontinfo.cpp:80
void tesseract::MasterTrainer::DisplaySamples ( const char *  unichar_str1,
int  cloud_font,
const char *  unichar_str2,
int  canonical_font 
)

Definition at line 700 of file mastertrainer.cpp.

702  {
703  const IntFeatureMap& feature_map = feature_map_;
704  const IntFeatureSpace& feature_space = feature_map.feature_space();
705  ScrollView* f_window = CreateFeatureSpaceWindow("Features", 100, 500);
707  f_window);
708  int class_id2 = samples_.unicharset().unichar_to_id(unichar_str2);
709  if (class_id2 != INVALID_UNICHAR_ID && canonical_font >= 0) {
710  const TrainingSample* sample = samples_.GetCanonicalSample(canonical_font,
711  class_id2);
712  for (int f = 0; f < sample->num_features(); ++f) {
713  RenderIntFeature(f_window, &sample->features()[f], ScrollView::RED);
714  }
715  }
716  int class_id1 = samples_.unicharset().unichar_to_id(unichar_str1);
717  if (class_id1 != INVALID_UNICHAR_ID && cloud_font >= 0) {
718  const BitVector& cloud = samples_.GetCloudFeatures(cloud_font, class_id1);
719  for (int f = 0; f < cloud.size(); ++f) {
720  if (cloud[f]) {
721  INT_FEATURE_STRUCT feature =
722  feature_map.InverseIndexFeature(f);
723  RenderIntFeature(f_window, &feature, ScrollView::GREEN);
724  }
725  }
726  }
727  f_window->Update();
728  ScrollView* s_window = CreateFeatureSpaceWindow("Samples", 100, 500);
729  SVEventType ev_type;
730  do {
731  SVEvent* ev;
732  // Wait until a click or popup event.
733  ev = f_window->AwaitEvent(SVET_ANY);
734  ev_type = ev->type;
735  if (ev_type == SVET_CLICK) {
736  int feature_index = feature_space.XYToFeatureIndex(ev->x, ev->y);
737  if (feature_index >= 0) {
738  // Iterate samples and display those with the feature.
739  Shape shape;
740  shape.AddToShape(class_id1, cloud_font);
741  s_window->Clear();
742  samples_.DisplaySamplesWithFeature(feature_index, shape,
743  feature_space, ScrollView::GREEN,
744  s_window);
745  s_window->Update();
746  }
747  }
748  delete ev;
749  } while (ev_type != SVET_DESTROY);
750 }
void DisplaySamplesWithFeature(int f_index, const Shape &shape, const IntFeatureSpace &feature_space, ScrollView::Color color, ScrollView *window) const
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:444
void Clear()
Definition: scrollview.cpp:590
const UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:176
Definition: cluster.h:32
#define f(xc, yc)
Definition: imgscale.cpp:39
SVEventType type
Definition: scrollview.h:64
int x
Definition: scrollview.h:66
static void Update()
Definition: scrollview.cpp:710
const UNICHARSET & unicharset() const
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:1132
const TrainingSample * GetCanonicalSample(int font_id, int class_id) const
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1822
SVEventType
Definition: scrollview.h:45
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1990
const BitVector & GetCloudFeatures(int font_id, int class_id) const
int y
Definition: scrollview.h:67
const IntFeatureSpace & feature_space() const
Definition: intfeaturemap.h:60
int tesseract::MasterTrainer::GetBestMatchingFontInfoId ( const char *  filename)

Definition at line 492 of file mastertrainer.cpp.

492  {
493  int fontinfo_id = -1;
494  int best_len = 0;
495  for (int f = 0; f < fontinfo_table_.size(); ++f) {
496  if (strstr(filename, fontinfo_table_.get(f).name) != NULL) {
497  int len = strlen(fontinfo_table_.get(f).name);
498  // Use the longest matching length in case a substring of a font matched.
499  if (len > best_len) {
500  best_len = len;
501  fontinfo_id = f;
502  }
503  }
504  }
505  return fontinfo_id;
506 }
#define NULL
Definition: host.h:144
#define f(xc, yc)
Definition: imgscale.cpp:39
int tesseract::MasterTrainer::GetFontInfoId ( const char *  font_name)

Definition at line 477 of file mastertrainer.cpp.

477  {
478  FontInfo fontinfo;
479  // We are only borrowing the string, so it is OK to const cast it.
480  fontinfo.name = const_cast<char*>(font_name);
481  fontinfo.properties = 0; // Not used to lookup in the table
482  fontinfo.universal_id = 0;
483  if (!fontinfo_table_.contains(fontinfo)) {
484  return -1;
485  } else {
486  return fontinfo_table_.get_id(fontinfo);
487  }
488 }
TrainingSampleSet* tesseract::MasterTrainer::GetSamples ( )
inline

Definition at line 185 of file mastertrainer.h.

185  {
186  return &samples_;
187  }
void tesseract::MasterTrainer::IncludeJunk ( )

Definition at line 312 of file mastertrainer.cpp.

312  {
313  // Get ids of fragments in junk_samples_ that replace the dead chars.
314  const UNICHARSET& junk_set = junk_samples_.unicharset();
315  const UNICHARSET& sample_set = samples_.unicharset();
316  int num_junks = junk_samples_.num_samples();
317  tprintf("Moving %d junk samples to master sample set.\n", num_junks);
318  for (int s = 0; s < num_junks; ++s) {
319  TrainingSample* sample = junk_samples_.mutable_sample(s);
320  int junk_id = sample->class_id();
321  const char* junk_utf8 = junk_set.id_to_unichar(junk_id);
322  int sample_id = sample_set.unichar_to_id(junk_utf8);
323  if (sample_id == INVALID_UNICHAR_ID)
324  sample_id = 0;
325  sample->set_class_id(sample_id);
326  junk_samples_.extract_sample(s);
327  samples_.AddSample(sample_id, sample);
328  }
329  junk_samples_.DeleteDeadSamples();
330  samples_.OrganizeByFontAndClass();
331 }
const char *const id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:233
const UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:176
Definition: cluster.h:32
int AddSample(const char *unichar, TrainingSample *sample)
const UNICHARSET & unicharset() const
UNICHAR_ID class_id() const
TrainingSample * mutable_sample(int index)
TrainingSample * extract_sample(int index)
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
bool tesseract::MasterTrainer::LoadFontInfo ( const char *  filename)

Definition at line 350 of file mastertrainer.cpp.

350  {
351  FILE* fp = fopen(filename, "rb");
352  if (fp == NULL) {
353  fprintf(stderr, "Failed to load font_properties from %s\n", filename);
354  return false;
355  }
356  int italic, bold, fixed, serif, fraktur;
357  while (!feof(fp)) {
358  FontInfo fontinfo;
359  char* font_name = new char[1024];
360  fontinfo.name = font_name;
361  fontinfo.properties = 0;
362  fontinfo.universal_id = 0;
363  if (fscanf(fp, "%1024s %i %i %i %i %i\n", font_name,
364  &italic, &bold, &fixed, &serif, &fraktur) != 6)
365  continue;
366  fontinfo.properties =
367  (italic << 0) +
368  (bold << 1) +
369  (fixed << 2) +
370  (serif << 3) +
371  (fraktur << 4);
372  if (!fontinfo_table_.contains(fontinfo)) {
373  fontinfo_table_.push_back(fontinfo);
374  }
375  }
376  fclose(fp);
377  return true;
378 }
#define NULL
Definition: host.h:144
void tesseract::MasterTrainer::LoadPageImages ( const char *  filename)

Definition at line 214 of file mastertrainer.cpp.

214  {
215  int page;
216  Pix* pix;
217  for (page = 0; (pix = pixReadTiff(filename, page)) != NULL; ++page) {
218  page_images_.push_back(pix);
219  }
220  tprintf("Loaded %d page images from %s\n", page, filename);
221 }
#define NULL
Definition: host.h:144
int push_back(T object)
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
void tesseract::MasterTrainer::LoadUnicharset ( const char *  filename)

Definition at line 119 of file mastertrainer.cpp.

119  {
120  if (!unicharset_.load_from_file(filename)) {
121  tprintf("Failed to load unicharset from file %s\n"
122  "Building unicharset for training from scratch...\n",
123  filename);
124  unicharset_.clear();
125  // Space character needed to represent NIL_LIST classification.
126  unicharset_.unichar_insert(" ");
127  }
128  charsetsize_ = unicharset_.size();
129  delete [] fragments_;
130  fragments_ = new int[charsetsize_];
131  memset(fragments_, 0, sizeof(*fragments_) * charsetsize_);
132  samples_.LoadUnicharset(filename);
133  junk_samples_.LoadUnicharset(filename);
134  verify_samples_.LoadUnicharset(filename);
135 }
int size() const
Definition: unicharset.h:264
void clear()
Definition: unicharset.h:233
bool load_from_file(const char *const filename, bool skip_fragments)
Definition: unicharset.h:298
void LoadUnicharset(const char *filename)
void unichar_insert(const char *const unichar_repr)
Definition: unicharset.cpp:511
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
bool tesseract::MasterTrainer::LoadXHeights ( const char *  filename)

Definition at line 382 of file mastertrainer.cpp.

382  {
383  tprintf("fontinfo table is of size %d\n", fontinfo_table_.size());
384  xheights_.init_to_size(fontinfo_table_.size(), -1);
385  if (filename == NULL) return true;
386  FILE *f = fopen(filename, "rb");
387  if (f == NULL) {
388  fprintf(stderr, "Failed to load font xheights from %s\n", filename);
389  return false;
390  }
391  tprintf("Reading x-heights from %s ...\n", filename);
392  FontInfo fontinfo;
393  fontinfo.properties = 0; // Not used to lookup in the table.
394  fontinfo.universal_id = 0;
395  char buffer[1024];
396  int xht;
397  int total_xheight = 0;
398  int xheight_count = 0;
399  while (!feof(f)) {
400  if (fscanf(f, "%1024s %d\n", buffer, &xht) != 2)
401  continue;
402  fontinfo.name = buffer;
403  if (!fontinfo_table_.contains(fontinfo)) continue;
404  int fontinfo_id = fontinfo_table_.get_id(fontinfo);
405  xheights_[fontinfo_id] = xht;
406  total_xheight += xht;
407  ++xheight_count;
408  }
409  if (xheight_count == 0) {
410  fprintf(stderr, "No valid xheights in %s!\n", filename);
411  return false;
412  }
413  int mean_xheight = DivRounded(total_xheight, xheight_count);
414  for (int i = 0; i < fontinfo_table_.size(); ++i) {
415  if (xheights_[i] < 0)
416  xheights_[i] = mean_xheight;
417  }
418  return true;
419 } // LoadXHeights
#define NULL
Definition: host.h:144
int DivRounded(int a, int b)
Definition: helpers.h:115
#define f(xc, yc)
Definition: imgscale.cpp:39
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
void init_to_size(int size, T t)
const ShapeTable& tesseract::MasterTrainer::master_shapes ( ) const
inline

Definition at line 188 of file mastertrainer.h.

188  {
189  return master_shapes_;
190  }
void tesseract::MasterTrainer::PostLoadCleanup ( )

Definition at line 228 of file mastertrainer.cpp.

228  {
229  if (debug_level_ > 0)
230  tprintf("PostLoadCleanup...\n");
231  if (enable_shape_anaylsis_)
232  ReplaceFragmentedSamples();
233  SampleIterator sample_it;
234  sample_it.Init(NULL, NULL, true, &verify_samples_);
235  sample_it.NormalizeSamples();
236  verify_samples_.OrganizeByFontAndClass();
237 
238  samples_.IndexFeatures(feature_space_);
239  // TODO(rays) DeleteOutliers is currently turned off to prove NOP-ness
240  // against current training.
241  // samples_.DeleteOutliers(feature_space_, debug_level_ > 0);
242  samples_.OrganizeByFontAndClass();
243  if (debug_level_ > 0)
244  tprintf("ComputeCanonicalSamples...\n");
245  samples_.ComputeCanonicalSamples(feature_map_, debug_level_ > 0);
246 }
void ComputeCanonicalSamples(const IntFeatureMap &map, bool debug)
#define NULL
Definition: host.h:144
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
void IndexFeatures(const IntFeatureSpace &feature_space)
void tesseract::MasterTrainer::PreTrainingSetup ( )

Definition at line 251 of file mastertrainer.cpp.

251  {
252  if (debug_level_ > 0)
253  tprintf("PreTrainingSetup...\n");
254  samples_.IndexFeatures(feature_space_);
255  samples_.ComputeCanonicalFeatures();
256  if (debug_level_ > 0)
257  tprintf("ComputeCloudFeatures...\n");
258  samples_.ComputeCloudFeatures(feature_space_.Size());
259 }
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
void IndexFeatures(const IntFeatureSpace &feature_space)
void ComputeCloudFeatures(int feature_space_size)
void tesseract::MasterTrainer::ReadTrainingSamples ( FILE *  fp,
const FEATURE_DEFS_STRUCT feature_defs,
bool  verification 
)

Definition at line 141 of file mastertrainer.cpp.

143  {
144  char buffer[2048];
145  int int_feature_type = ShortNameToFeatureType(feature_defs, kIntFeatureType);
146  int micro_feature_type = ShortNameToFeatureType(feature_defs,
148  int cn_feature_type = ShortNameToFeatureType(feature_defs, kCNFeatureType);
149  int geo_feature_type = ShortNameToFeatureType(feature_defs, kGeoFeatureType);
150 
151  while (fgets(buffer, sizeof(buffer), fp) != NULL) {
152  if (buffer[0] == '\n')
153  continue;
154 
155  char* space = strchr(buffer, ' ');
156  if (space == NULL) {
157  tprintf("Bad format in tr file, reading fontname, unichar\n");
158  continue;
159  }
160  *space++ = '\0';
161  int font_id = GetFontInfoId(buffer);
162  int page_number;
163  STRING unichar;
164  TBOX bounding_box;
165  if (!ParseBoxFileStr(space, &page_number, &unichar, &bounding_box)) {
166  tprintf("Bad format in tr file, reading box coords\n");
167  continue;
168  }
169  CHAR_DESC char_desc = ReadCharDescription(feature_defs, fp);
170  TrainingSample* sample = new TrainingSample;
171  sample->set_font_id(font_id);
172  sample->set_page_num(page_number + page_images_.size());
173  sample->set_bounding_box(bounding_box);
174  sample->ExtractCharDesc(int_feature_type, micro_feature_type,
175  cn_feature_type, geo_feature_type, char_desc);
176  AddSample(verification, unichar.string(), sample);
177  FreeCharDescription(char_desc);
178  }
179  charsetsize_ = unicharset_.size();
180 }
bool ParseBoxFileStr(const char *boxfile_str, int *page_number, STRING *utf8_str, TBOX *bounding_box)
Definition: boxread.cpp:105
int size() const
Definition: unicharset.h:264
const char * kGeoFeatureType
Definition: featdefs.cpp:44
Definition: cluster.h:32
const char * kCNFeatureType
Definition: featdefs.cpp:42
#define NULL
Definition: host.h:144
Definition: rect.h:29
void AddSample(bool verification, const char *unichar_str, TrainingSample *sample)
const char * kMicroFeatureType
Definition: featdefs.cpp:41
CHAR_DESC ReadCharDescription(const FEATURE_DEFS_STRUCT &FeatureDefs, FILE *File)
Definition: featdefs.cpp:261
const char * string() const
Definition: strngs.cpp:156
const char * kIntFeatureType
Definition: featdefs.cpp:43
void FreeCharDescription(CHAR_DESC CharDesc)
Definition: featdefs.cpp:141
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
Definition: strngs.h:40
int size() const
Definition: genericvector.h:59
int GetFontInfoId(const char *font_name)
int ShortNameToFeatureType(const FEATURE_DEFS_STRUCT &FeatureDefs, const char *ShortName)
Definition: featdefs.cpp:300
void tesseract::MasterTrainer::ReplicateAndRandomizeSamplesIfRequired ( )

Definition at line 338 of file mastertrainer.cpp.

338  {
339  if (enable_replication_) {
340  if (debug_level_ > 0)
341  tprintf("ReplicateAndRandomize...\n");
342  verify_samples_.ReplicateAndRandomizeSamples();
343  samples_.ReplicateAndRandomizeSamples();
344  samples_.IndexFeatures(feature_space_);
345  }
346 }
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
void IndexFeatures(const IntFeatureSpace &feature_space)
bool tesseract::MasterTrainer::Serialize ( FILE *  fp) const

Definition at line 76 of file mastertrainer.cpp.

76  {
77  if (fwrite(&norm_mode_, sizeof(norm_mode_), 1, fp) != 1) return false;
78  if (!unicharset_.save_to_file(fp)) return false;
79  if (!feature_space_.Serialize(fp)) return false;
80  if (!samples_.Serialize(fp)) return false;
81  if (!junk_samples_.Serialize(fp)) return false;
82  if (!verify_samples_.Serialize(fp)) return false;
83  if (!master_shapes_.Serialize(fp)) return false;
84  if (!flat_shapes_.Serialize(fp)) return false;
85  if (!fontinfo_table_.write(fp, NewPermanentTessCallback(write_info)))
86  return false;
87  if (!fontinfo_table_.write(fp, NewPermanentTessCallback(write_spacing_info)))
88  return false;
89  if (!xheights_.Serialize(fp)) return false;
90  return true;
91 }
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:72
bool Serialize(FILE *fp) const
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:112
bool Serialize(FILE *fp) const
bool Serialize(FILE *fp) const
Definition: shapetable.cpp:182
virtual bool Serialize(FILE *fp) const
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
bool save_to_file(const char *const filename) const
Definition: unicharset.h:273
void tesseract::MasterTrainer::SetFeatureSpace ( const IntFeatureSpace fs)
inline

Definition at line 84 of file mastertrainer.h.

84  {
85  feature_space_ = fs;
86  feature_map_.Init(fs);
87  }
void Init(const IntFeatureSpace &feature_space)
void tesseract::MasterTrainer::SetupFlatShapeTable ( ShapeTable shape_table)

Definition at line 509 of file mastertrainer.cpp.

509  {
510  // To exactly mimic the results of the previous implementation, the shapes
511  // must be clustered in order the fonts arrived, and reverse order of the
512  // characters within each font.
513  // Get a list of the fonts in the order they appeared.
514  GenericVector<int> active_fonts;
515  int num_shapes = flat_shapes_.NumShapes();
516  for (int s = 0; s < num_shapes; ++s) {
517  int font = flat_shapes_.GetShape(s)[0].font_ids[0];
518  int f = 0;
519  for (f = 0; f < active_fonts.size(); ++f) {
520  if (active_fonts[f] == font)
521  break;
522  }
523  if (f == active_fonts.size())
524  active_fonts.push_back(font);
525  }
526  // For each font in order, add all the shapes with that font in reverse order.
527  int num_fonts = active_fonts.size();
528  for (int f = 0; f < num_fonts; ++f) {
529  for (int s = num_shapes - 1; s >= 0; --s) {
530  int font = flat_shapes_.GetShape(s)[0].font_ids[0];
531  if (font == active_fonts[f]) {
532  shape_table->AddShape(flat_shapes_.GetShape(s));
533  }
534  }
535  }
536 }
int NumShapes() const
Definition: shapetable.h:140
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:179
#define f(xc, yc)
Definition: imgscale.cpp:39
int push_back(T object)
void AddShape(const Shape &other)
Definition: shapetable.cpp:94
int size() const
Definition: genericvector.h:59
CLUSTERER * tesseract::MasterTrainer::SetupForClustering ( const ShapeTable shape_table,
const FEATURE_DEFS_STRUCT feature_defs,
int  shape_id,
int *  num_samples 
)

Definition at line 540 of file mastertrainer.cpp.

544  {
545 
546  int desc_index = ShortNameToFeatureType(feature_defs, kMicroFeatureType);
547  int num_params = feature_defs.FeatureDesc[desc_index]->NumParams;
548  ASSERT_HOST(num_params == MFCount);
549  CLUSTERER* clusterer = MakeClusterer(
550  num_params, feature_defs.FeatureDesc[desc_index]->ParamDesc);
551 
552  // We want to iterate over the samples of just the one shape.
553  IndexMapBiDi shape_map;
554  shape_map.Init(shape_table.NumShapes(), false);
555  shape_map.SetMap(shape_id, true);
556  shape_map.Setup();
557  // Reverse the order of the samples to match the previous behavior.
559  SampleIterator it;
560  it.Init(&shape_map, &shape_table, false, &samples_);
561  for (it.Begin(); !it.AtEnd(); it.Next()) {
562  sample_ptrs.push_back(&it.GetSample());
563  }
564  int sample_id = 0;
565  for (int i = sample_ptrs.size() - 1; i >= 0; --i) {
566  const TrainingSample* sample = sample_ptrs[i];
567  int num_features = sample->num_micro_features();
568  for (int f = 0; f < num_features; ++f)
569  MakeSample(clusterer, sample->micro_features()[f], sample_id);
570  ++sample_id;
571  }
572  *num_samples = sample_id;
573  return clusterer;
574 }
Definition: cluster.h:32
#define f(xc, yc)
Definition: imgscale.cpp:39
int push_back(T object)
SAMPLE * MakeSample(CLUSTERER *Clusterer, const FLOAT32 *Feature, inT32 CharID)
Definition: cluster.cpp:450
const char * kMicroFeatureType
Definition: featdefs.cpp:41
const FEATURE_DESC_STRUCT * FeatureDesc[NUM_FEATURE_TYPES]
Definition: featdefs.h:50
CLUSTERER * MakeClusterer(inT16 SampleSize, const PARAM_DESC ParamDesc[])
Definition: cluster.cpp:395
Definition: mf.h:30
int size() const
Definition: genericvector.h:59
const PARAM_DESC * ParamDesc
Definition: ocrfeatures.h:58
#define ASSERT_HOST(x)
Definition: errcode.h:84
int ShortNameToFeatureType(const FEATURE_DEFS_STRUCT &FeatureDefs, const char *ShortName)
Definition: featdefs.cpp:300
void tesseract::MasterTrainer::SetupMasterShapes ( )

Definition at line 263 of file mastertrainer.cpp.

263  {
264  tprintf("Building master shape table\n");
265  int num_fonts = samples_.NumFonts();
266 
267  ShapeTable char_shapes_begin_fragment(samples_.unicharset());
268  ShapeTable char_shapes_end_fragment(samples_.unicharset());
269  ShapeTable char_shapes(samples_.unicharset());
270  for (int c = 0; c < samples_.charsetsize(); ++c) {
271  ShapeTable shapes(samples_.unicharset());
272  for (int f = 0; f < num_fonts; ++f) {
273  if (samples_.NumClassSamples(f, c, true) > 0)
274  shapes.AddShape(c, f);
275  }
276  ClusterShapes(kMinClusteredShapes, 1, kFontMergeDistance, &shapes);
277 
278  const CHAR_FRAGMENT *fragment = samples_.unicharset().get_fragment(c);
279 
280  if (fragment == NULL)
281  char_shapes.AppendMasterShapes(shapes);
282  else if (fragment->is_beginning())
283  char_shapes_begin_fragment.AppendMasterShapes(shapes);
284  else if (fragment->is_ending())
285  char_shapes_end_fragment.AppendMasterShapes(shapes);
286  else
287  char_shapes.AppendMasterShapes(shapes);
288  }
290  kFontMergeDistance, &char_shapes_begin_fragment);
291  char_shapes.AppendMasterShapes(char_shapes_begin_fragment);
293  kFontMergeDistance, &char_shapes_end_fragment);
294  char_shapes.AppendMasterShapes(char_shapes_end_fragment);
296  kFontMergeDistance, &char_shapes);
297  master_shapes_.AppendMasterShapes(char_shapes);
298  tprintf("Master shape_table:%s\n", master_shapes_.SummaryStr().string());
299 }
const int kMaxUnicharsPerCluster
#define NULL
Definition: host.h:144
#define f(xc, yc)
Definition: imgscale.cpp:39
void AppendMasterShapes(const ShapeTable &other)
Definition: shapetable.cpp:439
const UNICHARSET & unicharset() const
const CHAR_FRAGMENT * get_fragment(UNICHAR_ID unichar_id) const
Definition: unicharset.h:610
const char * string() const
Definition: strngs.cpp:156
bool is_ending() const
Definition: unicharset.h:90
const float kFontMergeDistance
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
const int kMinClusteredShapes
int NumClassSamples(int font_id, int class_id, bool randomize) const
STRING SummaryStr() const
Definition: shapetable.cpp:226
bool is_beginning() const
Definition: unicharset.h:87
float tesseract::MasterTrainer::ShapeDistance ( const ShapeTable shapes,
int  s1,
int  s2 
)

Definition at line 802 of file mastertrainer.cpp.

802  {
803  const IntFeatureMap& feature_map = feature_map_;
804  const Shape& shape1 = shapes.GetShape(s1);
805  const Shape& shape2 = shapes.GetShape(s2);
806  int num_chars1 = shape1.size();
807  int num_chars2 = shape2.size();
808  float dist_sum = 0.0f;
809  int dist_count = 0;
810  if (num_chars1 > 1 || num_chars2 > 1) {
811  // In the multi-char case try to optimize the calculation by computing
812  // distances between characters of matching font where possible.
813  for (int c1 = 0; c1 < num_chars1; ++c1) {
814  for (int c2 = 0; c2 < num_chars2; ++c2) {
815  dist_sum += samples_.UnicharDistance(shape1[c1], shape2[c2],
816  true, feature_map);
817  ++dist_count;
818  }
819  }
820  } else {
821  // In the single unichar case, there is little alternative, but to compute
822  // the squared-order distance between pairs of fonts.
823  dist_sum = samples_.UnicharDistance(shape1[0], shape2[0],
824  false, feature_map);
825  ++dist_count;
826  }
827  return dist_sum / dist_count;
828 }
float UnicharDistance(const UnicharAndFonts &uf1, const UnicharAndFonts &uf2, bool matched_fonts, const IntFeatureMap &feature_map)
double tesseract::MasterTrainer::TestClassifier ( int  report_level,
bool  replicate_samples,
TrainingSampleSet samples,
ShapeClassifier test_classifier,
STRING report_string 
)

Definition at line 775 of file mastertrainer.cpp.

779  {
780  SampleIterator sample_it;
781  sample_it.Init(NULL, test_classifier->GetShapeTable(), replicate_samples,
782  samples);
783  if (report_level > 0) {
784  int num_samples = 0;
785  for (sample_it.Begin(); !sample_it.AtEnd(); sample_it.Next())
786  ++num_samples;
787  tprintf("Iterator has charset size of %d/%d, %d shapes, %d samples\n",
788  sample_it.SparseCharsetSize(), sample_it.CompactCharsetSize(),
789  test_classifier->GetShapeTable()->NumShapes(), num_samples);
790  tprintf("Testing %sREPLICATED:\n", replicate_samples ? "" : "NON-");
791  }
792  double unichar_error = 0.0;
793  ErrorCounter::ComputeErrorRate(test_classifier, report_level,
794  CT_SHAPE_TOP_ERR, fontinfo_table_,
795  page_images_, &sample_it, &unichar_error,
796  NULL, report_string);
797  return unichar_error;
798 }
#define NULL
Definition: host.h:144
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:41
static double ComputeErrorRate(ShapeClassifier *classifier, int report_level, CountTypes boosting_mode, const UnicityTable< FontInfo > &fontinfo_table, const GenericVector< Pix * > &page_images, SampleIterator *it, double *unichar_error, double *scaled_error, STRING *fonts_report)
void tesseract::MasterTrainer::TestClassifierOnSamples ( int  report_level,
bool  replicate_samples,
ShapeClassifier test_classifier,
STRING report_string 
)

Definition at line 755 of file mastertrainer.cpp.

758  {
759  TestClassifier(report_level, replicate_samples, &samples_,
760  test_classifier, report_string);
761 }
double TestClassifier(int report_level, bool replicate_samples, TrainingSampleSet *samples, ShapeClassifier *test_classifier, STRING *report_string)
const UNICHARSET& tesseract::MasterTrainer::unicharset ( ) const
inline

Definition at line 182 of file mastertrainer.h.

182  {
183  return samples_.unicharset();
184  }
const UNICHARSET & unicharset() const
void tesseract::MasterTrainer::WriteInttempAndPFFMTable ( const UNICHARSET unicharset,
const UNICHARSET shape_set,
const ShapeTable shape_table,
CLASS_STRUCT float_classes,
const char *  inttemp_file,
const char *  pffmtable_file 
)

Definition at line 580 of file mastertrainer.cpp.

585  {
586  tesseract::Classify *classify = new tesseract::Classify();
587  // Move the fontinfo table to classify.
588  classify->get_fontinfo_table().move(&fontinfo_table_);
589  INT_TEMPLATES int_templates = classify->CreateIntTemplates(float_classes,
590  shape_set);
591  FILE* fp = fopen(inttemp_file, "wb");
592  classify->WriteIntTemplates(fp, int_templates, shape_set);
593  fclose(fp);
594  // Now write pffmtable. This is complicated by the fact that the adaptive
595  // classifier still wants one indexed by unichar-id, but the static
596  // classifier needs one indexed by its shape class id.
597  // We put the shapetable_cutoffs in a GenericVector, and compute the
598  // unicharset cutoffs along the way.
599  GenericVector<uinT16> shapetable_cutoffs;
600  GenericVector<uinT16> unichar_cutoffs;
601  for (int c = 0; c < unicharset.size(); ++c)
602  unichar_cutoffs.push_back(0);
603  /* then write out each class */
604  for (int i = 0; i < int_templates->NumClasses; ++i) {
605  INT_CLASS Class = ClassForClassId(int_templates, i);
606  // Todo: Test with min instead of max
607  // int MaxLength = LengthForConfigId(Class, 0);
608  uinT16 max_length = 0;
609  for (int config_id = 0; config_id < Class->NumConfigs; config_id++) {
610  // Todo: Test with min instead of max
611  // if (LengthForConfigId (Class, config_id) < MaxLength)
612  uinT16 length = Class->ConfigLengths[config_id];
613  if (length > max_length)
614  max_length = Class->ConfigLengths[config_id];
615  int shape_id = float_classes[i].font_set.get(config_id);
616  const Shape& shape = shape_table.GetShape(shape_id);
617  for (int c = 0; c < shape.size(); ++c) {
618  int unichar_id = shape[c].unichar_id;
619  if (length > unichar_cutoffs[unichar_id])
620  unichar_cutoffs[unichar_id] = length;
621  }
622  }
623  shapetable_cutoffs.push_back(max_length);
624  }
625  fp = fopen(pffmtable_file, "wb");
626  shapetable_cutoffs.Serialize(fp);
627  for (int c = 0; c < unicharset.size(); ++c) {
628  const char *unichar = unicharset.id_to_unichar(c);
629  if (strcmp(unichar, " ") == 0) {
630  unichar = "NULL";
631  }
632  fprintf(fp, "%s %d\n", unichar, unichar_cutoffs[c]);
633  }
634  fclose(fp);
635  free_int_templates(int_templates);
636 }
const char *const id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:233
int size() const
Definition: unicharset.h:264
#define ClassForClassId(T, c)
Definition: intproto.h:173
uinT8 NumConfigs
Definition: intproto.h:108
int push_back(T object)
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:774
UnicityTableEqEq< int > font_set
Definition: protos.h:65
const T & get(int id) const
Return the object from an id.
UnicityTable< FontInfo > & get_fontinfo_table()
Definition: classify.h:336
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1155
virtual bool Serialize(FILE *fp) const
unsigned short uinT16
Definition: host.h:101
uinT16 ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:111
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:573

The documentation for this class was generated from the following files: