Contar o número de um número na área da imagem

8

Seu objetivo é escrever um programa ou função completo que aceite 5 números inteiros positivos e uma string com um nome de arquivo de imagem como entrada [X1,Y1], [X2,Y2], N, image.jpgem qualquer formato razoável, em que:

  • O primeiro par [X1,Y1]é o canto superior esquerdo X, Ycoordenadas ( <=20) da área do retângulo azul na imagem de exemplo ( 16,11).
  • O segundo par [X2,Y2]é o canto inferior direito X, Ycoordenadas ( <=20) da área do retângulo azul na figura de exemplo ( 20,22).
  • Quinto número, Nesse 0 <= N <= 9é o número que deve ser encontrado.
  • O sexto parâmetro é uma string com o nome do arquivo desta imagem JPG .

Emita quantos Nestão presentes na área indicada (destacada em azul na figura para este exemplo):

insira a descrição da imagem aqui

Clique aqui para obter uma versão maior e limpa da mesma imagem.

Na figura, há 500 números de 0até 9(incluídos) organizados em 20 colunas por 25 linhas, em Courier Newfonte monoespaçada . Cada número diferente tem uma cor diferente (você pode tirar proveito desse fato ou ignorá-lo e considerar ou converter a imagem em monocromo, se isso o ajudar).

Casos de teste:

[4,4],[13,5],1,image.jpg    > 4  (outlined in red)
[4,4],[13,5],4,image.jpg    > 2  (outlined in red)
[17,5],[17,5],2,image.jpg   > 1  (outlined in magenta)
[17,5],[17,5],9,image.jpg   > 0  (outlined in magenta)
[20,8],[20,9],3,image.jpg   > 1  (outlined in cyan)
[20,8],[20,9],2,image.jpg   > 0  (outlined in cyan)
[16,11],[20,22],0,image.jpg > 8  (outlined in blue)
[16,11],[20,22],3,image.jpg > 9  (outlined in blue)
[3,14],[11,20],7,image.jpg  > 6  (outlined in green)
[3,14],[11,20],5,image.jpg  > 6  (outlined in green)
[3,14],[11,20],8,image.jpg  > 8  (outlined in green)
[1,1],[20,25],0,image.jpg   > 47 (whole picture)
[1,1],[20,25],8,image.jpg   > 50 (whole picture)
[1,1],[20,25],1,image.jpg   > 55 (whole picture)

Regras:

  • Isso é então o código mais curto vence.
  • Você deve tomar como entrada este arquivo JPG .
  • Você não tem permissão para codificar a matriz de números representados no JPG ou os resultados.
  • As brechas padrão são proibidas.
Mario
fonte

Respostas:

4

Mathematica, 92 bytes

Count[Take[Characters@StringSplit@TextRecognize@Binarize[Import@#4,.9],#2,#],ToString@#3,2]&

Função sem nome levando os argumentos neste formato: [{X1,X2}, {Y1,Y2}, N, "image.jpg"]. (Na verdade, o quarto argumento pode ser o nome do arquivo local ou a URL http://i67.tinypic.com/6qh5lj.jpg.)

Import@#4importa o arquivo de imagem, Binarize[...,.9]escurece todos os números para preto e TextRecognize(a função faz claramente o trabalho pesado aqui!) extrai uma string de várias linhas da imagem resultante, que é dividida em uma lista aninhada de caracteres com Characters@.

Take[...,#2,#]mantém apenas os caracteres correspondentes ao retângulo destacado e Count[...,ToString@#3,2]conta o número de ocorrências Nno resultado.

Greg Martin
fonte
2

Python 3 + travesseiro + pytesseract, 239 bytes

from PIL.Image import*
from pytesseract import*
def c(a,b,n,f):w,h=b[0]-a[0]+1,b[1]-a[1]+1;return len([1for i in range(h*w)if image_to_string(open(f).convert('L').point(lambda x:[9,0][x<250],'1')).split()[i//w+a[1]-1][i%w+a[0]-1]==str(n)])

Isso é terrivelmente ineficiente, pois para cada bloco numérico, o arquivo inteiro é analisado. A solução de 243 bytes muito mais rápida e um pouco mais longa seria

from PIL.Image import*
from pytesseract import*
def c(a,b,n,f):s=image_to_string(open(f).convert('L').point(lambda x:[9,0][x<250],'1')).split();w,h=b[0]-a[0]+1,b[1]-a[1]+1;return len([1for i in range(h*w)if s[i//w+a[1]-1][i%w+a[0]-1]==str(n)])
TidB
fonte