24
24
#endif
25
25
26
26
#include < ctype.h>
27
- #include " shapeclassifier.h"
28
27
#include " ambigs.h"
29
28
#include " blobclass.h"
30
29
#include " blobs.h"
31
- #include " helpers.h"
32
- #include " normfeat.h"
33
- #include " mfoutline.h"
34
- #include " picofeat.h"
35
- #include " float2int.h"
36
- #include " outfeat.h"
30
+ #include " callcpp.h"
31
+ #include " classify.h"
32
+ #include " const.h"
33
+ #include " dict.h"
34
+ #include " efio.h"
37
35
#include " emalloc.h"
36
+ #include " featdefs.h"
37
+ #include " float2int.h"
38
+ #include " genericvector.h"
39
+ #include " globals.h"
40
+ #include " helpers.h"
38
41
#include " intfx.h"
39
- #include " efio.h"
40
- #include " normmatch.h"
41
- #include " ndminx.h"
42
42
#include " intproto.h"
43
- #include " const.h"
44
- #include " globals.h"
45
- #include " werd.h"
46
- #include " callcpp.h"
43
+ #include " mfoutline.h"
44
+ #include " ndminx.h"
45
+ #include " normfeat.h"
46
+ #include " normmatch.h"
47
+ #include " outfeat.h"
47
48
#include " pageres.h"
48
49
#include " params.h"
49
- #include " classify.h"
50
+ #include " picofeat.h"
51
+ #include " shapeclassifier.h"
50
52
#include " shapetable.h"
51
53
#include " tessclassifier.h"
52
54
#include " trainingsample.h"
53
55
#include " unicharset.h"
54
- #include " dict.h"
55
- #include " featdefs.h"
56
- #include " genericvector.h"
56
+ #include " werd.h"
57
57
58
58
#include < stdio.h>
59
59
#include < string.h>
@@ -420,7 +420,13 @@ void Classify::LearnPieces(const char* fontname, int start, int length,
420
420
unicharset.id_to_unichar (class_id), threshold, font_id);
421
421
// If filename is not NULL we are doing recognition
422
422
// (as opposed to training), so we must have already set word fonts.
423
- AdaptToChar (rotated_blob, class_id, font_id, threshold);
423
+ AdaptToChar (rotated_blob, class_id, font_id, threshold, AdaptedTemplates);
424
+ if (BackupAdaptedTemplates != NULL ) {
425
+ // Adapt the backup templates too. They will be used if the primary gets
426
+ // too full.
427
+ AdaptToChar (rotated_blob, class_id, font_id, threshold,
428
+ BackupAdaptedTemplates);
429
+ }
424
430
} else if (classify_debug_level >= 1 ) {
425
431
tprintf (" Can't adapt to %s not in unicharset\n " , correct_text);
426
432
}
@@ -470,6 +476,10 @@ void Classify::EndAdaptiveClassifier() {
470
476
free_adapted_templates (AdaptedTemplates);
471
477
AdaptedTemplates = NULL ;
472
478
}
479
+ if (BackupAdaptedTemplates != NULL ) {
480
+ free_adapted_templates (BackupAdaptedTemplates);
481
+ BackupAdaptedTemplates = NULL ;
482
+ }
473
483
474
484
if (PreTrainedTemplates != NULL ) {
475
485
free_int_templates (PreTrainedTemplates);
@@ -607,10 +617,35 @@ void Classify::ResetAdaptiveClassifierInternal() {
607
617
}
608
618
free_adapted_templates (AdaptedTemplates);
609
619
AdaptedTemplates = NewAdaptedTemplates (true );
620
+ if (BackupAdaptedTemplates != NULL )
621
+ free_adapted_templates (BackupAdaptedTemplates);
622
+ BackupAdaptedTemplates = NULL ;
610
623
NumAdaptationsFailed = 0 ;
611
624
}
612
625
626
+ // If there are backup adapted templates, switches to those, otherwise resets
627
+ // the main adaptive classifier (because it is full.)
628
+ void Classify::SwitchAdaptiveClassifier () {
629
+ if (BackupAdaptedTemplates == NULL ) {
630
+ ResetAdaptiveClassifierInternal ();
631
+ return ;
632
+ }
633
+ if (classify_learning_debug_level > 0 ) {
634
+ tprintf (" Switch to backup adaptive classifier (NumAdaptationsFailed=%d)\n " ,
635
+ NumAdaptationsFailed);
636
+ }
637
+ free_adapted_templates (AdaptedTemplates);
638
+ AdaptedTemplates = BackupAdaptedTemplates;
639
+ BackupAdaptedTemplates = NULL ;
640
+ NumAdaptationsFailed = 0 ;
641
+ }
613
642
643
+ // Resets the backup adaptive classifier to empty.
644
+ void Classify::StartBackupAdaptiveClassifier () {
645
+ if (BackupAdaptedTemplates != NULL )
646
+ free_adapted_templates (BackupAdaptedTemplates);
647
+ BackupAdaptedTemplates = NewAdaptedTemplates (true );
648
+ }
614
649
615
650
/* ---------------------------------------------------------------------------*/
616
651
/* *
@@ -839,20 +874,19 @@ bool Classify::AdaptableWord(WERD_RES* word) {
839
874
* @param ClassId class to add blob to
840
875
* @param FontinfoId font information from pre-trained templates
841
876
* @param Threshold minimum match rating to existing template
877
+ * @param adaptive_templates current set of adapted templates
842
878
*
843
879
* Globals:
844
- * - AdaptedTemplates current set of adapted templates
845
880
* - AllProtosOn dummy mask to match against all protos
846
881
* - AllConfigsOn dummy mask to match against all configs
847
882
*
848
883
* @return none
849
884
* @note Exceptions: none
850
885
* @note History: Thu Mar 14 09:36:03 1991, DSJ, Created.
851
886
*/
852
- void Classify::AdaptToChar (TBLOB *Blob,
853
- CLASS_ID ClassId,
854
- int FontinfoId,
855
- FLOAT32 Threshold) {
887
+ void Classify::AdaptToChar (TBLOB* Blob, CLASS_ID ClassId, int FontinfoId,
888
+ FLOAT32 Threshold,
889
+ ADAPT_TEMPLATES adaptive_templates) {
856
890
int NumFeatures;
857
891
INT_FEATURE_ARRAY IntFeatures;
858
892
UnicharRating int_result;
@@ -866,12 +900,12 @@ void Classify::AdaptToChar(TBLOB *Blob,
866
900
return ;
867
901
868
902
int_result.unichar_id = ClassId;
869
- Class = AdaptedTemplates ->Class [ClassId];
903
+ Class = adaptive_templates ->Class [ClassId];
870
904
assert (Class != NULL );
871
905
if (IsEmptyAdaptedClass (Class)) {
872
- InitAdaptedClass (Blob, ClassId, FontinfoId, Class, AdaptedTemplates );
906
+ InitAdaptedClass (Blob, ClassId, FontinfoId, Class, adaptive_templates );
873
907
} else {
874
- IClass = ClassForClassId (AdaptedTemplates ->Templates , ClassId);
908
+ IClass = ClassForClassId (adaptive_templates ->Templates , ClassId);
875
909
876
910
NumFeatures = GetAdaptiveFeatures (Blob, IntFeatures, &FloatFeatures);
877
911
if (NumFeatures <= 0 )
@@ -913,7 +947,7 @@ void Classify::AdaptToChar(TBLOB *Blob,
913
947
int_result.config , TempConfig->NumTimesSeen );
914
948
915
949
if (TempConfigReliable (ClassId, TempConfig)) {
916
- MakePermanent (AdaptedTemplates , ClassId, int_result.config , Blob);
950
+ MakePermanent (adaptive_templates , ClassId, int_result.config , Blob);
917
951
UpdateAmbigsGroup (ClassId, Blob);
918
952
}
919
953
} else {
@@ -923,15 +957,12 @@ void Classify::AdaptToChar(TBLOB *Blob,
923
957
if (classify_learning_debug_level > 2 )
924
958
DisplayAdaptedChar (Blob, IClass);
925
959
}
926
- NewTempConfigId = MakeNewTemporaryConfig (AdaptedTemplates,
927
- ClassId,
928
- FontinfoId,
929
- NumFeatures,
930
- IntFeatures,
931
- FloatFeatures);
960
+ NewTempConfigId =
961
+ MakeNewTemporaryConfig (adaptive_templates, ClassId, FontinfoId,
962
+ NumFeatures, IntFeatures, FloatFeatures);
932
963
if (NewTempConfigId >= 0 &&
933
964
TempConfigReliable (ClassId, TempConfigFor (Class, NewTempConfigId))) {
934
- MakePermanent (AdaptedTemplates , ClassId, NewTempConfigId, Blob);
965
+ MakePermanent (adaptive_templates , ClassId, NewTempConfigId, Blob);
935
966
UpdateAmbigsGroup (ClassId, Blob);
936
967
}
937
968
@@ -1547,7 +1578,7 @@ void Classify::DebugAdaptiveClassifier(TBLOB *blob,
1547
1578
* Globals:
1548
1579
* - PreTrainedTemplates built-in training templates
1549
1580
* - AdaptedTemplates templates adapted for this page
1550
- * - matcher_great_threshold rating limit for a great match
1581
+ * - matcher_reliable_adaptive_result rating limit for a great match
1551
1582
*
1552
1583
* @note Exceptions: none
1553
1584
* @note History: Tue Mar 12 08:50:11 1991, DSJ, Created.
@@ -1569,7 +1600,8 @@ void Classify::DoAdaptiveMatch(TBLOB *Blob, ADAPT_RESULTS *Results) {
1569
1600
Ambiguities = BaselineClassifier (Blob, bl_features, fx_info,
1570
1601
AdaptedTemplates, Results);
1571
1602
if ((!Results->match .empty () &&
1572
- MarginalMatch (Results->best_rating , matcher_great_threshold) &&
1603
+ MarginalMatch (Results->best_rating ,
1604
+ matcher_reliable_adaptive_result) &&
1573
1605
!tess_bn_matching) ||
1574
1606
Results->match .empty ()) {
1575
1607
CharNormClassifier (Blob, *sample, Results);
0 commit comments