Eu tenho um diagrama de várias imagens, que contém rótulos como caracteres alfanuméricos, em vez de apenas o rótulo do texto. Quero que meu modelo YOLO identifique todos os números e caracteres alfanuméricos presentes nele.
Como posso treinar meu modelo YOLO para fazer o mesmo. O conjunto de dados pode ser encontrado aqui. https://drive.google.com/open?id=1iEkGcreFaBIJqUdAADDXJbUrSj99bvoi
Por exemplo: veja as caixas delimitadoras. Quero que o YOLO detecte onde quer que o texto esteja presente. No entanto, atualmente não é necessário identificar o texto dentro dele.
Também é necessário fazer o mesmo para esse tipo de imagem
As imagens podem ser baixadas aqui
É isso que tentei usar o opencv, mas ele não funciona para todas as imagens no conjunto de dados.
import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Users\HPO2KOR\AppData\Local\Tesseract-OCR\tesseract.exe"
image = cv2.imread(r'C:\Users\HPO2KOR\Desktop\Work\venv\Patent\PARTICULATE DETECTOR\PD4.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
clean = thresh.copy()
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,1))
detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(clean, [c], -1, 0, 3)
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,30))
detect_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(clean, [c], -1, 0, 3)
cnts = cv2.findContours(clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 100:
cv2.drawContours(clean, [c], -1, 0, 3)
elif area > 1000:
cv2.drawContours(clean, [c], -1, 0, -1)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
x,y,w,h = cv2.boundingRect(c)
if len(approx) == 4:
cv2.rectangle(clean, (x, y), (x + w, y + h), 0, -1)
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
opening = cv2.morphologyEx(clean, cv2.MORPH_OPEN, open_kernel, iterations=2)
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,2))
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, close_kernel, iterations=4)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = cv2.contourArea(c)
if area > 500:
ROI = image[y:y+h, x:x+w]
ROI = cv2.GaussianBlur(ROI, (3,3), 0)
data = pytesseract.image_to_string(ROI, lang='eng',config='--psm 6')
if data.isalnum():
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
print(data)
cv2.imwrite('image.png', image)
cv2.imwrite('clean.png', clean)
cv2.imwrite('close.png', close)
cv2.imwrite('opening.png', opening)
cv2.waitKey()
Existe algum modelo, técnica aberta ou algum modelo pré-treinado que possa fazer o mesmo por mim? Eu só preciso das caixas delimitadoras em torno de todos os caracteres alfanuméricos presentes nas imagens. Depois disso, preciso identificar o que está presente nele. No entanto, a segunda parte não é importante atualmente.
fonte
Respostas:
Uma abordagem possível é usar o detector de texto de aprendizado profundo EAST (Texto de cena eficiente e preciso) com base no artigo de Zhou et al. : EAST: Um detector de texto de cena eficiente e preciso . O modelo foi originalmente treinado para detectar texto em imagens de cenas naturais, mas pode ser possível aplicá-lo em imagens de diagrama. O EAST é bastante robusto e é capaz de detectar texto borrado ou reflexivo. Aqui está uma versão modificada da implementação do EAST de Adrian Rosebrock. Em vez de aplicar o detector de texto diretamente na imagem, podemos tentar remover o máximo de objetos que não sejam de texto na imagem antes de executar a detecção de texto. A idéia é remover linhas horizontais, verticais e contornos que não sejam de texto (curvas, diagonais, formas circulares) antes de aplicar a detecção. Aqui estão os resultados com algumas de suas imagens:
Entrada
->
de contornos não textuais para remover em verdeResultado
Outras imagens
O
frozen_east_text_detection.pb
modelo pré-treinado necessário para executar a detecção de texto pode ser encontrado aqui . Embora o modelo capte a maior parte do texto, os resultados não são 100% precisos e apresentam falsos positivos ocasionais, provavelmente devido à forma como foi treinado em imagens de cenas naturais. Para obter resultados mais precisos, você provavelmente precisará treinar seu próprio modelo personalizado. Mas se você deseja uma solução pronta e decente, isso deve funcionar com você. Confira a detecção de texto OpenCV de Adrian (detector de texto EAST) publicação do blog de para obter uma explicação mais abrangente do detector de texto EAST.Código
fonte
Por conveniência, eu gostaria de adicionar o pacote keras_ocr . Ele pode ser instalado facilmente com o pip e é baseado no detector de texto CRAFT, que é um pouco mais novo que o detector EAST, se não estiver errado.
Ao lado da detecção, ele também já faz OCR! Os resultados são os seguintes: veja isso como uma alternativa, talvez mais fácil de implementar, do que a resposta aceita.
fonte
O que você está descrevendo parece ser OCR ( reconhecimento óptico de caracteres ). Um mecanismo de OCR que conheço é o tesseract , embora exista também este da IBM e de outros.
Como o YOLO foi originalmente treinado para uma tarefa muito diferente, para usá-lo para localizar texto, provavelmente será necessário treiná-lo do zero. Pode-se tentar usar pacotes existentes (adaptados à sua configuração específica) para a verdade básica (embora valha a pena lembrar que o modelo geralmente seria tão bom quanto a verdade básica). Ou, talvez mais facilmente, gere dados sintéticos para treinamento (por exemplo, adicione texto nas posições que você escolher nos desenhos existentes e treine para localizá-los).
Como alternativa, se todas as suas imagens-alvo estiverem estruturadas de maneira semelhante à anterior, tente criar uma verdade básica usando heurísticas clássicas de CV, como você fez acima, para separar / segmentar símbolos, seguido de classificação usando uma CNN treinada em MNIST ou similar para determinar se um determinado blob contiver um símbolo.
No caso de você optar pelo YOLO - existem implementações existentes em python, por exemplo, eu tive alguma experiência com este - deve ser bastante simples configurar o treinamento com sua própria verdade básica.
Finalmente, se o uso do YOLO ou da CNN não é um objetivo em si, mas apenas a solução, qualquer uma das "verdades fundamentais" acima pode ser usada diretamente como solução, e não para o treinamento de um modelo.
Espero ter entendido sua pergunta corretamente
fonte