A integração de modelos de visão computacional com Large Lenguage Models (LLMs) abre portas para aplicações sofisticadas, como a digitalização inteligente de capas de livros. Ao unir um modelo YOLOv10 personalizado para localziação de regiões de texto com um LLM via Ollama, é possível transformar saídas caóticas de OCR em dados estruturados e de alta confiabilidade.
Limitações do OCR Convencional
Ferramentas tradicionais de Reconhecimento Óptico de Caracteres (OCR) enfrentam dificuldades quando o texto está sobreposto a elementos visuais complexos ou ruídos. Sem um pré-processamento adequado, os resultados tendem a ser inutilizáveis. O exemplo abaixo ilustra a aplicação direta do EasyOCR em uma imagem:
import easyocr
import cv2
leitor = easyocr.Reader(['en'])
img_capa = cv2.imread('capa_livro.jpg')
texto_bruto = leitor.readtext(img_capa)
for coordenadas, palavra, confianca in texto_bruto:
print(f"Texto: {palavra} - Confiança: {confianca}")
Ao processar imagens densas, a saída frequentemente inclui fragmentos visuais interpretados como letras ou textos embaralhados. Para mitigar isso, o YOLO atua como um filtro espacial preciso, isolando apenas as regiões de intereses antes da extração do texto.
- Treinamento do Modelo YOLOv10
A fundação deste pipeline é treinar um detector de objetos especializado em identificar blocos de texto, como títulos e nomes de autores. O YOLOv10 se destaca por sua eficiência e otimização para objetos de pequenas dimensões.
from ultralytics import YOLO
detector = YOLO("yolov10n.pt")
detector.train(
data="dataset_livros/config.yaml",
epochs=50,
imgsz=640
)
Ajustes nos hiperparâmetros e no volume do dataset podem ser aplicados para refinar a precisão da detecção de limites na sua base de dados específica.
- Extração de Caixas Delimitadoras em Vídeo
Com o modelo treinado, a inferência é aplicada quadro a quadro para gerar caixas delimitadoras (bounding boxes), separando visualmente o texto do fundo e preparando o terreno para um OCR limpo.
import cv2
from ultralytics import YOLO
captura = cv2.VideoCapture('video_livros.mp4')
detector = YOLO('pesos_modelo_livro.pt')
def processar_deteccoes(modelo, quadro, limiar=0.5):
inferencias = modelo.predict(quadro, conf=limiar)
for inferencia in inferencias:
for caixa in inferencia.boxes:
x1, y1, x2, y2 = map(int, caixa.xyxy[0].tolist())
cv2.rectangle(quadro, (x1, y1), (x2, y2), (0, 255, 0), 2)
return quadro, inferencias
while captura.isOpened():
status, frame = captura.read()
if not status:
break
frame_processado, inferencias = processar_deteccoes(detector, frame)
cv2.imshow('Deteccao de Texto', frame_processado)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
captura.release()
cv2.destroyAllWindows()
Este script isola as coordenadas exatas onde o texto reside, eliminando a interferência do restante da imagem durante a leitura.
- Aplicação de OCR nas Regiões Isoladas
Ao restringir a leitura do OCR apenas aos recortes das caixas delimitadoras, a precisão do texto extraído aumenta significativamente, evitando falsos positivos gerados por texturas ou ilustrações.
import easyocr
leitor_ocr = easyocr.Reader(['en'])
def ler_regioes_recortadas(quadro, caixas):
resultados_ocr = []
for caixa in caixas:
x1, y1, x2, y2 = map(int, caixa.xyxy[0].tolist())
recorte = quadro[y1:y2, x1:x2]
leitura = leitor_ocr.readtext(recorte)
resultados_ocr.append(leitura)
return resultados_ocr
for inferencia in inferencias:
leituras = ler_regioes_recortadas(frame, inferencia.boxes)
palavras_extraidas = [detec[1] for leitura in leituras for detec in leitura]
print(f"Palavras extraídas: {', '.join(palavras_extraidas)}")
O resultado agora contém apenas as palavras relevantes da capa, como 'THE, SECRET, HISTORY, DONNA, TARTT', minimizando erros de interpretação de fundo.
- Refinamento Semântico com Ollama (Llama 3)
Mesmo restrito às caixas, o OCR pode retornar caracteres equivocados ou sequências desordenadas. Ao direcionar a saída bruta para o Llama 3 via Ollama, é possível sanitizar, organizar e formatar as informações de forma semântica.
import ollama
instrucao_llm = f"""
- O texto a seguir foi obtido via OCR de uma capa de livro e contém o título e o autor.
- Pode haver pequenos erros de ortografia ou desordem de palavras.
- Sua tarefa é identificar o título e o autor corretamente.
- Retorne APENAS no formato: 'Título: <livro> | Autor: <autor>'.
- Não inclua nenhuma outra informação ou comentário.
Texto bruto:
{palavras_extraidas}
"""
resposta_llm = ollama.chat(
model="llama3",
messages=[{"role": "user", "content": instrucao_llm}]
)
dado_estruturado = resposta_llm['message']['content'].strip()
print(dado_estruturado)
A resposta gerada pelo modelo será algo como: Título: The Secret History | Autor: Donna Tartt. Esse dado formatado pode ser automaticamente inserido em bancos de dados, utilizado para indexação em bibliotecas digitais ou para geração de metadados em sistemas de arquivamento, eliminando a necessidade de curadoria manual e garantindo a consistência da informação extraída.