Pregunta

estoy usando microsoft MODI en VB6 para OCR una imagen.(Conozco otras herramientas de OCR como tesseract, etc., pero encuentro que MODI es más preciso que otras)

La imagen a OCRed es así

enter image description here

y el texto que recibo después del OCR es el siguiente

Text1
Text2
Text3
Number1
Number2
Number3

El problema aquí es que no se mantiene el texto correspondiente de la columna opuesta.¿Cómo puedo asignar Número1 con Texto1?

Sólo puedo pensar en una solución como esta.

MODI proporciona coordenadas de todas las palabras OCR como esta

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

Entonces, para alinear palabras en la misma línea, podemos hacer coincidir TopPos de cada palabra y luego ordenarlas por LeftPos.Obtendremos la línea completa.Así que recorrí todas las palabras y almacené su texto, así como el izquierdo y el superior en una tabla MySQL.luego ejecuté esta consulta

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

Mi problema es que las posiciones superiores no son exactamente las mismas para cada palabra. Obviamente, habrá un par de diferencias de píxeles.

Intenté agregar DIV 5, para fusionar palabras que están en un rango de 5 píxeles, pero eso no funciona en algunos casos.También intenté hacerlo en node.js calculando la tolerancia para cada palabra y luego ordenándola por LeftPos, pero sigo sintiendo que esta no es la mejor manera de hacerlo.

Actualizar: El código js hace el trabajo, excepto en el caso en que Número1 tiene una diferencia de 5 píxeles y Texto2 no tiene correspondencia en esa línea.

¿Hay alguna idea mejor para hacer esto?

¿Fue útil?

Solución

No estoy 100% seguro de cómo identifica esas palabras que están en su columna "izquierda", pero una vez que tenga esa palabra identificada, puede encontrar otras palabras en la línea de TI al proyectar no solo la coordenada superior, sino la totalidad.Rectángulo a través (tanto arriba como inferior).Determine la superposición (intersección) con las otras palabras.Tenga en cuenta el área marcada en rojo debajo.

Proyección horizontal

Esta es la tolerancia que puede usar para detectar si algo está en la misma línea.Si algo se superpone solo con un píxel, es probable que sea de una línea inferior o superior.Pero si se superpone, digamos, 50% o más de la altura "Text1, entonces es probable en la misma línea.


Ejemplo SQL para encontrar todas las palabras en la "línea" basada en la ATOP y la coorda inferior

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)


Ejemplo de código PSUEDO VB6 para calcular las líneas también.

'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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top