Spaces:
Sleeping
Sleeping
| import asyncio | |
| import cv2 | |
| import time | |
| import sounddevice as sd | |
| from scipy.io.wavfile import write | |
| import speech_recognition as sr | |
| import edge_tts | |
| import os | |
| import pygame | |
| import unicodedata | |
| from datetime import datetime | |
| FAMILY_FOLDER = "family" | |
| CAPTURE_FOLDER = "captured_images" | |
| for folder in [FAMILY_FOLDER, CAPTURE_FOLDER]: | |
| if not os.path.exists(folder): | |
| os.makedirs(folder) | |
| # Initialize pygame mixer for playing TTS audio | |
| pygame.mixer.init() | |
| def normalize_text(text): | |
| """ | |
| Normalize Arabic text by removing diacritics and converting to lowercase. | |
| This function uses Unicode normalization to strip combining characters (harakat) | |
| and then returns the clean, lowercased text. | |
| Args: | |
| text (str): Arabic text to normalize. | |
| Returns: | |
| str: Normalized text without diacritics and in lowercase. | |
| """ | |
| text = unicodedata.normalize('NFKD', text) | |
| text = ''.join(c for c in text if not unicodedata.combining(c)) | |
| return text.lower().strip() | |
| # List of recognized voice commands (normalized) | |
| START_COMMANDS = [normalize_text(cmd) for cmd in ["ุฃูููููุง ู ูุจูุตูุฑ", "ู ูุฑูุญูุจูุง ู ูุจูุตูุฑ", "ุงูุณููููุงู ู ุนูููููู"]] | |
| EXPLORE_COMMANDS = [normalize_text(cmd) for cmd in ["ุงูุณูุชูููุดููู ุงูู ูููุงู", "ุงูุณูุชูููุดูุงู ุงูู ูููุงู", "ุงูุณูุชูููุดูุงู"]] | |
| PHOTO_COMMANDS = [normalize_text(cmd) for cmd in ["ุงูููุชูููุทู ุตููุฑูุฉ", "ุตููููุฑู", "ุฃูุฎูุฐู ุตููุฑูุฉ"]] | |
| EXIT_COMMANDS = [normalize_text(cmd) for cmd in ["ุดูููุฑูุง ู ูุจูุตูุฑ", "ุฅูููููุงุก", "ุฎูุฑููุฌ"]] | |
| # Text-to-Speech using Edge TTS | |
| async def edge_speak(text): | |
| """ | |
| Convert Arabic text to speech using Edge TTS and play it. | |
| This function creates an MP3 file using Edge TTS with an Arabic voice, | |
| plays it using pygame, and then deletes the file after playback. | |
| Args: | |
| text (str): Arabic text to speak. | |
| """ | |
| voice = "ar-EG-SalmaNeural" | |
| filename = "temp.mp3" | |
| communicate = edge_tts.Communicate(text, voice) | |
| await communicate.save(filename) | |
| try: | |
| pygame.mixer.music.load(filename) | |
| pygame.mixer.music.play() | |
| while pygame.mixer.music.get_busy(): | |
| pygame.time.Clock().tick(10) | |
| finally: | |
| pygame.mixer.music.unload() | |
| if os.path.exists(filename): | |
| os.remove(filename) | |
| # Speech recognition | |
| def listen_once(duration=3, fs=16000): | |
| """ | |
| Record a short audio clip from the microphone and transcribe it to text. | |
| Uses Google Speech Recognition (with Arabic language) to convert speech to text. | |
| Normalizes the result before returning. | |
| Args: | |
| duration (int, optional): Recording duration in seconds. Default is 3. | |
| fs (int, optional): Sample rate in Hz. Default is 16000. | |
| Returns: | |
| str: Normalized recognized text, or an empty string if recognition fails. | |
| """ | |
| print("๐ค ููุณูุชูู ูุนู...") | |
| recording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16') | |
| sd.wait() | |
| filename = "temp.wav" | |
| write(filename, fs, recording) | |
| recognizer = sr.Recognizer() | |
| with sr.AudioFile(filename) as source: | |
| audio = recognizer.record(source) | |
| try: | |
| text = recognizer.recognize_google(audio, language="ar-EG") | |
| print(f" ููููุชู: {text}") | |
| return normalize_text(text) | |
| except sr.UnknownValueError: | |
| print("ููู ู ุฃูููููู ู ุงูููููุงู ู") | |
| return "" | |
| except sr.RequestError as e: | |
| print(f"ุฎูุทูุฃู ููู ุฎูุฏูู ูุฉู ุงูุชููุนูุฑูููู: {e}") | |
| return "" | |
| finally: | |
| if os.path.exists(filename): | |
| os.remove(filename) | |
| # Image capture functions | |
| def capture_Family_image(): | |
| """ | |
| Capture an image and save it to the 'family' folder with a custom name. | |
| Prompts the user to enter a filename, checks for duplicates, and saves | |
| the captured photo using OpenCV. | |
| Returns: | |
| str or None: File path of the saved image if successful, or None if failed. | |
| """ | |
| print("ุณูููุชูู ูู ุงูุชููุตููููุฑู ุจูุนูุฏู ูฃ ุซูููุงูู... ุงูุจูุชูุณูู ู ") | |
| time.sleep(3) | |
| try: | |
| cam = cv2.VideoCapture(0) | |
| if not cam.isOpened(): | |
| raise Exception("๐ท ููู ู ุฃูุชูู ูููููู ู ููู ููุชูุญู ุงูููุงู ููุฑูุง") | |
| ret, frame = cam.read() | |
| cam.release() | |
| if not ret: | |
| raise Exception("ููู ู ุฃูุชูู ูููููู ู ููู ุงูุชููููุงุทู ุงูุตูููุฑูุฉ") | |
| while True: | |
| img_name_input = input("ุฃูุฏูุฎููู ุงุณูู ู ุงูุตูููุฑูุฉู (ุจุฏูู ุงู ุชุฏุงุฏ): ").strip() | |
| if img_name_input: | |
| img_name_clean = "".join(c for c in img_name_input if c.isalnum()) | |
| if not img_name_clean: | |
| print("ููุฐูุง ุงูุงูุณูู ู ุบูููุฑู ุตูุงููุญูุ ุฌูุฑููุจู ุงุณูู ูุง ุขุฎูุฑู.") | |
| continue | |
| img_path = os.path.join(FAMILY_FOLDER, f"{img_name_clean}.png") | |
| if os.path.exists(img_path): | |
| print("ุงูุตูููุฑูุฉู ู ูููุฌููุฏูุฉู ุจูุงูููุนููู. ุงูุฎูุชูุฑู ุงุณูู ูุง ุขุฎูุฑู.") | |
| else: | |
| break | |
| else: | |
| print("ููู ู ุชูุฏูุฎููู ุฃูููู ุงุณูู ูุ ุฌูุฑููุจู ู ูุฑููุฉู ุฃูุฎูุฑูู.") | |
| cv2.imwrite(img_path, frame) | |
| print("ุชูู ูู ุงูุชููููุงุทู ุงูุตูููุฑูุฉู.") | |
| return img_path | |
| except Exception as e: | |
| print(f" ุฎูุทูุฃู: {e}") | |
| return None | |
| def capture_image(): | |
| """ | |
| Capture an image and save it to the 'captured_images' folder using a unique timestamp. | |
| Uses OpenCV to take the photo, waits for 3 seconds before capturing, and | |
| saves the image file with a timestamp-based name. | |
| Returns: | |
| str or None: File path of the saved image if successful, or None if failed. | |
| """ | |
| print(" ุณูููุชูู ูู ุงูุชููุตููููุฑู ุจูุนูุฏู ูฃ ุซูููุงูู... ุงูุจูุชูุณูู ู ") | |
| time.sleep(3) | |
| try: | |
| cam = cv2.VideoCapture(0) | |
| if not cam.isOpened(): | |
| raise Exception("๐ท ููู ู ุฃูุชูู ูููููู ู ููู ููุชูุญู ุงูููุงู ููุฑูุง") | |
| ret, frame = cam.read() | |
| cam.release() | |
| if not ret: | |
| raise Exception("๐ท ููู ู ุฃูุชูู ูููููู ู ููู ุงูุชููููุงุทู ุงูุตูููุฑูุฉ") | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| img_filename = f"image_{timestamp}.png" | |
| img_path = os.path.join(CAPTURE_FOLDER, img_filename) | |
| cv2.imwrite(img_path, frame) | |
| print(f" ุชูู ูู ุงูุชููููุงุทู ุงูุตูููุฑูุฉู ููุชูุฎูุฒููููููุง: {img_path}") | |
| return img_path | |
| except Exception as e: | |
| print(f"ุฎูุทูุฃู: {e}") | |
| return None | |