Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -13,39 +13,116 @@ except ImportError:
|
|
13 |
import requests
|
14 |
|
15 |
TITLE = "English to Pakistan Sign Language Translator"
|
16 |
-
DESCRIPTION = """This app translates English text to Pakistan Sign Language
|
|
|
|
|
17 |
|
18 |
**NOTE:**
|
19 |
-
- The
|
20 |
-
-
|
21 |
- For best results, use simple sentences
|
22 |
"""
|
23 |
|
24 |
-
#
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
29 |
try:
|
30 |
-
|
|
|
|
|
|
|
|
|
31 |
except Exception as e:
|
32 |
-
print(f"Error initializing
|
33 |
-
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
-
def
|
36 |
-
"""
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
def english_to_urdu(text):
|
43 |
-
"""Translate English text to Urdu
|
44 |
if not text:
|
45 |
return "", "Please enter text to translate"
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
try:
|
48 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
url = f"https://api.mymemory.translated.net/get?q={text}&langpair=en|ur"
|
50 |
response = requests.get(url)
|
51 |
data = response.json()
|
@@ -53,68 +130,114 @@ def english_to_urdu(text):
|
|
53 |
if "responseData" in data and "translatedText" in data["responseData"]:
|
54 |
urdu_text = data["responseData"]["translatedText"]
|
55 |
return urdu_text, f"Translated to Urdu: {urdu_text}"
|
56 |
-
|
57 |
-
|
58 |
|
59 |
except Exception as e:
|
60 |
print(f"Translation API error: {str(e)}")
|
61 |
return "", f"Error during Urdu translation: {str(e)}"
|
62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
def urdu_to_sign(urdu_text, format_type):
|
64 |
"""Translate Urdu text to Pakistan Sign Language"""
|
65 |
if not urdu_text:
|
66 |
return None, "No Urdu text to translate"
|
67 |
|
68 |
-
# Initialize
|
69 |
-
if not
|
70 |
-
return None, "Failed to initialize
|
71 |
|
72 |
try:
|
73 |
-
# Configure model
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
|
78 |
if format_type == "landmarks":
|
79 |
-
|
80 |
|
81 |
# Translate
|
82 |
-
output_path = "
|
83 |
-
sign =
|
84 |
|
85 |
# Save output
|
86 |
if isinstance(sign, slt.Landmarks):
|
87 |
-
# Position hands correctly
|
88 |
sign.data[:, 33:54, :3] += -sign.data[:, 33:34, :3] + sign.data[:, 15:16, :3]
|
89 |
sign.data[:, 54:, :3] += -sign.data[:, 54:55, :3] + sign.data[:, 16:17, :3]
|
90 |
sign.save_animation(output_path, overwrite=True)
|
91 |
else:
|
92 |
sign.save(output_path, overwrite=True, codec="mp4v")
|
93 |
|
94 |
-
return output_path,
|
95 |
|
96 |
except Exception as e:
|
97 |
error_msg = str(e)
|
98 |
-
print(f"
|
99 |
-
return None, f"
|
100 |
|
101 |
def translate_english_to_sign(english_text, format_type):
|
102 |
-
"""Complete translation pipeline
|
103 |
if not english_text:
|
104 |
-
return None, ""
|
|
|
|
|
|
|
105 |
|
106 |
-
#
|
|
|
|
|
|
|
|
|
107 |
urdu_text, urdu_status = english_to_urdu(english_text)
|
108 |
if not urdu_text:
|
109 |
-
return None, urdu_status
|
110 |
|
111 |
-
#
|
112 |
video, sign_status = urdu_to_sign(urdu_text, format_type)
|
113 |
|
114 |
# Combine status messages
|
115 |
-
status = f"English: \"{english_text}\"\
|
116 |
|
117 |
-
return video, status
|
118 |
|
119 |
# Create the Gradio interface
|
120 |
with gr.Blocks(title=TITLE) as demo:
|
@@ -140,8 +263,8 @@ with gr.Blocks(title=TITLE) as demo:
|
|
140 |
clear_btn = gr.Button("Clear")
|
141 |
translate_btn = gr.Button("Translate", variant="primary")
|
142 |
|
143 |
-
# Intermediate Urdu translation
|
144 |
-
urdu_output = gr.Textbox(label="Urdu Translation", interactive=False)
|
145 |
|
146 |
# Status area
|
147 |
status_output = gr.Textbox(label="Status", interactive=False)
|
@@ -155,27 +278,22 @@ with gr.Blocks(title=TITLE) as demo:
|
|
155 |
show_download_button=True
|
156 |
)
|
157 |
|
158 |
-
# Examples
|
159 |
gr.Examples(
|
160 |
examples=[
|
161 |
-
["
|
162 |
-
["
|
163 |
-
["
|
164 |
-
["
|
165 |
],
|
166 |
inputs=[english_input, format_dropdown],
|
167 |
outputs=[video_output, urdu_output, status_output],
|
168 |
-
fn=
|
169 |
)
|
170 |
|
171 |
# Event handlers
|
172 |
-
def handle_translation(text, fmt):
|
173 |
-
video, status = translate_english_to_sign(text, fmt)
|
174 |
-
urdu = english_to_urdu(text)[0] if text else ""
|
175 |
-
return video, urdu, status
|
176 |
-
|
177 |
translate_btn.click(
|
178 |
-
fn=
|
179 |
inputs=[english_input, format_dropdown],
|
180 |
outputs=[video_output, urdu_output, status_output]
|
181 |
)
|
|
|
13 |
import requests
|
14 |
|
15 |
TITLE = "English to Pakistan Sign Language Translator"
|
16 |
+
DESCRIPTION = """This app translates English text to Pakistan Sign Language using two approaches:
|
17 |
+
1. Direct English to Pakistan Sign Language translation
|
18 |
+
2. English → Urdu → Pakistan Sign Language (as a fallback)
|
19 |
|
20 |
**NOTE:**
|
21 |
+
- The app will first try direct translation, then fallback to Urdu if needed
|
22 |
+
- Some simple phrases work better with direct translation
|
23 |
- For best results, use simple sentences
|
24 |
"""
|
25 |
|
26 |
+
# Common English phrases with their Urdu translations
|
27 |
+
COMMON_PHRASES = {
|
28 |
+
"how are you": "آپ کیسے ہیں",
|
29 |
+
"hello": "السلام علیکم",
|
30 |
+
"thank you": "شکریہ",
|
31 |
+
"good morning": "صبح بخیر",
|
32 |
+
"good afternoon": "دوپہر بخیر",
|
33 |
+
"good evening": "شام بخیر",
|
34 |
+
"good night": "شب بخیر",
|
35 |
+
"my name is": "میرا نام ہے",
|
36 |
+
"what is your name": "آپ کا نام کیا ہے",
|
37 |
+
"nice to meet you": "آپ سے مل کر خوشی ہوئی",
|
38 |
+
"i am fine": "میں ٹھیک ہوں",
|
39 |
+
"yes": "ہاں",
|
40 |
+
"no": "نہیں",
|
41 |
+
"please": "براہ کرم",
|
42 |
+
"sorry": "معذرت",
|
43 |
+
"goodbye": "خدا حافظ",
|
44 |
+
"i love you": "میں تم سے پیار کرتا ہوں",
|
45 |
+
"welcome": "خوش آمدید",
|
46 |
+
"excuse me": "معذرت",
|
47 |
+
"help": "مدد",
|
48 |
+
"where is": "کہاں ہے",
|
49 |
+
"what time is it": "کیا وقت ہوا ہے",
|
50 |
+
"how much is this": "یہ کتنے کا ہے",
|
51 |
+
"i understand": "میں سمجھتا ہوں",
|
52 |
+
"i don't understand": "میں نہیں سمجھتا",
|
53 |
+
}
|
54 |
|
55 |
+
# Global model variables
|
56 |
+
en_model = None
|
57 |
+
ur_model = None
|
58 |
+
|
59 |
+
def get_models():
|
60 |
+
"""Initialize both translation models"""
|
61 |
try:
|
62 |
+
print("Loading English model...")
|
63 |
+
en_model = slt.models.ConcatenativeSynthesis("en", "pk-sl", "video")
|
64 |
+
print("Loading Urdu model...")
|
65 |
+
ur_model = slt.models.ConcatenativeSynthesis("ur", "pk-sl", "video")
|
66 |
+
return en_model, ur_model
|
67 |
except Exception as e:
|
68 |
+
print(f"Error initializing models: {str(e)}")
|
69 |
+
return None, None
|
70 |
+
|
71 |
+
def initialize_models():
|
72 |
+
"""Ensure models are loaded"""
|
73 |
+
global en_model, ur_model
|
74 |
+
if en_model is None or ur_model is None:
|
75 |
+
en_model, ur_model = get_models()
|
76 |
+
return en_model is not None and ur_model is not None
|
77 |
|
78 |
+
def check_phrase_match(text):
|
79 |
+
"""Check if input matches any common phrases"""
|
80 |
+
text = text.lower().strip()
|
81 |
+
|
82 |
+
# Direct matches
|
83 |
+
if text in COMMON_PHRASES:
|
84 |
+
return COMMON_PHRASES[text]
|
85 |
+
|
86 |
+
# Check for partial matches at the beginning of the phrase
|
87 |
+
for eng, urdu in COMMON_PHRASES.items():
|
88 |
+
if text.startswith(eng + " "):
|
89 |
+
return urdu + text[len(eng):]
|
90 |
+
|
91 |
+
return None
|
92 |
|
93 |
def english_to_urdu(text):
|
94 |
+
"""Translate English text to Urdu"""
|
95 |
if not text:
|
96 |
return "", "Please enter text to translate"
|
97 |
|
98 |
+
# First check our custom dictionary
|
99 |
+
phrase_match = check_phrase_match(text.lower())
|
100 |
+
if phrase_match:
|
101 |
+
return phrase_match, f"Using known translation: {phrase_match}"
|
102 |
+
|
103 |
+
# Try multiple translation APIs for better reliability
|
104 |
try:
|
105 |
+
# First try Google Translate API via a proxy endpoint
|
106 |
+
url = "https://translate.googleapis.com/translate_a/single"
|
107 |
+
params = {
|
108 |
+
"client": "gtx",
|
109 |
+
"sl": "en",
|
110 |
+
"tl": "ur",
|
111 |
+
"dt": "t",
|
112 |
+
"q": text
|
113 |
+
}
|
114 |
+
|
115 |
+
response = requests.get(url, params=params)
|
116 |
+
if response.status_code == 200:
|
117 |
+
data = response.json()
|
118 |
+
try:
|
119 |
+
# Extract translation from response
|
120 |
+
translated_text = ''.join([sent[0] for sent in data[0]])
|
121 |
+
return translated_text, f"Translated to Urdu: {translated_text}"
|
122 |
+
except:
|
123 |
+
pass
|
124 |
+
|
125 |
+
# Fallback to MyMemory API
|
126 |
url = f"https://api.mymemory.translated.net/get?q={text}&langpair=en|ur"
|
127 |
response = requests.get(url)
|
128 |
data = response.json()
|
|
|
130 |
if "responseData" in data and "translatedText" in data["responseData"]:
|
131 |
urdu_text = data["responseData"]["translatedText"]
|
132 |
return urdu_text, f"Translated to Urdu: {urdu_text}"
|
133 |
+
|
134 |
+
return "", "Error: Could not translate to Urdu"
|
135 |
|
136 |
except Exception as e:
|
137 |
print(f"Translation API error: {str(e)}")
|
138 |
return "", f"Error during Urdu translation: {str(e)}"
|
139 |
|
140 |
+
def english_to_sign_direct(english_text, format_type):
|
141 |
+
"""Try direct English to Sign Language translation"""
|
142 |
+
if not english_text:
|
143 |
+
return None, "No English text to translate"
|
144 |
+
|
145 |
+
# Initialize models if needed
|
146 |
+
if not initialize_models():
|
147 |
+
return None, "Failed to initialize models"
|
148 |
+
|
149 |
+
try:
|
150 |
+
# Convert first letter to lowercase (required by model)
|
151 |
+
text = english_text[:1].lower() + english_text[1:] if english_text else ""
|
152 |
+
|
153 |
+
# Configure English model
|
154 |
+
en_model.text_language = "en"
|
155 |
+
en_model.sign_language = "pk-sl"
|
156 |
+
en_model.sign_format = format_type
|
157 |
+
|
158 |
+
if format_type == "landmarks":
|
159 |
+
en_model.sign_embedding_model = "mediapipe-world"
|
160 |
+
|
161 |
+
# Translate directly
|
162 |
+
output_path = "output_en.mp4"
|
163 |
+
sign = en_model.translate(text)
|
164 |
+
|
165 |
+
# Save output
|
166 |
+
if isinstance(sign, slt.Landmarks):
|
167 |
+
sign.data[:, 33:54, :3] += -sign.data[:, 33:34, :3] + sign.data[:, 15:16, :3]
|
168 |
+
sign.data[:, 54:, :3] += -sign.data[:, 54:55, :3] + sign.data[:, 16:17, :3]
|
169 |
+
sign.save_animation(output_path, overwrite=True)
|
170 |
+
else:
|
171 |
+
sign.save(output_path, overwrite=True, codec="mp4v")
|
172 |
+
|
173 |
+
return output_path, "Direct translation successful"
|
174 |
+
|
175 |
+
except Exception as e:
|
176 |
+
error_msg = str(e)
|
177 |
+
print(f"Direct translation error: {error_msg}")
|
178 |
+
return None, f"Direct translation failed: {error_msg}"
|
179 |
+
|
180 |
def urdu_to_sign(urdu_text, format_type):
|
181 |
"""Translate Urdu text to Pakistan Sign Language"""
|
182 |
if not urdu_text:
|
183 |
return None, "No Urdu text to translate"
|
184 |
|
185 |
+
# Initialize models if needed
|
186 |
+
if not initialize_models():
|
187 |
+
return None, "Failed to initialize models"
|
188 |
|
189 |
try:
|
190 |
+
# Configure Urdu model
|
191 |
+
ur_model.text_language = "ur"
|
192 |
+
ur_model.sign_language = "pk-sl"
|
193 |
+
ur_model.sign_format = format_type
|
194 |
|
195 |
if format_type == "landmarks":
|
196 |
+
ur_model.sign_embedding_model = "mediapipe-world"
|
197 |
|
198 |
# Translate
|
199 |
+
output_path = "output_ur.mp4"
|
200 |
+
sign = ur_model.translate(urdu_text)
|
201 |
|
202 |
# Save output
|
203 |
if isinstance(sign, slt.Landmarks):
|
|
|
204 |
sign.data[:, 33:54, :3] += -sign.data[:, 33:34, :3] + sign.data[:, 15:16, :3]
|
205 |
sign.data[:, 54:, :3] += -sign.data[:, 54:55, :3] + sign.data[:, 16:17, :3]
|
206 |
sign.save_animation(output_path, overwrite=True)
|
207 |
else:
|
208 |
sign.save(output_path, overwrite=True, codec="mp4v")
|
209 |
|
210 |
+
return output_path, "Urdu translation successful"
|
211 |
|
212 |
except Exception as e:
|
213 |
error_msg = str(e)
|
214 |
+
print(f"Urdu translation error: {error_msg}")
|
215 |
+
return None, f"Urdu translation failed: {error_msg}"
|
216 |
|
217 |
def translate_english_to_sign(english_text, format_type):
|
218 |
+
"""Complete translation pipeline with fallback option"""
|
219 |
if not english_text:
|
220 |
+
return None, "", ""
|
221 |
+
|
222 |
+
# Try direct translation first
|
223 |
+
video, direct_status = english_to_sign_direct(english_text, format_type)
|
224 |
|
225 |
+
# If direct translation works, return it
|
226 |
+
if video:
|
227 |
+
return video, "", f"English: \"{english_text}\"\nDirect translation: {direct_status}"
|
228 |
+
|
229 |
+
# If direct translation fails, try via Urdu
|
230 |
urdu_text, urdu_status = english_to_urdu(english_text)
|
231 |
if not urdu_text:
|
232 |
+
return None, "", f"English: \"{english_text}\"\nDirect translation failed\n{urdu_status}"
|
233 |
|
234 |
+
# Translate Urdu to Sign Language
|
235 |
video, sign_status = urdu_to_sign(urdu_text, format_type)
|
236 |
|
237 |
# Combine status messages
|
238 |
+
status = f"English: \"{english_text}\"\nDirect translation failed\nUsing Urdu: \"{urdu_text}\"\n{sign_status}"
|
239 |
|
240 |
+
return video, urdu_text, status
|
241 |
|
242 |
# Create the Gradio interface
|
243 |
with gr.Blocks(title=TITLE) as demo:
|
|
|
263 |
clear_btn = gr.Button("Clear")
|
264 |
translate_btn = gr.Button("Translate", variant="primary")
|
265 |
|
266 |
+
# Intermediate Urdu translation (may be empty if direct translation works)
|
267 |
+
urdu_output = gr.Textbox(label="Urdu Translation (if used)", interactive=False)
|
268 |
|
269 |
# Status area
|
270 |
status_output = gr.Textbox(label="Status", interactive=False)
|
|
|
278 |
show_download_button=True
|
279 |
)
|
280 |
|
281 |
+
# Examples that work well with this model
|
282 |
gr.Examples(
|
283 |
examples=[
|
284 |
+
["we are here", "video"],
|
285 |
+
["thank you", "video"],
|
286 |
+
["good morning", "video"],
|
287 |
+
["yes", "video"]
|
288 |
],
|
289 |
inputs=[english_input, format_dropdown],
|
290 |
outputs=[video_output, urdu_output, status_output],
|
291 |
+
fn=translate_english_to_sign
|
292 |
)
|
293 |
|
294 |
# Event handlers
|
|
|
|
|
|
|
|
|
|
|
295 |
translate_btn.click(
|
296 |
+
fn=translate_english_to_sign,
|
297 |
inputs=[english_input, format_dropdown],
|
298 |
outputs=[video_output, urdu_output, status_output]
|
299 |
)
|