DemoRepo / LangTransGui.py
Language's picture
Initial
75487c0
import tkinter
from tkinter import messagebox
from tkinter import *
import pickle
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from tensorflow.keras.models import Model
from tensorflow.keras import models
from tensorflow.keras.layers import Input, LSTM, Dense
import speech_recognition as sr
import pyttsx3
BG_GRAY = "#ABB2B9"
BG_COLOR = "#000"
TEXT_COLOR = "#000"
FONT = "Melvetica 14"
FONT_BOLD = "Melvetica 13 bold"
cv = CountVectorizer(binary=True, tokenizer=lambda txt: txt.split(), stop_words=None, analyzer='char')
class LangTRans:
def __init__(self):
# initialize tkinter window and load the file
self.window = Tk()
self.demo_window()
self.datafile()
def datafile(self):
# get all datas from datafile and load the model.
datafile = pickle.load(open("training_data.pkl", "rb"))
self.input_characters = datafile['input_characters']
self.target_characters = datafile['target_characters']
self.max_input_length = datafile['max_input_length']
self.max_target_length = datafile['max_target_length']
self.num_en_chars = datafile['num_en_chars']
self.num_dec_chars = datafile['num_dec_chars']
self.loadmodel()
# runwindow
def run(self):
self.window.mainloop()
def run2(self):
self.window.mainloop()
def demo_window(self):
self.window.title("Language Translator")
self.window.resizable(width=False, height=False)
self.window.configure(width=800, height=300)
# head_label.place(relwidth=1)
# line = Label(self.window,width=450,bg=BG_COLOR)
# line.place(relwidth=1,rely=0.07,relheight=0.012)
self.myText = StringVar()
head_label = Label(self.window, text="Translate to french Language!", font=FONT_BOLD, pady=10)
head_label.grid(row=0, column=3, padx=20, pady=20, columnspan=5)
head_label.grid_rowconfigure(1, weight=1)
head_label.grid_columnconfigure(1, weight=1)
Label(self.window, text="Input Text:").grid(row=1, padx=10, pady=10)
self.e1 = Entry(self.window)
self.e1.grid(row=2, column=1)
send_button2 = Button(self.window, text="Voice", font=FONT_BOLD, width=2, bg="Red",
command=lambda: self.voice_input(None))
send_button2.grid(row=3, column=1, sticky=W + E + N + S, padx=20, pady=20)
Label(self.window, text="Translated text in French:").grid(row=1, column=4,sticky="W")
self.output_box = Label(self.window, width=20, text="", textvariable=self.myText)
self.output_box.grid(row=2, column=5)
self.e1 = Entry(self.window)
self.e1.grid(row=1, column=1)
send_button = Button(self.window, text="Translate", font=FONT_BOLD, width=2, bg="blue", command=lambda: self.on_enter(None))
send_button.grid(row=3, column=3, sticky=W + E + N + S, padx=20, pady=20)
send_button1 = Button(self.window, text="Voice Output", font=FONT_BOLD, bg="Red",
command=lambda: self.on_enter_voice(None))
send_button1.grid(row=3, column=4, sticky=W + E + N + S, padx=20, pady=20)
def main_window(self):
# add title to window and configure it
self.window.title("Language Translator")
self.window.resizable(width=False, height=False)
self.window.configure(width=520, height=520, bg=BG_COLOR)
head_label = Label(self.window, bg=BG_COLOR, fg=TEXT_COLOR, text="Translate to french Language!",
font=FONT_BOLD, pady=10)
head_label.place(relwidth=1)
line = Label(self.window, width=450, bg=BG_COLOR)
line.place(relwidth=1, rely=0.07, relheight=0.012)
# create text widget where input and output will be displayed
self.text_widget = Text(self.window, width=20, height=2, bg="#fff", fg="#000", font=FONT, padx=5, pady=5)
self.text_widget.place(relheight=0.745, relwidth=1, rely=0.08)
self.text_widget.configure(cursor="arrow", state=DISABLED)
# create scrollbar
scrollbar = Scrollbar(self.text_widget)
scrollbar.place(relheight=1, relx=0.974)
scrollbar.configure(command=self.text_widget.yview)
# create bottom label where text widget will placed
bottom_label = Label(self.window, bg=BG_GRAY, height=80)
bottom_label.place(relwidth=1, rely=0.825)
# this is for user to put english text
self.msg_entry = Entry(bottom_label, bg="#2C3E50", fg=TEXT_COLOR, font=FONT)
self.msg_entry.place(relwidth=0.65, relheight=0.06, rely=0.008, relx=0.008)
self.msg_entry.focus()
self.msg_entry.bind("<Return>", self.on_enter)
# send button which will call on_enter function to send the text
send_button2 = Button(bottom_label, text="Voice\n Input", font=FONT_BOLD, width=2, bg="Red",
command=lambda: self.voice_input(None))
send_button2.place(relx=0.66, rely=0.008, relheight=0.06, relwidth=0.1325)
# send button which will call on_enter function to send the text
send_button = Button(bottom_label, text="Only Text", font=FONT_BOLD, width=8, bg="Red",
command=lambda: self.on_enter(None))
send_button.place(relx=0.80, rely=0.008, relheight=0.03, relwidth=0.20)
# send button which will call on_enter function to send the text
send_button1 = Button(bottom_label, text="Voice", font=FONT_BOLD, width=2, bg="Red",
command=lambda: self.on_enter_voice(None))
send_button1.place(relx=0.80, rely=0.04, relheight=0.027, relwidth=0.20)
def loadmodel(self):
# Inference model
# load the model
model = models.load_model("s2s")
# construct encoder model from the output of second layer
# discard the encoder output and store only states.
enc_outputs, state_h_enc, state_c_enc = model.layers[2].output # lstm_1
# add input object and state from the layer.
self.en_model = Model(model.input[0], [state_h_enc, state_c_enc])
# create Input object for hidden and cell state for decoder
# shape of layer with hidden or latent dimension
dec_state_input_h = Input(shape=(256,), name="input_3")
dec_state_input_c = Input(shape=(256,), name="input_4")
dec_states_inputs = [dec_state_input_h, dec_state_input_c]
# add input from the encoder output and initialize with
# states.
dec_lstm = model.layers[3]
dec_outputs, state_h_dec, state_c_dec = dec_lstm(
model.input[1], initial_state=dec_states_inputs
)
dec_states = [state_h_dec, state_c_dec]
dec_dense = model.layers[4]
dec_outputs = dec_dense(dec_outputs)
# create Model with the input of decoder state input and encoder input
# and decoder output with the decoder states.
self.dec_model = Model(
[model.input[1]] + dec_states_inputs, [dec_outputs] + dec_states
)
def decode_sequence(self, input_seq):
# create dict object to get character from the index.
reverse_target_char_index = dict(enumerate(self.target_characters))
# get the states from the user input sequence
states_value = self.en_model.predict(input_seq)
# fit target characters and
# initialize every first character to be 1 which is '\t'.
# Generate empty target sequence of length 1.
co = cv.fit(self.target_characters)
target_seq = np.array([co.transform(list("\t")).toarray().tolist()], dtype="float32")
# if the iteration reaches the end of text than it will be stop the it
stop_condition = False
# append every predicted character in decoded sentence
decoded_sentence = ""
while not stop_condition:
# get predicted output and discard hidden and cell state.
output_chars, h, c = self.dec_model.predict([target_seq] + states_value)
# get the index and from dictionary get character from it.
char_index = np.argmax(output_chars[0, -1, :])
text_char = reverse_target_char_index[char_index]
decoded_sentence += text_char
# Exit condition: either hit max length
# or find stop character.
if text_char == "\n" or len(decoded_sentence) > self.max_target_length:
stop_condition = True
# update target sequence to the current character index.
target_seq = np.zeros((1, 1, self.num_dec_chars))
target_seq[0, 0, char_index] = 1.0
states_value = [h, c]
# return the decoded sentence
return decoded_sentence
def on_enter(self, event):
# get user query and bot response
msg = self.e1.get()
# self.my_msg(msg, "English")
self.deocded_output(msg)
def on_enter_voice(self, event):
# get user query and bot response
msg = self.output_box["text"]
# self.my_msg(msg, "English")
self.deocded_output_voice(msg)
def voice_input(self, event):
r = sr.Recognizer()
with sr.Microphone() as source:
audio = r.listen(source,phrase_time_limit=5)
try:
msg = r.recognize_google(audio)
# print(msg)
self.e1.insert(0, msg)
# self.msg_entry.insert(0,msg)
except:
print("Not working")
# tkinter.messagebox.showerror(title="Error", message="Sorry could not recognize what you said.")
def bagofcharacters(self, input_t):
cv = CountVectorizer(binary=True, tokenizer=lambda txt: txt.split(), stop_words=None, analyzer='char')
en_in_data = [];
pad_en = [1] + [0] * (len(self.input_characters) - 1)
cv_inp = cv.fit(self.input_characters)
en_in_data.append(cv_inp.transform(list(input_t)).toarray().tolist())
if len(input_t) < self.max_input_length:
for _ in range(self.max_input_length - len(input_t)):
en_in_data[0].append(pad_en)
return np.array(en_in_data, dtype="float32")
def deocded_output(self, msg):
# self.text_widget.configure(state=NORMAL)
# en_in_data = self.bagofcharacters(msg.lower() + ".")
# self.text_widget.insert(END, str(sender) + " : " + self.decode_sequence(en_in_data)
# + "\n\n")
# self.text_widget.configure(state=DISABLED)
# self.text_widget.see(END)
en_in_data = self.bagofcharacters(msg.lower())
# print(self.decode_sequence(en_in_data))
self.myText.set(self.decode_sequence(en_in_data))
def deocded_output_voice(self, msg):
# self.text_widget.configure(state=NORMAL)
# en_in_data = self.bagofcharacters(msg.lower() + ".")
# self.text_widget.insert(END, str(sender) + " : " + self.decode_sequence(en_in_data)
# + "\n\n")
engine = pyttsx3.init()
engine.setProperty("rate", 135)
engine.say(msg)
engine.runAndWait()
# self.text_widget.configure(state=DISABLED)
# self.text_widget.see(END)
def my_msg(self, msg, sender):
if not msg:
return
self.msg_entry.delete(0, END)
self.text_widget.configure(state=NORMAL)
self.text_widget.insert(END, str(sender) + " : " + str(msg) + "\n")
self.text_widget.configure(state=DISABLED)
# run the file
if __name__ == "__main__":
LT = LangTRans()
LT.run2()