Izluščevanje tabel v PDFium Component od različice 3.117.0 tanke zapolnjene pravokotnike obravnava kot obrobe tabel. Ko je omogočen DetectFilledRulings, kar je privzeto, zapolnjen z osema poravnan okvir, ki ni debelejši od MaxRulingThickness (3 točke), postane ena obroba po svoji dolgi osi, večji zapolnjen okvir prispeva svoje štiri robove, vsaka koordinata obrobe pa se pred sestavljanjem mreže poravna znotraj RulingSnapTolerance (4 točke). Tabele, izvožene iz Worda, Google Docs in brskalnikov, zato do zaznavanja mrež z obrobami pridejo kot popolne mreže, namesto da bi kot fragmenti padle na zaznavanje po belini
Prejšnji članek o zaznavanju in izluščevanju tabel je navajal, da zaznavanje mrež z obrobami uporablja narisane črte in da se vsak segment obrisane poti pretvori v koordinate strani. Ta stavek je bil resničen in nepopoln. Štetje objektov poti po naboru 13 vzorčnih dokumentov iz resničnega sveta je pokazalo, da jih 9 ne vsebuje nobene obrisane poti, vsaka njihova stran pa nosi stotine zapolnjenih pravokotnikov, debelih od 0,5 do 1 točke. Zaznavanje, ki je gledalo le obrise, ni videlo ničesar, vsaka stran je padla na zaznavanje po belini, izhod pa je bil razsutje drobnih fragmentov in ne tabele. Prednastavitev kompaktnih stolpcev, dodana v 3.116.4, je to omilila na ravni fragmentov; korenski vzrok je bil, da je zaznavanje bralo napačen operator slikanja
Zakaj tabela, izvožena iz Worda, nima obrisanih črt?
Urejevalnik besedil o obrobi ne razmišlja kot o črti; razmišlja o okvirju s širino in ta okvir nariše s polnilom. ISO 32000-1 §8.5.2.1 določa, da operator re doda podpot pravokotnika, §8.5.3 pa loči operatorje slikanja: S obriše pot s trenutno širino črte, f napolni njeno notranjost. Obroba celice debeline 0,5 točke se izpiše kot x y w 0.5 re f in strojna oprema za obrise, vključno s širino črte, stiki in vzorcem črtkanja, se nikoli ne zažene. Senčenje celic je ista konstrukcija z večjim okvirjem. Obrisana mreža, narisana z m, l in S, je tisto, kar je pričakovalo izvirno zaznavanje, in tisto, kar ne proizvede skoraj nič, kar izvozi pisarniška aplikacija:
% ena obroba celice iz izvoza urejevalnika besedil: zapolnjen okvir, visok 0,5 točke
72 700 468 0.5 re f
% senčenje celice: zapolnjen okvir v velikosti celice
72 676 117 24 re f
% obrisana črta mreže, za katero je bilo napisano izvirno zaznavanje
72 700 m 540 700 l S
Za zaznavanje, ki FPDFPath_GetDrawMode vpraša le, ali je zastavica za obris nastavljena, sta oba zapolnjena okvirja nevidna. Besede znotraj celic nato dosežejo zaznavanje po belini, kjer so stolpci, ločeni s 6-točkovnim razmikom, pod privzetim MinColumnGap 12 točk, in vrne se tista podmnožica vrstic, ki se slučajno poravna dovolj dobro, da prestane MinRows. To je vedenje fragmentov in nobeno nastavljanje parametrov ga ne spremeni v mrežo, ki jo je narisal avtor
Kako PDFium Component spremeni zapolnjen okvir v obrobo?
TableCollectObjectRulings pregleda vsak objekt poti po eno podpot naenkrat. Način risanja pride iz FPDFPath_GetDrawMode; pot šteje kot zapolnjena, kadar je DetectFilledRulings vklopljen in način polnjenja ni none. Vsaka točka se pretvori skozi matriko objekta in zbere, do MaxSubpathPoints (8) na podpot, vsak segment krivulje pa podpot označi kot ukrivljeno. Ko se podpot zapre ali se začne nov MoveTo, FlushSubpath odloči, kaj je bila: ukrivljena podpot se zavrže in prav tako vsak zaprt mnogokotnik, katerega točke ne ležijo vse znotraj PointTolerance (0,05 točke) od robov omejevalnega okvira na vsaj eni osi. Trikotnik, znak v obliki črke V ali zaobljen jeziček nikoli ne postane obroba, in prav to ohranja okrasno grafiko zunaj mreže
Kar preživi, je z osema poravnan pravokotnik, razvrščen po svojem omejevalnem okvirju. Širina na ravni MaxRulingThickness ali pod njo z višino nad njo da eno navpično obrobo na vodoravni sredini, ki sega čez okvir od spodaj navzgor; zrcalni primer da eno vodoravno obrobo. Obe dimenziji nad mejo pomenita senčeno celico in okvir prispeva štiri obrobe, po eno na rob. Obe dimenziji na meji ali pod njo ne prispevata ničesar, zato 2-točkovni kvadratni znak za alinejo ni zamenjan za črto. Obrisana pot ubere starejšo pot skozi AddLine, po eno obrobo na segment, poravnan z osema, zato je mreža, narisana s S, obdelana natanko kot prej, pot, slikana tako s polnilom kot z obrisom, pa da prekrivajoče se kose, ki jih prehod združevanja zloži:
uses
PDFium;
var
Pdf: TPdf;
Options: TPdfTableExtractionOptions;
Tables: TPdfTables;
Mode: string;
I: Integer;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'itinerary-from-word.pdf';
Pdf.LoadDocument;
Pdf.PageNumber := 1; // 1-indeksirano
Options := TPdfTableExtractionOptions.Default;
// to so privzete vrednosti 3.117.0, izpisane zaradi jasnosti
Options.DetectFilledRulings := True; // tanki zapolnjeni okvirji postanejo obrobe
Options.MaxRulingThickness := 3.0; // točke; debelejši okvirji štejejo kot senčenje
Options.RulingSnapTolerance := 4.0; // točke; 0 izklopi poravnavanje
Options.IncludeFormXObjects := True;
Tables := Pdf.ExtractTables(Options);
for I := 0 to High(Tables) do
begin
if Tables[I].DetectionMode = ptdmRuled then
Mode := 'ruled'
else
Mode := 'whitespace';
Writeln(Format('%dx%d %s, confidence %.2f',
[Tables[I].RowCount, Tables[I].ColumnCount, Mode,
Tables[I].Confidence]));
end;
finally
Pdf.Free;
end;
end;
Kaj RulingSnapTolerance naredi za tabele s senčenimi celicami?
RulingSnapTolerance je tisto, zaradi česar se tabela, zgrajena samo iz senčenja, poveže v eno mrežo. Nekateri izvozi ne narišejo nobene obrobe: vsaka celica je zapolnjen okvir v svoji barvi, sosednja okvirja pa ločuje razmik bele barve od 1 do 3 točk. Vsak okvir da štiri robne obrobe, a desni rob ene celice in levi rob naslednje stojita 2 točki narazen, preskus povezljivosti pa uporablja RulingTolerance, ki je privzeto 1 točka. Brez poravnavanja vsaka celica tvori svojo povezano komponento iz štirih obrob, nobena komponenta ne doseže MinRows in stran ne prijavi ničesar. TableSnapRulings zbere vsako koordinato X v igri (položaj vsake navpične obrobe plus začetek in konec vsake vodoravne) in prav tako vsako koordinato Y, vsak seznam razvrsti, ga razdeli v gruče z veriženjem vrednosti, katerih sosed se razlikuje za največ toleranco, vsako gručo nadomesti z njeno srednjo vrednostjo in nato vsak položaj, začetek in konec premakne na najbližje središče gruče. Obe strani razmika postaneta ista črta in povezljivost se ohrani
Poravnavanje se izvede pred TableMergeRulings, ki obrobe razvrsti in združi kolinearne kose, ki se dotikajo ali prekrivajo znotraj RulingTolerance, oba prehoda pa se izvedeta, preden TableDetectRuled sploh vidi podatke, zato je preskus povezljivosti po parih sorazmeren s številom črt mreže in ne s številom fragmentov po celicah. Na obrisani mreži sta prehoda neškodljiva, ker se koordinate, ki so bile že prej enake, poravnajo same s sabo. Kar velja imeti v mislih, je, da verižno gručanje samo po sebi nima omejitve širine: niz koordinat, vsaka 3 točke od naslednje, se zloži v eno samo središče. Pri privzetih 4 točkah to prizadene le stolpce, ožje od znaka, če pa ima dokument resnične 3-točkovne razmike, ki morajo ostati ločeni, toleranco znižajte ali jo nastavite na 0, da poravnavanje izklopite:
// Izoliraj strategijo mrež z obrobami in primerjaj, kaj vsaka nastavitev vidi na eni strani
function CountRuledTables(Pdf: TPdf; FilledRulings: Boolean;
SnapTolerance: Double): Integer;
var
Options: TPdfTableExtractionOptions;
begin
Options := TPdfTableExtractionOptions.Default;
Options.DetectWhitespaceTables := False;
Options.DetectFilledRulings := FilledRulings;
Options.RulingSnapTolerance := SnapTolerance;
Result := Length(Pdf.ExtractTables(Options));
end;
// Izvoz iz Worda običajno prijavi 0, N in nato manj kot N:
// samo obrisi ne vidijo nič, poravnavanje poveže senčene celice,
// izklop poravnavanja pa pusti vsako senčeno celico kot svoj otok
Writeln(CountRuledTables(Pdf, False, 4.0));
Writeln(CountRuledTables(Pdf, True, 4.0));
Writeln(CountRuledTables(Pdf, True, 0.0));
Obrobe znotraj form XObject
Orodja za postavitev strani pogosto ovijejo tabelo ali celotno telo strani v form XObject in ga narišejo z Do. ISO 32000-1 §8.10.1 določa, da se matrika obrazca ob risanju obrazca združi s trenutno matriko transformacije, zato pravokotnik znotraj obrazca živi v prostoru obrazca in pristane na strani šele po dveh ali več transformacijah. TableCollectObjectRulings se spusti v objekte obrazca, kadar je IncludeFormXObjects nastavljen: prebere matriko objekta, jo prek TableMultiplyMatrix združi z matriko starša, katerega vrstni red argumentov pomeni "preslikaj skozi prvo matriko, nato skozi drugo", in otroke našteje s FPDFFormObj_CountObjects in FPDFFormObj_GetObject, pri čemer združeno matriko posreduje naprej. Gnezdenje, globlje od MaxFormDepth (8), se tiho preskoči, kar je varovalka proti patološkim datotekam in ne meja, ki bi se ji približal kateri koli resničen izvoz. Zakaj je vrstni red množenja pomemben, je isto vprašanje, obdelano v dodajanju matrike spredaj proti zadaj: zamenjava operandov premakne člen translacije in obroba, ki bi morala pristati na vrhu strani, pristane v izhodišču
Zakaj se je proračun obrob početveril?
Privzeti MaxRulingSegments se je v različici 3.117.0 dvignil s 4096 na 16384, ker obrobe po celicah prihajajo v veliko večjem številu kot obrisane črte mreže. Obrisana tabela s 30 vrsticami in 6 stolpci ima 38 segmentov črt. Ista tabela, izvožena kot zapolnjeni okvirji, ima do štiri obrobe na celico, 720 kosov pred združevanjem, obrazec s senčenimi celicami pa to podvoji. Dve taki tabeli na strani bi izčrpali stari proračun. Proračun se uveljavlja v TableAppendRuling prek Check, ki sproži EPdfError s sporočilom "Table ruling-segment budget exceeded"; poslabšanega rezultata ni, delne mreže ni, prehod po belini pa se prav tako ne izvede. Če za nezaupanja vreden vhod nastavite strožji proračun, izjemo ujemite in se odločite, namesto da bi prazen rezultat brali kot "ni tabel":
Options := TPdfTableExtractionOptions.Default;
Options.MaxRulingSegments := 2048; // namerno strogo za nezaupanja vreden vhod
try
Tables := Pdf.ExtractTables(Options);
except
on E: EPdfError do
begin
Log(E.Message); // 'Table ruling-segment budget exceeded'
Options.MaxRulingSegments := 16384; // privzeto v 3.117.0
Tables := Pdf.ExtractTables(Options);
end;
end;
Izmerjeni rezultati in kje se pristop ustavi
Na istih 13 vzorčnih dokumentih je izluščevanje z 43 tabel, od tega 9 mrež z obrobami in 34 fragmentov po belini ali lažnih pozitivov, prešlo na 41 tabel z obrobami in nobenega lažnega pozitiva po belini. Del tega čiščenja pripada dvema spremljevalnima spremembama v 3.117.0: besede, ki jih je mreža z obrobami že zahtevala, se odstranijo, preden se zažene zaznavanje po belini, zato tabela ni nikoli prijavljena dvakrat, meja stolpca po belini pa mora biti zdaj koridor brez besedila čez vsako vrstico, ki jo ločuje, in prav to je ustavilo obojestransko poravnane odstavke, da se niso šteli kot tabele 5x4. Bralnik zapolnjenih pravokotnikov je tisto, kar je same tabele premaknilo iz stolpca fragmentov v stolpec mrež z obrobami
Meje velja povedati naravnost. Stran brez besedilnega sloja še vedno da ogrodje mreže, vsaka celica prazna, ker obrobe prihajajo iz geometrije in besedilo iz besedilne strani; skenirane strani najprej potrebujejo OCR. Zapolnjene oblike z krivuljami, zaobljenimi vogali ali nepravokotnimi obrisi se zavržejo v celoti, zato tabela, katere obrobe so narisane kot obrisi zaobljenih pravokotnikov, potrebuje zaznavanje po belini kot prej. Tabela brez obrob in brez senčenja se s tem ne spremeni in ostaja domena strategije po belini, opisane v članku o izluščevanju tabel; kadar tudi to ni dovolj, so okviri besed in bloki iz strukturiranega besedila in vrstnega reda branja surovina za bralnik, prilagojen domeni. Predstavitev TableExtractionLab, ki izhaja s komponento, v svoji plošči z možnostmi izpostavlja DetectFilledRulings, kar je najhitrejši način, da vidite, kakšen je dani izvoz z njim in brez njega; celoten API je opisan na strani izdelka PDFium Component za Delphi