Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 2
Ir a la página 1, 2  Siguiente
 
Tesseract Gambas (antes Python)
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Tesseract Gambas (antes Python) 
 
Hola a todos, encontré este código python que según dice en la web de donde lo saque, pasa de imagen de tabla a tabla.

Me gustaría poder pasarlo a gambas pero, por decirlo de alguna manera, python no es mi fuerte  

Saludos.

import Image, ImageOps
import subprocess, sys, os, glob
 
# minimum run of adjacent pixels to call something a line
H_THRESH = 300
V_THRESH = 300
 
def get_hlines(pix, w, h):
    """Get start/end pixels of lines containing horizontal runs of at least THRESH black pix"""
    hlines = []
    for y in range(h):
        x1, x2 = (None, None)
        black = 0
        run = 0
        for x in range(w):
            if pix[x,y] == (0,0,0):
                black = black + 1
                if not x1: x1 = x
                x2 = x
            else:
                if black > run:
                    run = black
                black = 0
        if run > H_THRESH:
            hlines.append((x1,y,x2,y))
    return hlines
 
def get_vlines(pix, w, h):
    """Get start/end pixels of lines containing vertical runs of at least THRESH black pix"""
    vlines = []
    for x in range(w):
        y1, y2 = (None,None)
        black = 0
        run = 0
        for y in range(h):
            if pix[x,y] == (0,0,0):
                black = black + 1
                if not y1: y1 = y
                y2 = y
            else:
                if black > run:
                    run = black
                black = 0
        if run > V_THRESH:
            vlines.append((x,y1,x,y2))
    return vlines
 
def get_cols(vlines):
    """Get top-left and bottom-right coordinates for each column from a list of vertical lines"""
    cols = []
    for i in range(1, len(vlines)):
        if vlines[i][0] - vlines[i-1][0] > 1:
            cols.append((vlines[i-1][0],vlines[i-1][1],vlines[i][2],vlines[i][3]))
    return cols
 
def get_rows(hlines):
    """Get top-left and bottom-right coordinates for each row from a list of vertical lines"""
    rows = []
    for i in range(1, len(hlines)):
        if hlines[i][1] - hlines[i-1][3] > 1:
            rows.append((hlines[i-1][0],hlines[i-1][1],hlines[i][2],hlines[i][3]))
    return rows        
 
def get_cells(rows, cols):
    """Get top-left and bottom-right coordinates for each cell usings row and column coordinates"""
    cells = {}
    for i, row in enumerate(rows):
        cells.setdefault(i, {})
        for j, col in enumerate(cols):
            x1 = col[0]
            y1 = row[1]
            x2 = col[2]
            y2 = row[3]
            cells[i][j] = (x1,y1,x2,y2)
    return cells
 
def ocr_cell(im, cells, x, y):
    """Return OCRed text from this cell"""
    fbase = "working/%d-%d" % (x, y)
    ftif = "%s.tif" % fbase
    ftxt = "%s.txt" % fbase
    cmd = "tesseract %s %s" % (ftif, fbase)
    # extract cell from whole image, grayscale (1-color channel), monochrome
    region = im.crop(cells[x][y])
    region = ImageOps.grayscale(region)
    region = region.point(lambda p: p > 200 and 255)
    # determine background color (most used color)
    histo = region.histogram()
    if histo[0] > histo[255]: bgcolor = 0
    else: bgcolor = 255
    # trim borders by finding top-left and bottom-right bg pixels
    pix = region.load()
    x1,y1 = 0,0
    x2,y2 = region.size
    x2,y2 = x2-1,y2-1
    while pix[x1,y1] != bgcolor:
        x1 += 1
        y1 += 1
    while pix[x2,y2] != bgcolor:
        x2 -= 1
        y2 -= 1
    # save as TIFF and extract text with Tesseract OCR
    trimmed = region.crop((x1,y1,x2,y2))
    trimmed.save(ftif, "TIFF")
    subprocess.call([cmd], shell=True, stderr=subprocess.PIPE)
    lines = [l.strip() for l in open(ftxt).readlines()]
    return lines[0]
 
def get_image_data(filename):
    """Extract textual data[rows][cols] from spreadsheet-like image file"""  
    im = Image.open(filename)
    pix = im.load()
    width, height = im.size
    hlines = get_hlines(pix, width, height)
    sys.stderr.write("%s: hlines: %d\n" % (filename, len(hlines)))
    vlines = get_vlines(pix, width, height)
    sys.stderr.write("%s: vlines: %d\n" % (filename, len(vlines)))
    rows = get_rows(hlines)
    sys.stderr.write("%s: rows: %d\n" % (filename, len(rows)))
    cols = get_cols(vlines)
    sys.stderr.write("%s: cols: %d\n" % (filename, len(cols)))
    cells = get_cells(rows, cols)
    
    data = []
    for row in range(len(rows)):
        data.append([ocr_cell(im,cells, row, col) for col in range(len(cols))])
    return data
 
