tesseractnotfounderror - Mi propio programa OCR en Python
tesseract is not installed or it''s not in your path (4)
¡OCR es muy, muy difícil! El enfoque que se usará para intentar la OCR se basará en lo que usted está tratando de lograr (reconocimiento de escritura a mano, lectura de texto generada por computadora, etc.)
Sin embargo, para comenzar, lea sobre Redes neuronales y OCR. Aquí hay algunos artículos sobre el tema:
http://www.codeproject.com/KB/cs/neural_network_ocr.aspx
http://www.codeproject.com/KB/dotnet/simple_ocr.aspx
Utilice su motor de búsqueda favorito para encontrar información.
¡Que te diviertas!
Todavía soy un principiante, pero quiero escribir un programa de reconocimiento de caracteres. Este programa no está listo todavía. Y edité mucho, por lo tanto los comentarios pueden no coincidir exactamente. Usaré la conectividad 8 para el etiquetado de componentes conectados.
from PIL import Image
import numpy as np
im = Image.open("D://Python26//PYTHON-PROGRAMME//bild_schrift.jpg")
w,h = im.size
w = int(w)
h = int(h)
#2D-Array for area
area = []
for x in range(w):
area.append([])
for y in range(h):
area[x].append(2) #number 0 is white, number 1 is black
#2D-Array for letter
letter = []
for x in range(50):
letter.append([])
for y in range(50):
letter[x].append(0)
#2D-Array for label
label = []
for x in range(50):
label.append([])
for y in range(50):
label[x].append(0)
#image to number conversion
pix = im.load()
threshold = 200
for x in range(w):
for y in range(h):
aaa = pix[x, y]
bbb = aaa[0] + aaa[1] + aaa[2] #total value
if bbb<=threshold:
area[x][y] = 1
if bbb>threshold:
area[x][y] = 0
np.set_printoptions(threshold=''nan'', linewidth=10)
#matrix transponation
ccc = np.array(area)
area = ccc.T #better solution?
#find all black pixel and set temporary label numbers
i=1
for x in range(40): # width (later)
for y in range(40): # heigth (later)
if area[x][y]==1:
letter[x][y]=1
label[x][y]=i
i += 1
#connected components labeling
for x in range(40): # width (later)
for y in range(40): # heigth (later)
if area[x][y]==1:
label[x][y]=i
#if pixel has neighbour:
if area[x][y+1]==1:
#pixel and neighbour get the lowest label
pass # tomorrows work
if area[x+1][y]==1:
#pixel and neighbour get the lowest label
pass # tomorrows work
#should i also compare pixel and left neighbour?
#find width of the letter
#find height of the letter
#find the middle of the letter
#middle = [width/2][height/2] #?
#divide letter into 30 parts --> 5 x 6 array
#model letter
#letter A-Z, a-z, 0-9 (maybe more)
#compare each of the 30 parts of the letter with all model letters
#make a weighting
#print(letter)
im.save("D://Python26//PYTHON-PROGRAMME//bild2.jpg")
print(''done'')
La mayoría de los algoritmos de OCR en estos días se basan en algoritmos de redes neuronales. Las redes Hopfield son un buen lugar para comenzar. Basado en el Modelo Hopfield disponible aquí en C , construí un algoritmo de reconocimiento de imagen muy básico en python similar a lo que describiste. He publicado la fuente completa here . Es un proyecto de juguete y no es adecuado para OCR real, pero puede ayudarlo a comenzar en la dirección correcta.
El modelo Hopfield se utiliza como una memoria de asociación automática para almacenar y recuperar un conjunto de imágenes de mapa de bits . Las imágenes se almacenan calculando una matriz de peso correspondiente. A partir de entonces, a partir de una configuración arbitraria, la memoria se asentará exactamente en la imagen almacenada, que es la más cercana a la configuración inicial en términos de distancia de Hamming. Por lo tanto, dada una versión incompleta o dañada de una imagen almacenada, la red puede recuperar la imagen original correspondiente.
Un applet de Java para jugar con un ejemplo se puede encontrar here ; la red está entrenada con entradas de ejemplo para los dígitos 0-9. Dibuje en el cuadro de la derecha, haga clic en prueba y vea los resultados de la red.
No dejes que la notación matemática te intimide, los algoritmos son sencillos una vez que llegas al código fuente.
OCR es muy, muy difícil. Incluso con los caracteres generados por computadora, es bastante desafiante si no conoce la fuente y el tamaño de la fuente de antemano. Incluso si está combinando exactamente los caracteres, no lo llamaría un proyecto de programación "de inicio"; es bastante sutil
Si desea reconocer caracteres escaneados o escritos a mano, eso es aún más difícil: deberá usar matemática avanzada, algoritmos y aprendizaje automático. Hay bastantes libros y miles de artículos escritos sobre este tema, por lo que no es necesario reinventar la rueda.
Admiro tu esfuerzo, pero no creo que hayas llegado lo suficientemente lejos como para alcanzar alguna de las dificultades reales todavía. Hasta ahora solo estás explorando píxeles aleatoriamente y copiándolos de una matriz a otra. Todavía no has hecho ninguna comparación y no estoy seguro del propósito de tu "caminata aleatoria".
- ¿Por qué al azar? Escribir algoritmos aleatorios correctos es bastante difícil. Yo recomendaría comenzar con un algoritmo determinista primero.
- ¿Por qué estás copiando de una matriz a otra? ¿Por qué no simplemente comparar directamente?
Cuando obtenga la comparación, tendrá que lidiar con el hecho de que la imagen no es exactamente la misma que el "prototipo", y no está claro cómo manejará eso.
Sin embargo, según el código que ha escrito hasta ahora, tengo una idea para usted: intente escribir un programa que encuentre su camino a través de un "laberinto" en una imagen. La entrada sería la imagen, más el píxel inicial y el píxel objetivo. La salida es un camino a través del laberinto desde el principio hasta la meta. Este es un problema mucho más fácil que OCR: resolver los laberintos es algo para lo que las computadoras son excelentes, pero aún así es divertido y desafiante.
OCR no es una tarea fácil de hecho. Es por eso que el texto CAPTCHAs todavía funciona :)
Para hablar solo sobre la extracción de letras y no sobre el reconocimiento de patrones, la técnica que está utilizando para separar las letras se denomina etiquetado de componentes conectados . Ya que está solicitando una forma más eficiente de hacer esto, intente implementar el algoritmo de dos pasos que se describe en este artículo. Otra descripción se puede encontrar en el artículo Extracción de manchas .
EDIT : Aquí está la implementación para el algoritmo que he sugerido:
import sys
from PIL import Image, ImageDraw
class Region():
def __init__(self, x, y):
self._pixels = [(x, y)]
self._min_x = x
self._max_x = x
self._min_y = y
self._max_y = y
def add(self, x, y):
self._pixels.append((x, y))
self._min_x = min(self._min_x, x)
self._max_x = max(self._max_x, x)
self._min_y = min(self._min_y, y)
self._max_y = max(self._max_y, y)
def box(self):
return [(self._min_x, self._min_y), (self._max_x, self._max_y)]
def find_regions(im):
width, height = im.size
regions = {}
pixel_region = [[0 for y in range(height)] for x in range(width)]
equivalences = {}
n_regions = 0
#first pass. find regions.
for x in xrange(width):
for y in xrange(height):
#look for a black pixel
if im.getpixel((x, y)) == (0, 0, 0, 255): #BLACK
# get the region number from north or west
# or create new region
region_n = pixel_region[x-1][y] if x > 0 else 0
region_w = pixel_region[x][y-1] if y > 0 else 0
max_region = max(region_n, region_w)
if max_region > 0:
#a neighbour already has a region
#new region is the smallest > 0
new_region = min(filter(lambda i: i > 0, (region_n, region_w)))
#update equivalences
if max_region > new_region:
if max_region in equivalences:
equivalences[max_region].add(new_region)
else:
equivalences[max_region] = set((new_region, ))
else:
n_regions += 1
new_region = n_regions
pixel_region[x][y] = new_region
#Scan image again, assigning all equivalent regions the same region value.
for x in xrange(width):
for y in xrange(height):
r = pixel_region[x][y]
if r > 0:
while r in equivalences:
r = min(equivalences[r])
if not r in regions:
regions[r] = Region(x, y)
else:
regions[r].add(x, y)
return list(regions.itervalues())
def main():
im = Image.open(r"c:/users/personal/py/ocr/test.png")
regions = find_regions(im)
draw = ImageDraw.Draw(im)
for r in regions:
draw.rectangle(r.box(), outline=(255, 0, 0))
del draw
#im.show()
output = file("output.png", "wb")
im.save(output)
output.close()
if __name__ == "__main__":
main()
Y aquí está el archivo de salida:
No es 100% perfecto, pero como lo hace solo con fines de aprendizaje, puede ser un buen punto de partida. Con el cuadro delimitador de cada personaje, ahora puede usar una red neuronal como otros han sugerido aquí.