MCPcopy Create free account
hub / github.com/creatale/node-dv / GeometricClassify

Function GeometricClassify

deps/tesseract/ccmain/paragraphs.cpp:1077–1210  ·  view source on GitHub ↗

This function is called if strong textual clues were not available, but the caller hopes that the paragraph breaks will be super obvious just by the outline of the text. The particularly difficult case is figuring out what's going on if you don't have enough short paragraph end lines to tell us what's going on. For instance, let's say you have the following outline: (A1) xxxxxxxxxxxxxxxxxxxxxx

Source from the content-addressed store, hash-verified

1075// it's worth guessing that (A1b) is the correct interpretation if there are
1076// far more "full" lines than "short" lines.
1077void GeometricClassify(int debug_level,
1078 GenericVector<RowScratchRegisters> *rows,
1079 int row_start, int row_end,
1080 ParagraphTheory *theory) {
1081 if (!AcceptableRowArgs(debug_level, 4, __func__, rows, row_start, row_end))
1082 return;
1083 if (debug_level > 1) {
1084 tprintf("###############################################\n");
1085 tprintf("##### GeometricClassify( rows[%d:%d) ) ####\n",
1086 row_start, row_end);
1087 tprintf("###############################################\n");
1088 }
1089 RecomputeMarginsAndClearHypotheses(rows, row_start, row_end, 10);
1090
1091 GeometricClassifierState s(debug_level, rows, row_start, row_end);
1092 if (s.left_tabs.size() > 2 && s.right_tabs.size() > 2) {
1093 s.Fail(2, "Too much variety for simple outline classification.");
1094 return;
1095 }
1096 if (s.left_tabs.size() <= 1 && s.right_tabs.size() <= 1) {
1097 s.Fail(1, "Not enough variety for simple outline classification.");
1098 return;
1099 }
1100 if (s.left_tabs.size() + s.right_tabs.size() == 3) {
1101 GeometricClassifyThreeTabStopTextBlock(debug_level, s, theory);
1102 return;
1103 }
1104
1105 // At this point, we know that one side has at least two tab stops, and the
1106 // other side has one or two tab stops.
1107 // Left to determine:
1108 // (1) Which is the body indent and which is the first line indent?
1109 // (2) Is the text fully justified?
1110
1111 // If one side happens to have three or more tab stops, assume that side
1112 // is opposite of the aligned side.
1113 if (s.right_tabs.size() > 2) {
1114 s.AssumeLeftJustification();
1115 } else if (s.left_tabs.size() > 2) {
1116 s.AssumeRightJustification();
1117 } else if (s.ltr) { // guess based on script direction
1118 s.AssumeLeftJustification();
1119 } else {
1120 s.AssumeRightJustification();
1121 }
1122
1123 if (s.AlignTabs().size() == 2) {
1124 // For each tab stop on the aligned side, how many of them appear
1125 // to be paragraph start lines? [first lines]
1126 int firsts[2] = {0, 0};
1127 // Count the first line as a likely paragraph start line.
1128 firsts[s.AlignsideTabIndex(s.row_start)]++;
1129 // For each line, if the first word would have fit on the previous
1130 // line count it as a likely paragraph start line.
1131 bool jam_packed = true;
1132 for (int i = s.row_start + 1; i < s.row_end; i++) {
1133 if (s.FirstWordWouldHaveFit(i - 1, i)) {
1134 firsts[s.AlignsideTabIndex(i)]++;

Callers 1

DetectParagraphsFunction · 0.85

Calls 15

AcceptableRowArgsFunction · 0.85
ValidFirstLineFunction · 0.85
NearlyEqualFunction · 0.85
MarkRowsWithModelFunction · 0.85
FailMethod · 0.80
AlignTabsMethod · 0.80
AlignsideTabIndexMethod · 0.80
FirstWordWouldHaveFitMethod · 0.80

Tested by

no test coverage detected