|
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): |
|
|
|
self.window = Tk() |
|
self.demo_window() |
|
self.datafile() |
|
|
|
def datafile(self): |
|
|
|
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() |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
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): |
|
|
|
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) |
|
|
|
|
|
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) |
|
|
|
|
|
scrollbar = Scrollbar(self.text_widget) |
|
scrollbar.place(relheight=1, relx=0.974) |
|
scrollbar.configure(command=self.text_widget.yview) |
|
|
|
|
|
bottom_label = Label(self.window, bg=BG_GRAY, height=80) |
|
bottom_label.place(relwidth=1, rely=0.825) |
|
|
|
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_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 = 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_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): |
|
|
|
|
|
model = models.load_model("s2s") |
|
|
|
|
|
enc_outputs, state_h_enc, state_c_enc = model.layers[2].output |
|
|
|
self.en_model = Model(model.input[0], [state_h_enc, state_c_enc]) |
|
|
|
|
|
|
|
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] |
|
|
|
|
|
|
|
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) |
|
|
|
|
|
self.dec_model = Model( |
|
[model.input[1]] + dec_states_inputs, [dec_outputs] + dec_states |
|
) |
|
|
|
def decode_sequence(self, input_seq): |
|
|
|
reverse_target_char_index = dict(enumerate(self.target_characters)) |
|
|
|
states_value = self.en_model.predict(input_seq) |
|
|
|
|
|
|
|
|
|
co = cv.fit(self.target_characters) |
|
target_seq = np.array([co.transform(list("\t")).toarray().tolist()], dtype="float32") |
|
|
|
|
|
stop_condition = False |
|
|
|
decoded_sentence = "" |
|
while not stop_condition: |
|
|
|
output_chars, h, c = self.dec_model.predict([target_seq] + states_value) |
|
|
|
|
|
char_index = np.argmax(output_chars[0, -1, :]) |
|
text_char = reverse_target_char_index[char_index] |
|
decoded_sentence += text_char |
|
|
|
|
|
|
|
if text_char == "\n" or len(decoded_sentence) > self.max_target_length: |
|
stop_condition = True |
|
|
|
target_seq = np.zeros((1, 1, self.num_dec_chars)) |
|
target_seq[0, 0, char_index] = 1.0 |
|
states_value = [h, c] |
|
|
|
return decoded_sentence |
|
|
|
def on_enter(self, event): |
|
|
|
msg = self.e1.get() |
|
|
|
self.deocded_output(msg) |
|
|
|
def on_enter_voice(self, event): |
|
|
|
msg = self.output_box["text"] |
|
|
|
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) |
|
|
|
self.e1.insert(0, msg) |
|
|
|
|
|
except: |
|
print("Not working") |
|
|
|
|
|
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): |
|
|
|
|
|
|
|
|
|
|
|
|
|
en_in_data = self.bagofcharacters(msg.lower()) |
|
|
|
self.myText.set(self.decode_sequence(en_in_data)) |
|
|
|
def deocded_output_voice(self, msg): |
|
|
|
|
|
|
|
|
|
engine = pyttsx3.init() |
|
engine.setProperty("rate", 135) |
|
engine.say(msg) |
|
engine.runAndWait() |
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
LT = LangTRans() |
|
LT.run2() |
|
|