Eu tenho tentado limpar imagens para OCR: (as linhas)
Preciso remover essas linhas para, às vezes, processar ainda mais a imagem e estou chegando bem perto, mas na maioria das vezes o limite retira muito do texto:
copy = img.copy()
blur = cv2.GaussianBlur(copy, (9,9), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,30)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
dilate = cv2.dilate(thresh, kernel, iterations=2)
cnts = cv2.findContours(dilate, 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 > 300:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(copy, (x, y), (x + w, y + h), (36,255,12), 3)
Editar: Além disso, o uso de números constantes não funcionará caso a fonte seja alterada. Existe uma maneira genérica de fazer isso?
Respostas:
Aqui está uma ideia. Dividimos esse problema em várias etapas:
Determine a área retangular média do contorno. Limitamos, então, os contornos e filtramos usando a área retangular do contorno. A razão pela qual fazemos isso é por causa da observação de que qualquer caractere típico será apenas tão grande, enquanto um ruído grande abrangerá uma área retangular maior. Em seguida, determinamos a área média.
Remova contornos grandes e extremos. Repetimos os contornos e removemos os contornos grandes, se forem
5x
maiores que a área média do contorno, preenchendo o contorno. Em vez de usar uma área de limite fixo, usamos esse limite dinâmico para obter mais robustez.Dilate com um kernel vertical para conectar caracteres . A idéia é aproveitar a observação de que os caracteres estão alinhados em colunas. Ao dilatar com um núcleo vertical, conectamos o texto para que o ruído não seja incluído nesse contorno combinado.
Remova pequenos ruídos . Agora que o texto a ser mantido está conectado, encontramos contornos e removemos os contornos menores que
4x
a área média do contorno.Bit a bit - e para reconstruir a imagem . Como nós apenas desejamos contornos para manter nossa máscara, nós bit a bit - e para preservar o texto e obter nosso resultado.
Aqui está uma visualização do processo:
Nós limiar de Otsu para obter uma imagem binária, em seguida, encontrar contornos para determinar a área retangular média do contorno. A partir daqui, removemos os grandes contornos extremos destacados em verde preenchendo os contornos
Em seguida, construímos um núcleo vertical e dilatamos para conectar os caracteres. Esta etapa conecta todo o texto desejado para manter e isolar o ruído em blobs individuais.
Agora encontramos contornos e filtramos usando a área de contorno para remover o pequeno ruído
Aqui estão todas as partículas de ruído removidas destacadas em verde
Resultado
Código
Nota: O processamento tradicional da imagem é limitado a operações de limiar, morfológicas e filtragem de contorno (aproximação de contorno, área, proporção ou detecção de blob). Como as imagens de entrada podem variar com base no tamanho do texto dos caracteres, é bastante difícil encontrar uma solução singular. Você pode querer treinar seu próprio classificador com aprendizado profundo / máquina para obter uma solução dinâmica.
fonte