def split_pdf(filename):
    """Split PDF into PNG pages, return filenames"""
    prefix = filename[:-4]
    cmd = "convert -density 600 %s working/%s-%%d.png" % (filename, prefix)
    subprocess.call([cmd], shell=True)
    return [f for f in glob.glob(os.path.join('working', '%s*' % prefix))]
 
def extract_pdf(filename):
    """Extract table data from pdf"""
    pngfiles = split_pdf(filename)
    sys.stderr.write("Pages: %d\n" % len(pngfiles))
    # extract table data from each page
    data = []
    for pngfile in pngfiles:
        pngdata = get_image_data(pngfile)
        for d in pngdata:
            data.append(d)
        # remove temp files for this page
        os.system("rm working/*.tif")
        os.system("rm working/*.txt")
    # remove split pages
    os.system("rm working/*")  
    return data
 
if __name__ == '__main__':
    if len(sys.argv) != 2:
        print "Usage: ctocr.py FILENAME"
        exit()
    # split target pdf into pages
    filename = sys.argv[1]
    data = extract_pdf(filename)
    for row in data:
        print "\t".join(row)
 

 



 
última edición por tincho el Lunes, 04 Abril 2016, 17:56; editado 1 vez 
tincho - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Hola Tincho.

Es solo por hablar y por preguntar. Tengo conocimientos de Python, pero no tantos como quisiera.
Algún que otro compañero más de la comunidad de gambas, han hecho los mismos cursos de Python
y pueden opinar muy parecido a lo que te puedo decir.

Uno de los problemas que me encuentro cuando veo el código, ademas de que es un poco largo. ( Suele pasar ).

No conozco los módulos que usa o importa al código. Image, ImageOps, subprocess, glob.
A saber lo que hay detrás.  

De los otros conozco algunas cosas.

Parece para Python 2. Python 3 tiene cosas que no son iguales, incluso instrucciones distintas.
Me he encontrado alguna que otra vez este problema. Siempre se debe buscar para comprobar las similitudes.

No creas que es tan difícil de entender el código. Hay cosas que hay cambiar, pero tampoco es algo extremo.
El problema en partes es que no conocemos las funciones que está importando.

¿ Qué problema te has encontrado para no poder hacerlo en gambas ?.

Por otra parte, no me extrañaría que se pudiera llamar externamente a este código desde Gambas.
Si se hace con C. A menos que se requiera algo que pida gambas en concreto.

No recuerdo si nuestro compañero Julio hizo algo de esto. Que se pudiese llamar a un código de Python
desde gambas.  

Nunca lo he intentado.

¿ Lo ejecutaste con Python 2 y es lo que quieres ?.

¿ Probaste alguna herramienta o aplicación para hacer lo que quieres ?.

5 herramientas digitales para extraer datos de archivos pdf protegidos

Saludos
 




===================
Gambas Básico
"No es un bug, es una característica no documentada"
 
Shell - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Así, a bote pronto, lo que hace el código es invocar a un proceso externo que es el ejecutable "tesseract", que es una utilidad OCR (reconocimiento de caracteres a partir de imágenes). Primero se extrae la imagen en formato tiff o desde un pdf, luego se escanea con el OCR y finalmente las rutinas interpretan su posición en la tabla, creando filas y columnas para componer el gridview o tabla.

Nada que no se pueda hacer en gambas directamente, eso sí, usando el binario tesseract como un proceso externo.

Saludos
 




===================
Jesús Guardón

Por favor, usemos el corrector ortográfico antes de pulsar el botón "Enviar".

"uo ǝs ʇɐu pıɟıɔıן ɐdɹǝupǝɹ ɐ dɹoƃɹɐɯɐɹ, soןo ɥɐʎ bnǝ dɹodouǝɹsǝןo"
 
jguardon - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Shell:
Bueno me interesa traducir este código a gambas, para poder importar escaneados de planillas de datos, pero no es mi objetivo meterme a programar (todavía) en python y respecto a las herramientas externas que propones no es posible adaptarlas al scripting con tesseract ya que hay que para usar estra herramientas hay que trabajar de forma mas o menos manual.

Jguardon:
Lo que describes es lo que hace el código, salvo que las paginas, en vez de .tif, las extrae en .png y luego las convierte en .tif.
Efectivamente creo que se puede hacer con gambas sin inconvenientes. Pero estoy estudiando el código este en python y no logro entender como hace para determinar las tablas, las filas y las columnas.
La parte de la extracción ya la tengo lista en destornillador la parte del ocr también.
El inconveniente es determinar y fraccionar las celdas de las tablas.

Saludos.
 



 
tincho - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Tincho:

¿ Tienes problemas con alguna función en concreto ?.

Saludos
 




===================
Gambas Básico
"No es un bug, es una característica no documentada"
 
Shell - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Shell escribió:  
¿ Tienes problemas con alguna función en concreto ?.


Pendiente:
def get_hlines(pix, w, h):
def get_vlines(pix, w, h):
def get_cols(vlines):
def get_rows(hlines):
def get_cells(rows, cols):
if __name__ == '__main__':

Solucionado:
os.system("rm working/*.tif") supongo que se puede reemplazar por shell "rm working/*.tif"
Extraer las imágenes desde el pdf

