Tekninen artikkeli

HotPDF: kiinan- ja monikielinen OCR RapidOCR:lla Delphissä

HotPDF suorittaa kiinan- ja monikielistä OCR:ää Delphissä natiivin RapidOCR-DLL-sovittimensa kautta: THPDFRapidOCRDLLOptions.ForLanguage kytkee kielitagin kuten 'zh-CN', 'zh-TW', 'ru' tai 'ar' sopivaan tunnistusmalliin ja merkistösanakirjaan, ja THotPDF.ApplyLoadedOCRTextLayer muuttaa tunnistetut rivit näkymättömäksi, haettavaksi Unicode-tekstitasoksi skannatuille PDF-sivuille

Latinankielisen demon saaminen toimimaan on helppo osa. Kiinnostavat viat alkavat, kun vaihdat perinteiseen kiinaan tai venäjään ja tuloksesta tulee itsevarmaa, hyvin muodostettua hölynpölyä, tai kun jokainen rivi menettää hiljaisesti viimeisen merkkinsä, tai kun arabiankielinen sivu palaa tekstialaatikot väärässä järjestyksessä. Mikään näistä ei nosta poikkeusta omin voimin. HotPDF v2.775.0:ssa lisätyt kielialisetukset ovat olemassa pääasiassa sulkemaan kyseiset aukot, ja alla olevat neljä ansaa on syytä ymmärtää, vaikka et koskaan koskisi natiivia koodia, koska kukin niistä selittää oireen, jonka perässä voisit muuten uhrata päivän

Miten ForLanguage valitsee mallin ja sanakirjan?

THPDFRapidOCRDLLOptions.ForLanguage ratkaisee tagin yhdeksi yhdeksästä profiilista ja palauttaa asetukset, jotka osoittavat kohteisiin <profile>/recognition.onnx ja <profile>/dictionary.txt mallikansiosi alla, säilyttäen jaetun detektorin, valinnaisen kulmaluokittelijan sekä säie-, pikseli- ja aikakatkaisuoletukset lähteestä THPDFRapidOCRDLLOptions.Default. Metodi muuntaa tagin pieniksi kirjaimiksi, muuntaa alaviivat viivoiksi ja leikkaa ympäröivät välilyönnit, joten tagit 'zh_TW', 'ZH-tw' ja ' zh-tw ' laskeutuvat kaikki samalle profiilille. Aliakset ovat eksplisiittinen luettelo etuliitevertailun sijaan: 'zh-Hant-TW' hyväksytään, koska se on luettelossa, kun taas mielivaltainen alueellinen muunnos, jota ei ole luettelossa, nostaa EArgumentExceptionn ennen kuin yksikään malli latautuu

HotPDF ForLanguage -profiilin ratkaisu funktiolle THPDFRapidOCRDLLOptions: tagit kuten zh_TW, ZH-tw ja zh-TW normalisoidaan ja sovitetaan yhdeksään luetteloidun profiilin joukkoon, joista kukin lukitsee tunnistusmallin ja sanakirjan, jotka aina asetetaan yhdessä, kun taas luetteloon kuulumaton tagi nostaa EArgumentExceptionn ennen minkään mallin latautumista
Yksi tagi valitsee yhden lukitun malli-sanakirja-parin; detektori, luokittelija ja budjetit pysyvät jaettuina, ja tuntematon tagi epäonnistuu nopeasti sen sijaan, että lataisi mitään
ProfiiliKieletEsimerkkitagitLukittu malli
chYksinkertaistettu kiina ja englantizh, zh-CN, zh-Hans, chi_simPP-OCRv4
chinese_chtPerinteinen kiinazh-TW, zh-HK, zh-Hant, chi_traPP-OCRv3
enEnglantien, en-US, en-GB, engPP-OCRv4
latinRanska, saksa, espanja, portugali, italia, hollanti, turkkifr, de, es-419, pt-BR, trPP-OCRv3
japanJapanija, ja-JP, jpnPP-OCRv4
koreanKoreako, ko-KR, korPP-OCRv4
cyrillicVenäjä, ukraina, bulgaria, valkovenäjäru, ru-RU, uk, bgPP-OCRv3
arabicArabia, persia, urduar, ar-SA, fa, urPP-OCRv4
devanagariHindi, marathi, nepalihi, mr, nePP-OCRv4

