gopalagra commited on
Commit
333179e
·
verified ·
1 Parent(s): 9ec241a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +202 -230
app.py CHANGED
@@ -65,6 +65,157 @@
65
  # interface.launch()
66
  # # demo.launch(share=True)
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  import gradio as gr
69
  from transformers import (
70
  BlipProcessor,
@@ -72,22 +223,20 @@ from transformers import (
72
  BlipForQuestionAnswering,
73
  pipeline
74
  )
75
- moderation_model = pipeline(
76
- "text-classification",
77
- model="Vrandan/Comment-Moderation",
78
- return_all_scores=True
79
- )
80
-
81
  from PIL import Image
82
  import torch
83
- from gtts import gTTS
84
  import tempfile
 
 
 
85
 
86
  # ----------------------
87
  # Device setup
88
  # ----------------------
89
  device = "cuda" if torch.cuda.is_available() else "cpu"
90
 
 
91
  # ----------------------
92
  # Load Models Once
93
  # ----------------------
@@ -113,41 +262,69 @@ moderation_model = pipeline("text-classification", model="unitary/toxic-bert")
113
 
114
  print("✅ All models loaded!")
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  # ----------------------
117
  # Safety Filter Function
118
  # ----------------------
119
  def is_caption_safe(caption):
120
  try:
121
  votes = moderation_model(caption)
122
- # If return_all_scores=True, it's [[{label, score}, ...]]
123
  if isinstance(votes, list) and isinstance(votes[0], list):
124
  votes = votes[0]
125
- # Now safe to loop
126
  for item in votes:
127
  if isinstance(item, dict) and item.get("label") in ["V", "V2"] and item.get("score", 0) > 0.5:
128
  return False
129
  except Exception as e:
130
  print("⚠️ Moderation failed:", e)
131
 
132
- # Fallback keywords
133
  unsafe_keywords = [
134
- "gun", "blood", "skull", "kill", "corpse", "gore", "knife", "weapon",
135
- "fire", "murder", "dead", "death", "suicide", "bomb", "explosion",
136
- "terrorist", "assault", "stab", "shoot", "pistol", "rifle", "shotgun",
137
- "grenade", "horror", "beheaded", "torture", "hostage", "rape",
138
- "war", "massacre", "chainsaw", "poison", "strangle", "hang", "drown"
139
  ]
140
  if any(word in caption.lower() for word in unsafe_keywords):
141
  return False
 
142
  return True
143
 
144
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
 
147
  # ----------------------
148
  # Caption + Translate + Speak
149
  # ----------------------
150
  def generate_caption_translate_speak(image, target_lang):
 
151
  # Step 1: Caption
152
  inputs = caption_processor(images=image, return_tensors="pt").to(device)
153
  with torch.no_grad():
@@ -156,7 +333,8 @@ def generate_caption_translate_speak(image, target_lang):
156
 
157
  # Step 1.5: Safety Check
158
  if not is_caption_safe(english_caption):
159
- return "⚠️ Warning: Unsafe or inappropriate content detected!", "", None
 
160
 
161
  # Step 2: Translate
162
  if target_lang in translation_models:
@@ -164,12 +342,11 @@ def generate_caption_translate_speak(image, target_lang):
164
  else:
165
  translated = "Translation not available"
166
 
167
- # Step 3: Generate Speech (English caption for now)
168
- tts = gTTS(english_caption, lang="en")
169
- tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
170
- tts.save(tmp_file.name)
171
 
172
- return english_caption, translated, tmp_file.name
173
 
174
  # ----------------------
175
  # VQA
@@ -180,17 +357,17 @@ def vqa_answer(image, question):
180
  out = vqa_model.generate(**inputs, max_new_tokens=50)
181
  answer = vqa_processor.decode(out[0], skip_special_tokens=True)
182
 
183
- # Run safety filter on answers too
184
  if not is_caption_safe(answer):
185
  return "⚠️ Warning: Unsafe or inappropriate content detected!"
186
 
187
  return answer
188
 
 
189
  # ----------------------
190
  # Gradio UI
191
  # ----------------------
192
  with gr.Blocks(title="BLIP Vision App") as demo:
193
- gr.Markdown("## 🖼️ BLIP: Image Captioning + Translation + Speech + VQA (with Safety Filter)")
194
 
195
  with gr.Tab("Caption + Translate + Speak"):
196
  with gr.Row():
@@ -198,7 +375,7 @@ with gr.Blocks(title="BLIP Vision App") as demo:
198
  lang_in = gr.Dropdown(["Hindi", "French", "Spanish"], label="Translate To", value="Hindi")
199
  eng_out = gr.Textbox(label="English Caption")
200
  trans_out = gr.Textbox(label="Translated Caption")
201
- audio_out = gr.Audio(label="Spoken Caption", type="filepath")
202
  btn1 = gr.Button("Generate Caption, Translate & Speak")
203
  btn1.click(generate_caption_translate_speak, inputs=[img_in, lang_in], outputs=[eng_out, trans_out, audio_out])
204
 
@@ -212,212 +389,7 @@ with gr.Blocks(title="BLIP Vision App") as demo:
212
 
213
  demo.launch()
214
 
215
-
216
-
217
-
218
-
219
-
220
- # import gradio as gr
221
- # from transformers import (
222
- # BlipProcessor,
223
- # BlipForConditionalGeneration,
224
- # BlipForQuestionAnswering,
225
- # pipeline
226
- # )
227
- # from PIL import Image
228
- # import torch
229
- # from gtts import gTTS
230
- # import tempfile
231
- # import numpy as np
232
- # import soundfile as sf
233
- # import librosa
234
- # import tempfile
235
-
236
- # def combine_audio(beep_path, speech_path):
237
- # """Combine beep + speech audio into one clip."""
238
- # beep, sr1 = sf.read(beep_path)
239
- # speech, sr2 = sf.read(speech_path)
240
-
241
- # # Resample beep if needed
242
- # if sr1 != sr2:
243
- # beep = librosa.resample(y=beep, orig_sr=sr1, target_sr=sr2)
244
- # sr1 = sr2
245
-
246
- # # Convert multi-channel to mono
247
- # if len(beep.shape) > 1:
248
- # beep = beep.mean(axis=1)
249
- # if len(speech.shape) > 1:
250
- # speech = speech.mean(axis=1)
251
-
252
- # # Concatenate beep + speech
253
- # combined = np.concatenate((beep, speech))
254
-
255
- # tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
256
- # sf.write(tmp_file.name, combined, sr1)
257
- # return tmp_file.name
258
-
259
- # # ----------------------
260
- # # Device setup
261
- # # ----------------------
262
- # device = "cuda" if torch.cuda.is_available() else "cpu"
263
-
264
- # # ----------------------
265
- # # Load Models Once
266
- # # ----------------------
267
- # print("🔄 Loading models...")
268
-
269
- # # Captioning
270
- # caption_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
271
- # caption_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-large").to(device)
272
-
273
- # # VQA
274
- # vqa_processor = BlipProcessor.from_pretrained("Salesforce/blip-vqa-base")
275
- # vqa_model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base").to(device)
276
-
277
- # # Translation
278
- # translation_models = {
279
- # "Hindi": pipeline("translation", model="Helsinki-NLP/opus-mt-en-hi"),
280
- # "French": pipeline("translation", model="Helsinki-NLP/opus-mt-en-fr"),
281
- # "Spanish": pipeline("translation", model="Helsinki-NLP/opus-mt-en-es"),
282
- # }
283
-
284
- # # Safety Moderation Pipeline
285
- # moderation_model = pipeline("text-classification", model="unitary/toxic-bert")
286
-
287
- # print("✅ All models loaded!")
288
-
289
-
290
- # # ----------------------
291
- # # Utility: Generate a Beep Sound
292
- # # ----------------------
293
- # def make_beep_sound(duration=0.5, freq=1000):
294
- # """Generate a short beep tone and save as temporary .wav file."""
295
- # samplerate = 44100
296
- # t = np.linspace(0, duration, int(samplerate * duration), endpoint=False)
297
- # wave = 0.5 * np.sin(2 * np.pi * freq * t)
298
- # tmp_beep = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
299
- # sf.write(tmp_beep.name, wave, samplerate)
300
- # return tmp_beep.name
301
-
302
-
303
- # # ----------------------
304
- # # Safety Filter Function
305
- # # ----------------------
306
- # def is_caption_safe(caption):
307
- # try:
308
- # votes = moderation_model(caption)
309
- # if isinstance(votes, list) and isinstance(votes[0], list):
310
- # votes = votes[0]
311
- # for item in votes:
312
- # if isinstance(item, dict) and item.get("label") in ["V", "V2"] and item.get("score", 0) > 0.5:
313
- # return False
314
- # except Exception as e:
315
- # print("⚠️ Moderation failed:", e)
316
-
317
- # unsafe_keywords = [
318
- # "gun", "blood", "skull", "kill", "corpse", "gore", "knife", "weapon",
319
- # "fire", "murder", "dead", "death", "suicide", "bomb", "explosion",
320
- # "terrorist", "assault", "stab", "shoot", "pistol", "rifle", "shotgun",
321
- # "grenade", "horror", "beheaded", "torture", "hostage", "rape",
322
- # "war", "massacre", "chainsaw", "poison", "strangle", "hang", "drown"
323
- # ]
324
- # if any(word in caption.lower() for word in unsafe_keywords):
325
- # return False
326
- # return True
327
-
328
-
329
- # # ----------------------
330
- # # Caption + Translate + Speak
331
- # # ----------------------
332
- # def generate_caption_translate_speak(image, target_lang):
333
- # # Step 1: Caption
334
- # inputs = caption_processor(images=image, return_tensors="pt").to(device)
335
- # with torch.no_grad():
336
- # out = caption_model.generate(**inputs, max_new_tokens=50)
337
- # english_caption = caption_processor.decode(out[0], skip_special_tokens=True)
338
-
339
- # # Step 1.5: Safety Check
340
- # if not is_caption_safe(english_caption):
341
- # # Generate beep
342
- # beep = make_beep_sound()
343
-
344
- # # Generate warning speech
345
- # tts = gTTS("Warning! Unsafe or inappropriate content detected.", lang="en")
346
- # speech_tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
347
- # tts.save(speech_tmp.name)
348
-
349
- # # Combine beep + speech
350
- # combined_audio = combine_audio(beep, speech_tmp.name)
351
-
352
- # # Return combined audio automatically
353
- # return "⚠️ Warning: Unsafe or inappropriate content detected!", "", combined_audio
354
-
355
-
356
-
357
- # # Step 2: Translate
358
- # if target_lang in translation_models:
359
- # translated = translation_models[target_lang](english_caption)[0]['translation_text']
360
- # else:
361
- # translated = "Translation not available"
362
-
363
- # # Step 3: Generate Speech (English caption)
364
- # tts = gTTS(english_caption, lang="en")
365
- # tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
366
- # tts.save(tmp_file.name)
367
-
368
- # return english_caption, translated, tmp_file.name
369
-
370
-
371
- # # ----------------------
372
- # # VQA
373
- # # ----------------------
374
- # def vqa_answer(image, question):
375
- # inputs = vqa_processor(image, question, return_tensors="pt").to(device)
376
- # with torch.no_grad():
377
- # out = vqa_model.generate(**inputs, max_new_tokens=50)
378
- # answer = vqa_processor.decode(out[0], skip_special_tokens=True)
379
-
380
- # if not is_caption_safe(answer):
381
- # beep = make_beep_sound()
382
- # tts = gTTS("Warning! Unsafe or inappropriate content detected.", lang="en")
383
- # speech_tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
384
- # tts.save(speech_tmp.name)
385
- # combined = combine_audio(beep, speech_tmp.name)
386
- # return "⚠️ Warning: Unsafe or inappropriate content detected!", combined
387
-
388
-
389
- # return answer, None
390
-
391
-
392
- # # ----------------------
393
- # # Gradio UI
394
- # # ----------------------
395
- # with gr.Blocks(title="BLIP Vision App") as demo:
396
- # gr.Markdown("## 🖼️ BLIP: Image Captioning + Translation + Speech + VQA (Auto-Play TTS + Safety Beep)")
397
-
398
- # # --- Caption + Translate + Speak ---
399
- # with gr.Tab("Caption + Translate + Speak"):
400
- # with gr.Row():
401
- # img_in = gr.Image(type="pil", label="Upload Image")
402
- # lang_in = gr.Dropdown(["Hindi", "French", "Spanish"], label="Translate To", value="Hindi")
403
- # eng_out = gr.Textbox(label="English Caption")
404
- # trans_out = gr.Textbox(label="Translated Caption")
405
- # audio_out = gr.Audio(label="Speech Output", type="filepath", autoplay=True) # Auto-plays TTS or beep
406
- # btn1 = gr.Button("Generate Caption, Translate & Speak")
407
- # btn1.click(generate_caption_translate_speak, inputs=[img_in, lang_in],
408
- # outputs=[eng_out, trans_out, audio_out])
409
-
410
- # # --- Visual Question Answering (VQA) ---
411
- # with gr.Tab("Visual Question Answering (VQA)"):
412
- # with gr.Row():
413
- # img_vqa = gr.Image(type="pil", label="Upload Image")
414
- # q_in = gr.Textbox(label="Ask a Question about the Image")
415
- # ans_out = gr.Textbox(label="Answer")
416
- # beep_out = gr.Audio(label="Alert Sound", type="filepath", autoplay=True) # Auto-plays beep
417
- # btn2 = gr.Button("Ask")
418
- # btn2.click(vqa_answer, inputs=[img_vqa, q_in], outputs=[ans_out, beep_out])
419
-
420
- # demo.launch()
421
 
422
 
423
 
 
65
  # interface.launch()
66
  # # demo.launch(share=True)
67
 
68
+ # import gradio as gr
69
+ # from transformers import (
70
+ # BlipProcessor,
71
+ # BlipForConditionalGeneration,
72
+ # BlipForQuestionAnswering,
73
+ # pipeline
74
+ # )
75
+ # moderation_model = pipeline(
76
+ # "text-classification",
77
+ # model="Vrandan/Comment-Moderation",
78
+ # return_all_scores=True
79
+ # )
80
+
81
+ # from PIL import Image
82
+ # import torch
83
+ # from gtts import gTTS
84
+ # import tempfile
85
+
86
+ # # ----------------------
87
+ # # Device setup
88
+ # # ----------------------
89
+ # device = "cuda" if torch.cuda.is_available() else "cpu"
90
+
91
+ # # ----------------------
92
+ # # Load Models Once
93
+ # # ----------------------
94
+ # print("🔄 Loading models...")
95
+
96
+ # # Captioning
97
+ # caption_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
98
+ # caption_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-large").to(device)
99
+
100
+ # # VQA
101
+ # vqa_processor = BlipProcessor.from_pretrained("Salesforce/blip-vqa-base")
102
+ # vqa_model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base").to(device)
103
+
104
+ # # Translation
105
+ # translation_models = {
106
+ # "Hindi": pipeline("translation", model="Helsinki-NLP/opus-mt-en-hi"),
107
+ # "French": pipeline("translation", model="Helsinki-NLP/opus-mt-en-fr"),
108
+ # "Spanish": pipeline("translation", model="Helsinki-NLP/opus-mt-en-es"),
109
+ # }
110
+
111
+ # # Safety Moderation Pipeline
112
+ # moderation_model = pipeline("text-classification", model="unitary/toxic-bert")
113
+
114
+ # print("✅ All models loaded!")
115
+
116
+ # # ----------------------
117
+ # # Safety Filter Function
118
+ # # ----------------------
119
+ # def is_caption_safe(caption):
120
+ # try:
121
+ # votes = moderation_model(caption)
122
+ # # If return_all_scores=True, it's [[{label, score}, ...]]
123
+ # if isinstance(votes, list) and isinstance(votes[0], list):
124
+ # votes = votes[0]
125
+ # # Now safe to loop
126
+ # for item in votes:
127
+ # if isinstance(item, dict) and item.get("label") in ["V", "V2"] and item.get("score", 0) > 0.5:
128
+ # return False
129
+ # except Exception as e:
130
+ # print("⚠️ Moderation failed:", e)
131
+
132
+ # # Fallback keywords
133
+ # unsafe_keywords = [
134
+ # "gun", "blood", "skull", "kill", "corpse", "gore", "knife", "weapon",
135
+ # "fire", "murder", "dead", "death", "suicide", "bomb", "explosion",
136
+ # "terrorist", "assault", "stab", "shoot", "pistol", "rifle", "shotgun",
137
+ # "grenade", "horror", "beheaded", "torture", "hostage", "rape",
138
+ # "war", "massacre", "chainsaw", "poison", "strangle", "hang", "drown"
139
+ # ]
140
+ # if any(word in caption.lower() for word in unsafe_keywords):
141
+ # return False
142
+ # return True
143
+
144
+
145
+
146
+
147
+ # # ----------------------
148
+ # # Caption + Translate + Speak
149
+ # # ----------------------
150
+ # def generate_caption_translate_speak(image, target_lang):
151
+ # # Step 1: Caption
152
+ # inputs = caption_processor(images=image, return_tensors="pt").to(device)
153
+ # with torch.no_grad():
154
+ # out = caption_model.generate(**inputs, max_new_tokens=50)
155
+ # english_caption = caption_processor.decode(out[0], skip_special_tokens=True)
156
+
157
+ # # Step 1.5: Safety Check
158
+ # if not is_caption_safe(english_caption):
159
+ # return "⚠️ Warning: Unsafe or inappropriate content detected!", "", None
160
+
161
+ # # Step 2: Translate
162
+ # if target_lang in translation_models:
163
+ # translated = translation_models[target_lang](english_caption)[0]['translation_text']
164
+ # else:
165
+ # translated = "Translation not available"
166
+
167
+ # # Step 3: Generate Speech (English caption for now)
168
+ # tts = gTTS(english_caption, lang="en")
169
+ # tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
170
+ # tts.save(tmp_file.name)
171
+
172
+ # return english_caption, translated, tmp_file.name
173
+
174
+ # # ----------------------
175
+ # # VQA
176
+ # # ----------------------
177
+ # def vqa_answer(image, question):
178
+ # inputs = vqa_processor(image, question, return_tensors="pt").to(device)
179
+ # with torch.no_grad():
180
+ # out = vqa_model.generate(**inputs, max_new_tokens=50)
181
+ # answer = vqa_processor.decode(out[0], skip_special_tokens=True)
182
+
183
+ # # Run safety filter on answers too
184
+ # if not is_caption_safe(answer):
185
+ # return "⚠️ Warning: Unsafe or inappropriate content detected!"
186
+
187
+ # return answer
188
+
189
+ # # ----------------------
190
+ # # Gradio UI
191
+ # # ----------------------
192
+ # with gr.Blocks(title="BLIP Vision App") as demo:
193
+ # gr.Markdown("## 🖼️ BLIP: Image Captioning + Translation + Speech + VQA (with Safety Filter)")
194
+
195
+ # with gr.Tab("Caption + Translate + Speak"):
196
+ # with gr.Row():
197
+ # img_in = gr.Image(type="pil", label="Upload Image")
198
+ # lang_in = gr.Dropdown(["Hindi", "French", "Spanish"], label="Translate To", value="Hindi")
199
+ # eng_out = gr.Textbox(label="English Caption")
200
+ # trans_out = gr.Textbox(label="Translated Caption")
201
+ # audio_out = gr.Audio(label="Spoken Caption", type="filepath")
202
+ # btn1 = gr.Button("Generate Caption, Translate & Speak")
203
+ # btn1.click(generate_caption_translate_speak, inputs=[img_in, lang_in], outputs=[eng_out, trans_out, audio_out])
204
+
205
+ # with gr.Tab("Visual Question Answering (VQA)"):
206
+ # with gr.Row():
207
+ # img_vqa = gr.Image(type="pil", label="Upload Image")
208
+ # q_in = gr.Textbox(label="Ask a Question about the Image")
209
+ # ans_out = gr.Textbox(label="Answer")
210
+ # btn2 = gr.Button("Ask")
211
+ # btn2.click(vqa_answer, inputs=[img_vqa, q_in], outputs=ans_out)
212
+
213
+ # demo.launch()
214
+
215
+
216
+
217
+
218
+
219
  import gradio as gr
220
  from transformers import (
221
  BlipProcessor,
 
223
  BlipForQuestionAnswering,
224
  pipeline
225
  )
 
 
 
 
 
 
226
  from PIL import Image
227
  import torch
228
+ import pyttsx3
229
  import tempfile
230
+ import numpy as np
231
+ import soundfile as sf
232
+
233
 
234
  # ----------------------
235
  # Device setup
236
  # ----------------------
237
  device = "cuda" if torch.cuda.is_available() else "cpu"
238
 
239
+
240
  # ----------------------
241
  # Load Models Once
242
  # ----------------------
 
262
 
263
  print("✅ All models loaded!")
264
 
265
+
266
+ # ----------------------
267
+ # Beep Generator
268
+ # ----------------------
269
+ def generate_beep():
270
+ sr = 44100
271
+ duration = 0.4
272
+ frequency = 880
273
+
274
+ t = np.linspace(0, duration, int(sr * duration), False)
275
+ wave = 0.5 * np.sin(2 * np.pi * frequency * t)
276
+
277
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
278
+ sf.write(tmp.name, wave, sr)
279
+ return tmp.name
280
+
281
+
282
  # ----------------------
283
  # Safety Filter Function
284
  # ----------------------
285
  def is_caption_safe(caption):
286
  try:
287
  votes = moderation_model(caption)
 
288
  if isinstance(votes, list) and isinstance(votes[0], list):
289
  votes = votes[0]
290
+
291
  for item in votes:
292
  if isinstance(item, dict) and item.get("label") in ["V", "V2"] and item.get("score", 0) > 0.5:
293
  return False
294
  except Exception as e:
295
  print("⚠️ Moderation failed:", e)
296
 
 
297
  unsafe_keywords = [
298
+ "gun", "blood", "skull", "kill", "corpse", "gore", "knife", "weapon",
299
+ "fire", "murder", "dead", "death", "suicide", "bomb", "explosion",
300
+ "terrorist", "assault", "stab", "shoot", "pistol", "rifle", "shotgun",
301
+ "grenade", "horror", "beheaded", "torture", "hostage", "rape",
302
+ "war", "massacre", "chainsaw", "poison", "strangle", "hang", "drown"
303
  ]
304
  if any(word in caption.lower() for word in unsafe_keywords):
305
  return False
306
+
307
  return True
308
 
309
 
310
+ # ----------------------
311
+ # Offline Text-to-Speech using pyttsx3
312
+ # ----------------------
313
+ def offline_tts(text):
314
+ engine = pyttsx3.init()
315
+
316
+ tmp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
317
+ engine.save_to_file(text, tmp_audio.name)
318
+ engine.runAndWait()
319
+
320
+ return tmp_audio.name
321
 
322
 
323
  # ----------------------
324
  # Caption + Translate + Speak
325
  # ----------------------
326
  def generate_caption_translate_speak(image, target_lang):
327
+
328
  # Step 1: Caption
329
  inputs = caption_processor(images=image, return_tensors="pt").to(device)
330
  with torch.no_grad():
 
333
 
334
  # Step 1.5: Safety Check
335
  if not is_caption_safe(english_caption):
336
+ beep = generate_beep()
337
+ return "⚠️ Warning: Unsafe or inappropriate content detected!", "", beep
338
 
339
  # Step 2: Translate
340
  if target_lang in translation_models:
 
342
  else:
343
  translated = "Translation not available"
344
 
345
+ # Step 3: Offline Speech
346
+ audio_path = offline_tts(english_caption)
347
+
348
+ return english_caption, translated, audio_path
349
 
 
350
 
351
  # ----------------------
352
  # VQA
 
357
  out = vqa_model.generate(**inputs, max_new_tokens=50)
358
  answer = vqa_processor.decode(out[0], skip_special_tokens=True)
359
 
 
360
  if not is_caption_safe(answer):
361
  return "⚠️ Warning: Unsafe or inappropriate content detected!"
362
 
363
  return answer
364
 
365
+
366
  # ----------------------
367
  # Gradio UI
368
  # ----------------------
369
  with gr.Blocks(title="BLIP Vision App") as demo:
370
+ gr.Markdown("## 🖼️ BLIP: Image Captioning + Translation + Speech + VQA (with Safety Filter + Warning Beep)")
371
 
372
  with gr.Tab("Caption + Translate + Speak"):
373
  with gr.Row():
 
375
  lang_in = gr.Dropdown(["Hindi", "French", "Spanish"], label="Translate To", value="Hindi")
376
  eng_out = gr.Textbox(label="English Caption")
377
  trans_out = gr.Textbox(label="Translated Caption")
378
+ audio_out = gr.Audio(label="Spoken Caption / Warning Beep", type="filepath")
379
  btn1 = gr.Button("Generate Caption, Translate & Speak")
380
  btn1.click(generate_caption_translate_speak, inputs=[img_in, lang_in], outputs=[eng_out, trans_out, audio_out])
381
 
 
389
 
390
  demo.launch()
391
 
392
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
 
394
 
395