Información:
Post desde donde descargue el código en python: http://craiget.com/blog/extracting-...-pdfs-with-ocr/

Teoria sobre el tema:
http://users.iit.demokritos.gr/~bgat/ICAPR2005.pdf
http://clement.chatelain.free.fr/pu...r_icdar2013.pdf

Pero el mayor problema que tengo a la hora de traducir el código desde python a gambas es que las variables no están definidas claramente como en gambas y eso me dificulta la "decodificación" del código python

Saludos.
 



 
tincho - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Bueno, como es verdad que el código es extenso, voy a ir por partes.
¿Que esto en python?

    sys.stderr.write("%s: hlines: %d\n" % (filename, Len(hlines)))


Saludos.
 



 
tincho - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Hola Tincho.

Citar:

if __name__ == '__main__':


Eso en Python es para averiguar si el modulo actual se está ejecutando o lo están importando.
Así que si lo ejecutas directamente, __name__ es igual a '__main__'.

Ejemplo:

if __name__ == "__main__":
    print ("Soy el programa principal.")
else:
    print("Otro modulo me esta importando.")
 


Si lo ejecutas tal como está, te mostraría "Soy el programa principal".
Ahora imagina que ese programa se llama, prueba.

Si lo importases en otro modulo, de esta forma, escribiendo esto en las primeras lineas del  modulo actual.

import prueba

Se ejecutaría "Otro modulo me está importando"

Otro ejemplo:

#!/usr/bin/python3

# Creando un Script principal
# Sintaxis

def main():
    print('Este es el fichero sintasis.py')
    huevo()

def huevo():
    print ('huevo')

# Esta linea que veremos en muchos scripts de python nos permite
# llamar a funciones que son escritas o definidas despues de la llamada

if __name__=="__main__": main()
 


Es lo primero que quieres que se ejecute al iniciar la aplicación.

Citar:

def get_hlines(pix, w, h):


Hay algo que se repite mucho en la mayoría de estas funciones.

...
if pix[x,y] == (0,0,0)
...
 


Veo el bucle anidado, como va comparando si en cada coordenada el color es negro (R, G, B)
No entendí que tipo de datos es pix. Recuerda a un array de dos dimensiones.

Citar:

Pero el mayor problema que tengo a la hora de traducir el código desde python a gambas es que las variables no están definidas claramente como en gambas y eso me dificulta la "decodificación" del código python


Si, eso es un problema. Se le puede preguntar a Python por el tipo de datos.

type(variable)

Ejemplo:

Citar:

>>> num = 1
>>> type (num)
<type 'int'>
>>> num2 = 1.2
>>> type (num2)
<type 'float'>
>>>


Tu ve sobre la marcha, llega hasta donde no entiendas y preguntas.

Saludos
 




===================
Gambas Básico
"No es un bug, es una característica no documentada"
 
Shell - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
tincho escribió:  

¿Que esto en python?

    sys.stderr.write("%s: hlines: %d\n" % (filename, Len(hlines)))




No soy muy "informático que digamos", o programador. Pero parece que escribe en la salida de errores un mensaje.

Lo primero es el nombre del archivo y luego un valor que cuenta la longitud de hlines

"%s: hlines: %d\n" % (filename, Len(hlines))
 


El %s en este caso es una cadena, es algo como &1. Se parece en gambas a Subst.
Python usa Len tanto para contar caracteres como para contar elementos de un lista, tupla...(abreviando de un array).

Casi parece esto:

Print Subst$("&1: hlines: &2\n", "nombrearchivo", 12)
 


Pero, claro se imprime en la salida estándar de error.

Saludos
 




===================
Gambas Básico
"No es un bug, es una característica no documentada"
 
última edición por Shell el Lunes, 04 Abril 2016, 11:05; editado 3 veces 
Shell - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Tesseract Python 
 
Sí, stderr es una la vías de comunicación de un programa. En este caso de salida y en especial de errores.

mejor explicado acá redirigir stdin, stdout y stderr en Unix/Linux

Ahora no recuerdo cual programa (Creo que lo decía el libro de gambas) hay un programa cuya comunicación al exterior es sólo con stderr.
 



 
vicr - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes GEC: Controles Extendidos Para Gambas (ant... tincho Aplicaciones/Fragmentos de Código 80 Martes, 13 Diciembre 2016, 23:28 Ver último mensaje
tincho
No hay nuevos mensajes OCR Con Gambas Mediante Tesseract tercoIDE Aplicaciones/Fragmentos de Código 15 Domingo, 25 Diciembre 2016, 19:11 Ver último mensaje
tercoIDE
No hay nuevos mensajes [Python] Por Qué Python Debería Ser El P... Shell Python 2 Martes, 04 Julio 2017, 21:01 Ver último mensaje
vuott
No hay nuevos mensajes [Python] Guido Van Rossum Abandona La Supe... Shell Python 5 Miercoles, 10 Octobre 2018, 08:59 Ver último mensaje
Shell
 

Publicar nuevo tema  Responder al tema  Página 1 de 2
Ir a la página 1, 2  Siguiente

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron