Previsão de dígitos manuscritos usando CNN (parte 2)

Taras Rumezhak Segue 16 de jul · 5 min ler

Bem-vindo de volta, queridos leitores! Na parte anterior, construímos nossa rede neural convolucional que vamos usar neste tutorial. Há muitos tutoriais sobre como criar reconhecimento de dígitos manuscritos em tempo real, mas eles estão usando principalmente aplicativos de navegador. Nós vamos construir um aplicativo para PC usando apenas bibliotecas Python.

Para a interface do usuário, usaremos o Tkinter. O Tkinter é uma ligação do Python ao kit de ferramentas da Tk GUI. É a interface padrão do Python para o kit de ferramentas Tk GUI e é a GUI padrão do Python.

Você pode facilmente encontrar alguns tutoriais Tkinter para construir o que quiser.

Trending AI Articles:

1. Notas do Livro de Aprendizagem Profunda, Capítulo 1

2. Notas do Livro de Aprendizagem Profunda, Capítulo 2

3. Máquinas Demonstram Autoconsciência

4. Workshop de Música Visual e Aprendizagem de Máquina para Crianças

Vamos usar a técnica de programação orientada a objetos para o nosso programa. Mas antes, vamos importar as bibliotecas necessárias.

 da importação do tkinter * 
from PIL import Image
importação io
import numpy como np
import matplotlib.pyplot como plt
de keras.models import load_model
importar cv2

Agora deixe-me explicar por que precisamos disso. Tkinter é nossa principal biblioteca e ferramenta para criar interface do usuário. Precisamos de imagem do PIL para trabalhar com nossas imagens. Francamente falando, não é reconhecimento em tempo real. Na realidade, salvamos nosso estado atual da tela e, em seguida, convertemo-lo e abrir como uma imagem para processamento, remodelação e dando como entrada para o nosso modelo. io é para codificar nosso postscript. Numpy é o pacote fundamental para computação científica com Python. Matplotlib é uma biblioteca para visualizações. cv2 é biblioteca OpenCV, precisamos apenas para processamento de imagem.

Já é hora de construir nossa classe.

 class DigitsClassifier (Frame): 
"" "Classe de classificador de dígitos manuscritos" ""
def __init __ (self, parent):
Quadro .__ init __ (auto, pai)
self.parent = pai
self.color = "preto"
self.brush_size = 12
self.setUI ()
def set_color (self, new_color):
"" "Mudança de cor adicional do pincel" ""
self.color = new_color
def set_brush_size (self, new_size):
"" "Altera o tamanho do pincel para testar diferentes larguras de linhas" ""
self.brush_size = new_size
def draw (self, event):
"" "Método para desenhar" ""
self.canv.create_oval (event.x - self.brush_size,
event.y - self.brush_size,
event.x + self.brush_size,
event.y + self.brush_size,
preenchimento = self.color, outline = self.color)

Você viu a janela do nosso programa na parte anterior. Aqui estão os métodos que estão fazendo este trabalho. Criamos algumas variáveis quando o objeto é criado. set_color e set_brush_size mudam o estado das variáveis correspondentes. O método draw cria pequenos círculos na posição do botão do mouse clicado e quando o movemos, muitos círculos criam a linha. Agora avançando para outro método:

 def save (auto): 
"" "Salve o estado atual da tela como o postscript
usa o método classify e mostra o resultado "" "
self.canv.update ()
ps = self.canv.postscript (colormode = 'mono')
img = Image.open (io.BytesIO (ps.encode ('utf-8')))
img.save ('result.png')
a = DigitsClassifier.classify ()
imprimir (a)
self.show_digit (a)

Precisamos desse método para salvar o estado atual da tela como um postscript e, em seguida, codificá-lo e convertê-lo em bytes e salvá-lo como uma imagem. Sim, é estranho e um pouco mais longo, mas é a única maneira de salvar o estado atual da tela. Agora podemos classificar nosso dígito nesta imagem.

 @staticmethod 
def classify ():
"" "
Processe a imagem do dígito de entrada e retorne o resultado
: return: digit
"" "
classificador = load_model ("digit_recognition.model")
im = cv2.imread ("result.png", 0)
im2 = cv2.resize (im, (28, 28))
im = im2.reshape (28, 28, -1)
im = im.reshape (1, 1, 28, 28)
im = cv2.bitwise_not (im)
plt.imshow (im.reshape (28, 28), cmap = 'Grays')
result = classifier.predict (im)
a = np.argmax (resultado)
devolver um

Aqui nós carregamos o modelo que já criamos. Depois disso, lemos nossa imagem salva e a processamos para parecer com os dados MNIST (veja na primeira parte). Este método também prevê o dígito na imagem e retorna o inteiro, que podemos exibir em nossa janela usando o próximo método:

 def show_digit (self, digit): 
"" "
Mostrar o dígito na tela
: param dígito: int
: retorno: Nenhum
"" "
text_label = Label (self, text = digit)
text_label.grid (linha = 0, coluna = 5, padx = 5, pady = 5)

E o último, mas não o menos importante, devemos adicionar o método para definir os elementos da interface do usuário.

 def setUI (self): 
"" "Configuração para todos os elementos da interface do usuário" ""
self.parent.title ("Classificador de Dígitos Desenhados")
self.pack (fill = BOTH, expand = 1)
self.columnconfigure (6, peso = 1)
self.rowconfigure (2, peso = 1)
self.canv = Canvas (auto, bg = "branco")
self.canv.grid (linha = 2, coluna = 0, colunaspan = 7,
padx = 5, pady = 5,
pegajoso = E + W + S + N)
self.canv.bind ("<B1-Motion>",
self.draw)
color_lab = Rótulo (auto, texto = "Cor:")
color_lab.grid (linha = 0, coluna = 0,
padx = 6)
black_btn = Botão (auto, texto = "Preto", largura = 10,
comando = lambda: self.set_color ("preto"))
black_btn.grid (linha = 0, coluna = 2)
white_btn = Botão (auto, texto = "Branco", largura = 10,
comando = lambda: self.set_color ("branco"))
white_btn.grid (linha = 0, coluna = 3)
clear_btn = Botão (auto, texto = "Limpar tudo", largura = 10,
comando = lambda: self.canv.delete ("all"))
clear_btn.grid (linha = 0, coluna = 4, pegajosa = W)
size_lab = Label (self, text = "Tamanho do pincel:")
size_lab.grid (linha = 1, coluna = 0, padx = 5)
five_btn = Botão (auto, texto = "Sete", largura = 10,
comando = lambda: self.set_brush_size (7))
five_btn.grid (linha = 1, coluna = 2)
seven_btn = Botão (auto, texto = "Dez", largura = 10,
comando = lambda: self.set_brush_size (10))
seven_btn.grid (linha = 1, coluna = 3)
ten_btn = Botão (auto, texto = "Vinte", largura = 10,
comando = lambda: self.set_brush_size (20))
ten_btn.grid (linha = 1, coluna = 4)
done_btn = Botão (auto, texto = "Feito", largura = 10,
comando = lambda: self.save ())
done_btn.grid (linha = 1, coluna = 5)

Aqui criamos nossa tela, grade, rótulos de texto e botões. Todos esses elementos são colocados na grade.

E bloco de código final após a criação da classe.

 def main (): 
root = Tk ()
root.geometry ("400x400")
root.resizable (0, 0)
app = DigitsClassifier (root)
root.mainloop ()
se __name__ == '__main__':
a Principal()

Aqui está. Nosso programa está pronto. O processamento de uma imagem demora cerca de 3 a 5 segundos. O modelo funciona perfeitamente e rápido, mas infelizmente, devemos salvar a tela como postscript e convertê-la em uma imagem que leva muito tempo, mas ainda é boa e empolgante. Aproveite o seu projeto. Obrigado por ler.

Não se esqueça de nos dar o seu ?!