Pergunta

Eu estou usando Microsoft MODI no VB6 para OCR em uma imagem.(Eu sei sobre outras ferramentas de OCR tesseract como etc, mas eu acho MODI mais precisos do que outros)

A imagem a ser Ocr é assim

enter image description here

e, o texto o eu chegar depois do OCR é como abaixo

Text1
Text2
Text3
Number1
Number2
Number3

O problema aqui é que o texto correspondente em frente coluna não é mantida.Como posso mapa Número1 com Texto1?

Eu só posso pensar em uma solução como essa.

MODI fornece as coordenadas de todos os Ocr palavras como essa

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

Então, para alinhar palavras na mesma linha, podemos combinar a TopPos de cada palavra e, em seguida, classificá-los por LeftPos.Teremos a linha completa.Então eu loop através de todas as palavras e armazenado em seu texto, bem como de esquerda e superior em uma tabela mysql.em seguida, correu esta consulta

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

O meu problema é Que posições de Topo não são exatamente iguais para cada palavra, Obviamente, haverá casal de pixel diferenças.

Eu tentei adicionar DIV 5, para a fusão de palavras que estão em 5 pixels, mas que não funciona para alguns casos.Eu também tentei fazê-lo em node.js através do cálculo de tolerância para cada palavra e, em seguida, a classificação por LeftPos, mas ainda sinto esta não é a melhor maneira de o fazer.

Atualização: O código js faz o trabalho, mas, exceto para o caso onde Número1 tem 5 pixel de diferença e Texto2 não tem correspondente na linha.

Existe alguma ideia melhor para fazer isso?

Foi útil?

Solução

Eu não tenho 100% de certeza de como você a identificar essas palavras que estão no seu "esquerda" coluna, mas uma vez que o word identificado, você pode encontrar outras palavras na mesma linha projetando-se não apenas o Topo de coordenadas, mas a todo o retângulo em (superior e inferior).Determinar a sobreposição (interseção) com o outras palavras.Observe a área marcada em vermelho abaixo.

Horizontal projection

Esta é a tolerância que você pode usar para detectar se algo está na mesma linha.Se algo se sobrepõe por apenas um pixel, em seguida, é, provavelmente, do maior ou menor linha.Mas se ele se sobrepõe a, digamos, 50% ou mais de altura `Texto1, então é provável que na mesma linha.


Exemplo de SQL para encontrar todas as palavras na "linha", baseado no topo e no fundo coord

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)

Exemplo psuedo código do VB6 para calcular as linhas bem.

'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.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top