Sovitin ei koskaan lataa mitään itse. Hankit tiedostot kerran mukana toimitettavalla apuskriptillä, esimerkiksi komennolla tools/Install-RapidOCRModels.ps1 -Destination C:/OCR/models -Language ch,chinese_cht,cyrillic (tai -Language All kaikille yhdeksälle profiilille), ja skripti sijoittaa jaetun detektorin ja luokittelijan juuritiedostonimiin, joita Default odottaa. Sen jälkeen yksinkertaistetun kiinan skannaus muuttuu haettavaksi muutamalla rivillä. Moottoriputki on sama IHPDFOCREngine-sauma, jota artikkeli in-process RapidOCR -DLL:stä ja sen ABI-rajasta kuvailee, joten tämä artikkeli pysyy kielissä

uses
  SysUtils, HPDFDoc, HPDFRapidOCRRecognition;

procedure MakeChineseScanSearchable(const SourceFile, TargetFile: string);
var
  Doc: THotPDF;
  Engine: IHPDFOCREngine;
  Models: THPDFRapidOCRDLLOptions;
  Layer: THPDFOCRTextLayerOptions;
  Info: THPDFOCRTextLayerInfo;
begin
  // ch/recognition.onnx + ch/dictionary.txt, jaettu detektori ja luokittelija
  Models := THPDFRapidOCRDLLOptions.ForLanguage('zh-CN');
  Engine := HPDFCreateRapidOCRDLLOCREngine(
    'C:\OCR\Win64\HotPDFRapidOCR.dll', 'C:\OCR\models', Models);
  Doc := THotPDF.Create(nil);
  try
    Doc.AutoLaunch := False;
    if Doc.LoadFromFile(SourceFile) < 1 then
      raise Exception.Create('Cannot load ' + SourceFile);
    Layer := THPDFOCRTextLayerOptions.Default;  // 300 DPI, MinimumConfidence 0.5
    // tyhjä sivuluettelo tarkoittaa jokaista sivua; sivut, joilla on jo tekstiä, ohitetaan
    if not Doc.ApplyLoadedOCRTextLayer([], Engine, Layer, Info) then
      raise Exception.Create(string(Info.Diagnostic));
    Writeln(string(Info.EngineName), ': ', Info.AcceptedWordCount,
      ' lines, ', Info.UniqueScalarCount, ' distinct characters');
    Doc.SaveLoadedDocument(TargetFile);
  finally
    Doc.Free;
  end;
end;

Kaksi yksityiskohtaa kyseisessä tulosteessa ansaitsee huomion. Natiivi putki palauttaa yhden tuloksen havaittua tekstiriviä kohden, ei sanaa kohden, joten AcceptedWordCount laskee täällä rivejä, ja MinimumConfidence verrataan koko rivin keskimääräiseen merkkiluottamusarvoon: rivi, jonka keskiarvo on 0.45, pudotetaan yksikkönä. UniqueScalarCount raportoi, montako erillistä Unicode-skaalaaria tekstitason piti kartoittaa fonttiinsa ja ToUnicode-taulukkoonsa, hyödyllinen järkevyystarkistus siitä, että CJK-tekstiä oikeasti saapui sen sijaan, että olisi tullut kourallinen latinalaisia varapolkuja. Pidä moottorin rajapinta elossa asiakirjojen yli, koska mallin alustus tapahtuu tehtaassa ja on kallis vaihe

Miksi vain tunnistusmallin vaihtaminen tuottaa roskaa?

CTC-tunnistusmalli ei koskaan tulosta merkkejä, vain luokkaindeksejä, ja sanakirja on ainoa asia, joka muuttaa indeksin 1 204 glyyfiksi. Vaihda tiedosto ch/recognition.onnx tiedostoon cyrillic/recognition.onnx mutta pidä kiinalainen sanakirja, ja malli emittoi ilomieleen kelvollisia kyrillisiä indeksejä, jotka vanha sanakirja kääntää satunnaisiksi han-merkeiksi. Tulos näyttää tekstiltä, läpäisee UTF-8-validoinnin, ja on haettava täsmälleen mitään ei. Siksi ForLanguage asettaa aina arvot RecognitionModel ja CharacterDictionary yhdessä, ja siksi käsin rakennettujen asetusten ei pidä koskaan muuttaa toista ilman toista

