Frage

Ich verwende Microsoft MODI In VB6 um ein Bild zu OCR zu machen.(Ich kenne andere OCR-Tools wie Tesseract usw., aber ich finde MODI genauer als andere)

Das Bild, das mit OCR bearbeitet werden soll, sieht folgendermaßen aus

enter image description here

und der Text, den ich nach der OCR erhalte, ist wie folgt

Text1
Text2
Text3
Number1
Number2
Number3

Das Problem hierbei ist, dass der entsprechende Text aus der gegenüberliegenden Spalte nicht beibehalten wird.Wie kann ich Number1 mit Text1 zuordnen?

Ich kann mir nur eine solche Lösung vorstellen.

MODI stellt die Koordinaten aller OCR-Wörter wie dieses bereit

LeftPos = Img.Layout.Words(0).Rects(0).Left
TopPos = Img.Layout.Words(0).Rects(0).Top

Um Wörter in derselben Zeile auszurichten, können wir die TopPos jedes Wortes abgleichen und sie dann nach LeftPos sortieren.Wir bekommen die komplette Linie.Also habe ich alle Wörter durchlaufen und ihren Text sowie links und oben in einer MySQL-Tabelle gespeichert.Dann habe ich diese Abfrage ausgeführt

SELECT group_concat(word ORDER BY `left` SEPARATOR ' ')
FROM test_copy
GROUP BY `top`

Mein Problem ist, dass die Spitzenpositionen nicht für jedes Wort genau gleich sind. Offensichtlich wird es einige Pixelunterschiede geben.

Ich habe versucht, hinzuzufügen DIV 5, zum Zusammenführen von Wörtern im 5-Pixel-Bereich, aber das funktioniert in einigen Fällen nicht.Ich habe es auch in node.js versucht, indem ich die Toleranz für jedes Wort berechnet und dann nach LeftPos sortiert habe, aber ich habe immer noch das Gefühl, dass dies nicht der beste Weg ist.

Aktualisieren: Der js-Code erledigt den Job, außer in dem Fall, dass Nummer1 einen Unterschied von 5 Pixeln hat und Text2 in dieser Zeile keine Entsprechung hat.

Gibt es eine bessere Idee, dies zu tun?

War es hilfreich?

Lösung

Ich bin mir nicht 100 % sicher, wie Sie die Wörter identifizieren, die sich in Ihrer „linken“ Spalte befinden, aber sobald Sie dieses Wort identifiziert haben, können Sie andere Wörter in der Zeile finden, indem Sie nicht nur die obere Koordinate, sondern das gesamte Rechteck über ( sowohl oben als auch unten).Bestimmen Sie die Überschneidung (Schnittpunkt) mit den anderen Wörtern.Beachten Sie den unten rot markierten Bereich.

Horizontal projection

Dies ist die Toleranz, mit der Sie erkennen können, ob sich etwas in derselben Zeile befindet.Wenn sich etwas nur um ein Pixel überlappt, stammt es wahrscheinlich aus einer niedrigeren oder höheren Zeile.Wenn es sich jedoch beispielsweise um 50 % oder mehr der Höhe „Text1“ überlappt, befindet es sich wahrscheinlich in derselben Zeile.


Beispiel-SQL, um alle Wörter in der „Zeile“ basierend auf der oberen und unteren Koordinate zu finden

select 
    word.id, word.Top, word.Left, word.Right, word.Bottom 
from 
    word
where 
    (word.Top >= @leftColWordTop and word.Top <= @leftColWordBottom)
    or (word.Bottom >= @leftColWordTop  and word.Bottom <= @leftColWordBottom)

Beispiel für Pseudo-VB6-Code zur Berechnung der Zeilen.

'assume words is a collection of WordInfo objects with an Id, Top, 
'   Left, Bottom, Right properties filled in, and a LineAnchorWordId 
'   property that has not been set yet.

'get the words in left-to-right order
wordsLeftToRight = SortLeftToRight(words) 

'also get the words in top-to-bottom order
wordsTopToBottom = SortTopToBottom(words) 

'pass through identifying a line "anchor", that being the left-most 
'   word that starts (and defines) a line
for each anchorWord in wordsLeftToRight

    'check if the word has been mapped to aline yet by checking if 
    '   its anchor property has been set yet.  This assumes 0 is not 
    '   a valid id, use -1 instead if needed
    if anchorWord.LineAnchorWordId = 0 then 

        'not locate every word on this line, as bounded by the 
        '   anchorWord.  every word determined to be on this line 
        '   gets its LineAnchorWordId property set to the Id of the 
        '   anchorWord
        for each lineWord in wordsTopToBottom

            if lineWord.Bottom < anchorWord.Top Then

                'skip it,it is above the line (but keep searching down
                '   because we haven't reached the anchorWord location yet)

            else if lineWord.Top > anchorWord.Bottom Then

                'skip it,it is below the line, and exit the search 
                '   early since all the rest will also be below the line
                exit for

            else if OverlapsWithinTolerance(anchorWord, lineWord) then

                lineWord.LineAnchorWordId = anchorWord.Id

            endif

        next

    end if

next anchorWord

'at this point, every word has been assigned a LineAnchorWordId, 
'   and every word on the same line will have a matching LineAnchorWordId
'   value.  If stored in a DB you can now group them by LineAnchorWordId 
' and sort them by their Left coord to get your output.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top