Ilmeinen turvatarkistus, sanakirjan koon vertaaminen mallin tulosteen leveyteen, on tarpeellinen mutta ei riittävä. Kaksi sanakirjaa voi sisältää saman määrän merkintöjä eri järjestyksessä, ja yhden väärin kohdalla oleva järjestys siirtää jokaista merkkiä yhdellä koodipisteellä. HotPDF tarkistaa siksi kahdessa vaiheessa, kun tehdas alustaa mallin. Ensinnäkin tulosteen luokkamäärän on oltava yhtä suuri kuin sanakirjan merkintöjen plus kaksi. Toiseksi, kun ONNX-tiedosto upottaa character-metadataluettelon, jokainen sanakirjamerkintä verrataan siihen järjestyksessä, ja ristiriita kaataa alustuksen arvolla EInvalidOperation ja natiivilla diagnostiikalla uskottavan roskan tuottamisen sijaan myöhemmin

"Plus kaksi" tulee luokka-asettelusta. Luokka 0 on CTC-tyhjä, luokat 1–N ovat sanakirjarivit tiedostojärjestyksessä, ja viimeinen luokka on välilyönti. Jotkut sanakirjat kantavat myös oman välilyöntimerkintänsä, ja kyseisen rivin on säilyttävä täsmälleen sellaisenaan. Tässä hyvätarkoittainen Trim tekee todellista vahinkoa: se muuttaa yhden välilyönnin merkinnän tyhjäksi merkkijonoksi ja siirtää tai rikkoo taulukon. Ainoa turvallinen normalisointi on loppurivinvaihtomerkin poistaminen, joten CRLF-rivinvaihdoin tallennettu sanakirja latautuu oikein, kun taas UTF-8:n tavujärjestysmerkki, tyhjä rivi tai sarkaimen sisältävä merkintä hylätään. Alla oleva luonnos näyttää asettelun Pascalissa; kyseessä on havainnollistava koodi, ei HotPDF-API

HotPDF:n CTC-luokkataulukon asettelu RapidOCR-sanakirjoille: luokka 0 on tyhjä, luokat 1–N ovat sanakirjarivit tiedostojärjestyksessä siten, että yksittäinen välilyöntimerkintä säilytetään, ja viimeinen luokka on välilyönti, mikä antaa N plus 2 tulostusluokkaa, jotka tehdas varmistaa mallia vasten, metadataluettelo mukaan lukien
Sanakirja on ainoa asia, joka muuttaa luokkaindeksit merkeiksi, joten sen koko, järjestys ja välilyöntimerkintä varmistetaan ennen kuin yksikään sivu tunnistetaan
// Vain havainnollistus: luokkataulukko, jonka CTC-tunnistin odottaa
uses
  SysUtils, IOUtils;

function BuildCTCClassTable(const FileName: string): TArray<string>;
var
  Text, Entry: string;
  Lines: TArray<string>;
  I, Last: Integer;
begin
  Text := TEncoding.UTF8.GetString(TFile.ReadAllBytes(FileName));
  if (Text <> '') and (Text[1] = #$FEFF) then
    raise EArgumentException.Create('Dictionary must be UTF-8 without a BOM');
  Lines := Text.Split([#10]);
  Last := High(Lines);
  if (Last >= 0) and (Lines[Last] = '') then
    Dec(Last);                                   // rivinvaihto tiedoston lopussa
  SetLength(Result, Last + 3);
  Result[0] := '';                               // luokka 0: CTC-tyhjä
  for I := 0 to Last do
  begin
    Entry := Lines[I];
    if (Entry <> '') and (Entry[Length(Entry)] = #13) then
      SetLength(Entry, Length(Entry) - 1);       // CRLF: pudota vain CR
    if (Entry = '') or (Pos(#9, Entry) > 0) then
      raise EArgumentException.Create('Invalid dictionary entry');
    Result[I + 1] := Entry;                      // ei koskaan Trimia: ' ' on luokka
  end;
  Result[Last + 2] := ' ';                       // viimeinen luokka: välilyönti
  // Length(Result)in on oltava yhtä suuri kuin mallin tulosteen luokkamäärä
end;

Mitä ahne CTC-dekoodaus oikeastaan tekee?

Ahne CTC-dekoodaus poimii korkeimman pistemäärän luokan jokaisella aikavaiheella, luhistaa peräkkäiset toistot yhdeksi merkiksi ja pudottaa tyhjän luokan; tyhjä on se, mikä antaa aidosti kahdentuneiden kirjainten selviytyä. Tunnistusmalli katsoo tekstiriviä kapeiden pystysuuntaisten viipaleiden jonona, ja jokaiselle viipaleelle eli aikavaiheelle se tulostaa todennäköisyyden jokaiselle luokalle. Rivi, joka sisältää merkkijonon AA中, saattaa tuottaa argmax-jonon A A blank A 中 space. Kahden ensimmäisen A-vaiheen luhistaminen antaa yhden A:n, tyhjä erottaa sen seuraavasta A:sta, ja tulos on AA中 loppuvälilyönti ehjänä. Ilman tyhjäsääntöä sanat book ja bok olisivat erottamattomia

HotPDF GreedyCTCDecoden läpikäynti: kuusi aikavaihetta äänestää argmax-luokkia A, A, blank, A, han-merkki ja space, peräkkäiset toistot luhistuvat, tyhjä nollaa toistovartijan niin, että aidosti kahdentunut kirjain selviää, ja kolme reunabugia pudottaa hiljaisesti sanavälit, viimeisen merkin tai kahdentuneet merkit
Dekooderi on tusinaa riviä, ja jokainen reuna merkitsee: sisällytä viimeinen luokka, sisällytä viimeinen aikavaihe, ja anna vain tyhjän erottaa toistot

Koska dekooderi on vain tusinaa riviä, reunoihin on helppo tarttua väärin, ja viat ovat hiljaisia. Jos sisempi argmax-silmukka pysähtyy yhtä luokkaa vajaaksi, välilyöntiluokka ei voi koskaan voittaa, ja jokainen rivi palaa ilman sanavälejä, mikä tuhoaa fraasihakun englannin- ja latinalaisilla sivuilla. Jos ulompi silmukka pysähtyy yhtä aikavaihetta vajaaksi, jokaisen rivin viimeinen merkki katoaa, mikä lyhyellä rivillä voi olla kolmasosa tekstistä. Ja jos toistovartijaa ei nollata tyhjällä, kahdentuneet merkit kuten ll tai kiinalaiset reduplikaatiot kuten 谢谢 luhistuvat yhdeksi. HotPDF:n dekooderi sisällyttää viimeisen luokan ja viimeisen aikavaiheen, pitää tyhjällä erotetut toistot ja hylätään lisäksi pisteet, jotka eivät ole äärellisiä tai jotka putoavat välin 0–1 ulkopuolelle, sekä mikä tahansa luokkamäärä, joka ei vastaa sanakirjaa. Tässä sama logiikka Pascal-havainnollistuksena

// Vain havainnollistus: ahne CTC-dekoodaus oikeilla reunoilla.
// Scores pitää sisällään Steps * Classes todennäköisyyttä, yksi rivi aikavaihetta kohden
function GreedyCTCDecode(const Scores: array of Single;
  Steps, Classes: Integer; const Characters: array of string): string;
var
  Step, C, Best, Previous: Integer;
  BestScore: Single;
begin
  if (Classes < 3) or (Length(Characters) <> Classes) or
    (Length(Scores) <> Steps * Classes) then
    raise EArgumentException.Create('Model output does not match the dictionary');
  Result := '';
  Previous := 0;                            // luokka 0 on CTC-tyhjä
  for Step := 0 to Steps - 1 do             // sisällytä viimeinen aikavaihe
  begin
    Best := 0;
    BestScore := Scores[Step * Classes];
    for C := 1 to Classes - 1 do            // sisällytä viimeinen luokka (välilyönti)
      if Scores[Step * Classes + C] > BestScore then
      begin
        Best := C;
        BestScore := Scores[Step * Classes + C];
      end;
    if (Best <> 0) and (Best <> Previous) then
      Result := Result + Characters[Best];
    Previous := Best;                       // tyhjä nollaa toistovartijan
  end;
end;

Ahne dekoodaus ei ole tarkin saatavilla oleva CTC-strategia; beam search kielimallilla voi korjata osan monimerkityksellisistä viipaleista. Painetuille asiakirjoille 300 DPI:llä ahne tulos on yleensä se, mitä mallilla on annettavana, eikä dekooderi ole paikka kompensoida mallin heikkouksia. Latinalainen PP-OCRv3-malli voi esimerkiksi lukea merkin ñ merkkinä n jopa puhtaalla syötteellä. HotPDF ei piilota kyseistä asiaa jälkikäsittelyn merkkikorvauksilla, koska korvaustaulukko, joka korjaa espanjan, rikkoo jotain muuta, ja väärä merkki haettavassa tasossa on pahempi kuin rehellinen ohi

Miten HotPDF järjestää tekstirivit, mukaan lukien oikealta vasemmalle kulkeva arabia?

HotPDF lajittelee havaitut tekstialueet ylhäältä alas, ryhmittelee laatikot riviksi, kun ne menevät päällekkäin pystysuunnassa vähintään pienemmän laatikon korkeuden puolikkaalla, ja järjestää jokaisen rivin vasemmalta oikealle tai oikealta vasemmalle, kun RightToLeft on käytössä; jokaisen tunnistetun rivin merkkejä ei koskaan käännetä. Ryhmittely merkitsee, koska detektori usein halkaisee yhden visuaalisen rivin useisiin laatikoihin, esimerkiksi nimikkeeseen ja arvoon, joiden välissä on leveä rako, ja pelkkä yläkoordinaatin lajittelu lomittaisi ne naapuririvin kanssa aina, kun niiden yläreunat eroavat pikselin tai parin verran

Arabia-alisetus asettaa arvon RightToLeft := True, mikä kertoo DLL:lle järjestää kunkin rivin laatikot niiden oikean reunan mukaan reunamarginaalista sisäänpäin. Kyseinen on koko vaikutus. Teksti, jonka malli palauttaa riville, on jo Unicode-loogisessa järjestyksessä, siinä järjestyksessä, jossa arabin lukija lukee ja kirjoittaa sen, ja kyseinen on myös järjestys, jonka PDF-tekstin poiminta ja haku odottavat. Merkkijonon mekaaninen kääntäminen, jotta se "näyttäisi oikealta" debuggarissa, rikkoi haun, kopioinnin ja liittämisen sekä ruudunlukijat. Kaksisuuntainen näyttö ja glyyfien muotoilu ovat katseluohjelman asia

Yksi moottori palvelee yhtä kieliprofiilia. Automaattista kirjainjärjestelmäntunnistusta ei ole, joten kirjainjärjestelmiä sekoittava asiakirja tarvitsee yhden moottorin profiilia kohden, sovellettuna sivuihin, jotka käyttävät sitä. Koska ApplyLoadedOCRTextLayer ottaa eksplisiittisen sivuluettelon ja vahvistaa jokaisen kutsun omana kaikki-tai-ei mitään -transaktionaan, kyseinen on suoraviivaista

uses
  SysUtils, HPDFDoc, HPDFRapidOCRRecognition;

function CreateRapidEngine(const Tag: string): IHPDFOCREngine;
var
  Models: THPDFRapidOCRDLLOptions;
begin
  // nostaa EArgumentExceptionn tuntemattomalle tagille, ennen kuin mikään malli latautuu
  Models := THPDFRapidOCRDLLOptions.ForLanguage(Tag);
  Models.MaxPixels := 33554432;          // tilaa A3-sivuille 300 DPI:llä
  Result := HPDFCreateRapidOCRDLLOCREngine(
    'C:\OCR\Win64\HotPDFRapidOCR.dll', 'C:\OCR\models', Models);
end;

procedure OCRMixedArchive(Doc: THotPDF);
var
  Chinese, Arabic: IHPDFOCREngine;
  Layer: THPDFOCRTextLayerOptions;
  Info: THPDFOCRTextLayerInfo;
begin
  Chinese := CreateRapidEngine('zh-TW');  // chinese_cht-profiili
  Arabic := CreateRapidEngine('ar-SA');   // arabia-profiili, RightToLeft = True
  Layer := THPDFOCRTextLayerOptions.Default;
  if not Doc.ApplyLoadedOCRTextLayer([0, 1, 2], Chinese, Layer, Info) then
    raise Exception.Create(string(Info.Diagnostic));
  if not Doc.ApplyLoadedOCRTextLayer([3], Arabic, Layer, Info) then
    raise Exception.Create(string(Info.Diagnostic));
end;

Rivi MaxPixels on siellä syystä. DLL:n asetusten oletus on 16 777 216 pikseliä pyyntöä kohden, mikä kattaa A4:n ja US Letterin 300 DPI:llä mukavasti, mutta A3-sivu 300 DPI:llä on noin 3508 kertaa 4961 pikseliä, suunnilleen 17,4 miljoonaa, ja pyyntö hylätään budjetin ylittyenä. Nosta arvoa MaxPixels (katto on 67 108 864) tai laske THPDFOCRTextLayerOptions.DPIa suuria formaatteja varten. Oikealta vasemmalle -järjestys käyttää ABI-version 1 valinnaista vientiä HPDFRapidOCRSetReadingDirection; sovitin vaatii sen vain, kun RightToLeft on asetettu, joten vanhempi DLL palvelee yhä vasemmalta oikealle -kieliä ja epäonnistuu moottorin luomisessa arvolla EArgumentException, joka nimeää puuttuvan viennin arabialle

Miksi uudemmat OCR-mallit epäonnistuvat latautumaan?

HotPDF RapidOCR -DLL linkittää staattisen ONNX Runtime 1.14:n, joka ei voi lukea ONNX IR -versiolla 10 tallennettuja malleja, ja uudemmat viennit kuten PP-OCRv5-mallit voivat vaatia tuota uudemman ajonympäristön; tällainen malli epäonnistuu moottorin luomisessa natiivilla diagnostiikalla. Kyseinen rajoite on syy siihen, että kielipaketit on lukittu tiettyihin PP-OCRv3- ja PP-OCRv4-tunnistin- ja sanakirjapareihin "uusimman" sijaan, ja siihen, miksi yllä oleva taulukko sekoittaa kaksi sukupolvea: jokainen lukittu pari on sellainen, joka latautuu ja varmistuu kyseisellä ajonympäristöllä

Asennusohjelma valvoo paritusta. Jokainen tiedosto manifestissaan kantaa SHA256-hashia, olemassa oleva tiedosto, jolla on eri hash, pysäyttää asennuksen ylikirjoittamisen sijaan, ja jokainen lataus laskeutuu väliaimaiselle nimelle ja siirtyy paikalleen vasta, kun sen hash täsmää. Se suojaa sanakirjaongelman hiljaiselta muodolta: joku pudottaa uudemman recognition.onnxin profiilikansioon käsin, luokkamäärä sattuu täsmäämään, eikä mikään epäonnistu ennen kuin asiakas raportoi, ettei haku löydä sanoja, jotka he selvästi näkevät. Ajonaikaisesti sovitin pysyy offline-tilassa eikä koskaan nouda puuttuvaa mallia. Tunnistin validoi mallin muodon lataushetkellä, hyväksyen NCHW-syötteen kiinteällä korkeudella 32 tai 48 pikseliä tai dynaamisella korkeudella, jonka se ajaa arvolla 48

Jos tarvitset kirjainjärjestelmää, jota mikään yhdeksästä profiilista ei kata, voit yhä osoittaa arvot RecognitionModel ja CharacterDictionary omiin tiedostoihisi. Samat tarkistukset pätevät, ja se on koko pointti: pariton pari epäonnistuu alustuksessa, ei asiakkaasi arkistossa. Sivuille, joilla kumpikaan RapidOCR-profiili ei sovi, artikkeli Tesseract-sovitin haettavaan PDF:ään kytkeytyy samaan ApplyLoadedOCRTextLayer-kutsuun, ja konepainetuille ASCII-lomakkeille artikkeli sisäänrakennettu mallivertailu-OCR-moottori ei tarvitse malleja lainkaan

Pikaopas: monikielinen RapidOCR-tarkistuslista

  • Luo asetukset funktiolla THPDFRapidOCRDLLOptions.ForLanguage ja käsittele EArgumentException tukemattomana tagina, ei ajonaikaisena viana
  • Vaihda arvot RecognitionModel ja CharacterDictionary yhdessä, ei koskaan toista yksinään; yhtä suuret luokkamäärät eivät todista yhtä suurta merkkijärjestystä
  • Pidä sanakirjat UTF-8:na ilman BOM:ia, älä koskaan trimaa merkintöjä, ja odota mallilla N + 2 luokkaa: tyhjä, N merkintää, välilyönti
  • Oman CTC-dekooderin on katettava viimeinen luokka ja viimeinen aikavaihe ja pidettävä tyhjällä erotetut toistot
  • Käytä yhtä moottoria kieliprofiilia kohden ja anna eksplisiittiset sivuluettelot kirjainjärjestelmiä sekoittaville asiakirjoille
  • RightToLeft muuttaa vain laatikkojärjestystä; tunnistettu teksti pysyy Unicode-loogisessa järjestyksessä
  • Asenna mallit skriptillä Install-RapidOCRModels.ps1 niin, että SHA256-lukitukset pitävä mallin ja sanakirjan parituksen; aseta UseAngleClassifier := False, jos asensit lipulla -SkipClassifier
  • Nosta MaxPixels oletuksen 16 777 216 yli ennen A3- tai suurempien sivujen ajamista 300 DPI:llä

RapidOCR-kielialisetukset, natiivi DLL-sovitin ja OCR-tekstitasoputki kuuluvat pakettiin HotPDF Delphi PDF Component Delphille, C++Builderille ja Windows FPC/Lazarukselle, alkaen versiosta v2.775.0 monikielisten profiilien osalta