From 7edcb9ecdf8e62f44e518134b8e66df1971202d4 Mon Sep 17 00:00:00 2001 From: khanak khandelwal Date: Tue, 22 Jul 2025 14:28:07 +0530 Subject: [PATCH 01/25] Updated Gemini prompt to give short and concise scene descriptions --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 26160be..b0ef654 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ def speak(text): # IP Webcam URL (replace with your phone's IP) url = 'http://10.134.93.78:8080/video' # Update IP -cap = cv2.VideoCapture(url) +cap = cv2.VideoCapture(0) status = "Press 's' or say 'scan' to scan surroundings..." scan_triggered = False # Flag for voice activation @@ -31,7 +31,7 @@ def process_frame(frame): rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_image = Image.fromarray(rgb_frame) response = model.generate_content([ - "Describe this scene briefly for a blind user. If there are any signs like STOP or traffic lights, mention them clearly.", + "Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights.", pil_image ]) description = response.text.strip() From 270adde88ca5cff110892008496fa7e61547c6b3 Mon Sep 17 00:00:00 2001 From: khanak khandelwal Date: Tue, 22 Jul 2025 14:33:14 +0530 Subject: [PATCH 02/25] Updated Gemini prompt to give short and concise scene descriptions --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index b0ef654..3e4b7e2 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ def speak(text): # IP Webcam URL (replace with your phone's IP) url = 'http://10.134.93.78:8080/video' # Update IP -cap = cv2.VideoCapture(0) +cap = cv2.VideoCapture(url) status = "Press 's' or say 'scan' to scan surroundings..." scan_triggered = False # Flag for voice activation From cba8b9825bb3abd37034cbc6eeb9e66b38c56036 Mon Sep 17 00:00:00 2001 From: Roopakjeet Kaur Date: Fri, 25 Jul 2025 09:28:19 +0530 Subject: [PATCH 03/25] Add configurable TTS engine support (gTTS/pyttsx3) with offline fallback (#15) * Added TTS engine switch with gTTS/pyttsx3 and offline fallback * Remove .gitignore from repository * Remove __pycache__ from tracked files * Updated the prompt * Added Usage Comment --- config.py | 11 +++++++ main.py | 83 ++++++++++++++++++++++++------------------------ requirements.txt | 3 ++ tts_utils.py | 51 +++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 42 deletions(-) create mode 100644 config.py create mode 100644 tts_utils.py diff --git a/config.py b/config.py new file mode 100644 index 0000000..64a2631 --- /dev/null +++ b/config.py @@ -0,0 +1,11 @@ +# config.py +# Select the text-to-speech engine. +# Options: +# "gTTS" → uses Google Text-to-Speech (online, clearer) +# "pyttsx3" → uses system speech engine (offline, basic) + +TTS_ENGINE = "gTTS" # or "pyttsx3" + +# IP Webcam URL ((replace with your phone's IP)) +# Make sure your phone and laptop are on the same Wi-Fi +IP_WEBCAM_URL = "http://192.168.29.169:8080/video" \ No newline at end of file diff --git a/main.py b/main.py index 3e4b7e2..efb2409 100644 --- a/main.py +++ b/main.py @@ -1,43 +1,48 @@ import cv2 -import pyttsx3 -import google.generativeai as genai import numpy as np -import time import threading +import os import speech_recognition as sr from PIL import Image -import io - -# Initialize TTS engine -engine = pyttsx3.init() +from dotenv import load_dotenv +import socket +import google.generativeai as genai -def speak(text): - print("Speaking:", text) - engine.say(text) - engine.runAndWait() +from tts_utils import speak +from config import TTS_ENGINE, IP_WEBCAM_URL -# Initialize Gemini -genai.configure(api_key="API KEY") +# Load Gemini API key from .env +load_dotenv() +api_key = os.getenv("API_KEY") +genai.configure(api_key=api_key) model = genai.GenerativeModel(model_name="gemini-1.5-flash") -# IP Webcam URL (replace with your phone's IP) -url = 'http://10.134.93.78:8080/video' # Update IP -cap = cv2.VideoCapture(url) +def is_connected(): + try: + socket.create_connection(("www.google.com", 80), timeout=2) + return True + except OSError: + return False + +# Camera: IP Webcam (phone camera) +cap = cv2.VideoCapture(IP_WEBCAM_URL) status = "Press 's' or say 'scan' to scan surroundings..." -scan_triggered = False # Flag for voice activation +scan_triggered = False def process_frame(frame): rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_image = Image.fromarray(rgb_frame) - response = model.generate_content([ - "Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights.", - pil_image - ]) - description = response.text.strip() - return description - -# Voice recognition function + try: + response = model.generate_content([ + "Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights.", + pil_image + ]) + return response.text.strip() + except Exception as e: + print(f"[Gemini Error] {e}") + return "Unable to analyze surroundings due to internet issue." + def listen_for_scan(): global scan_triggered recognizer = sr.Recognizer() @@ -50,44 +55,38 @@ def listen_for_scan(): while True: with mic as source: try: - print("Listening...") audio = recognizer.listen(source, timeout=3, phrase_time_limit=5) command = recognizer.recognize_google(audio).lower() - print(f"Recognized: {command}") if "scan" in command: - print("Voice command 'scan' detected.") scan_triggered = True - except sr.WaitTimeoutError: - print("Listening timed out, retrying...") - except sr.UnknownValueError: - print("Could not understand audio.") - except sr.RequestError as e: - print(f"Speech recognition service error: {e}") - -# Start voice recognition in a separate thread + except (sr.WaitTimeoutError, sr.UnknownValueError, sr.RequestError): + pass + +# Start voice recognition in background voice_thread = threading.Thread(target=listen_for_scan, daemon=True) voice_thread.start() +if not is_connected(): + speak("Warning. You are offline. Scene analysis will not work.") + while True: ret, frame = cap.read() if not ret: - print("Camera error.") + print("Camera error. Check your IP Webcam app and Wi-Fi.") continue - cv2.putText(frame, status, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, - 0.8, (0, 255, 0), 2) - + cv2.putText(frame, status, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) cv2.imshow("Blind Assist Tool", frame) key = cv2.waitKey(1) & 0xFF if key == ord('s') or scan_triggered: - scan_triggered = False # reset flag + scan_triggered = False status = "Analyzing surroundings..." speak("Analyzing surroundings") desc = process_frame(frame) speak(desc) - # Detect important keywords + # Alert on specific signs if "stop sign" in desc.lower() or "stop" in desc.lower(): speak("Stop! There's a stop sign.") elif "red light" in desc.lower(): diff --git a/requirements.txt b/requirements.txt index 804c823..6d72124 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,10 @@ opencv-python pyttsx3 +gTTS google-generativeai numpy Pillow SpeechRecognition pyaudio +playsound +python-dotenv \ No newline at end of file diff --git a/tts_utils.py b/tts_utils.py new file mode 100644 index 0000000..6664625 --- /dev/null +++ b/tts_utils.py @@ -0,0 +1,51 @@ +""" +tts_utils.py + +Handles Text-to-Speech functionality for the Blind Assist Tool. +Supports both gTTS (online) and pyttsx3 (offline) engines with fallback. + +Usage: +- Import the speak() function and call speak("your message") +- Engine can be set in config.py using TTS_ENGINE = "gTTS" or "pyttsx3" + +""" + +from config import TTS_ENGINE +import pyttsx3 +from gtts import gTTS +from playsound import playsound +import tempfile +import os + +# Initialize pyttsx3 if selected +if TTS_ENGINE == "pyttsx3": + engine = pyttsx3.init() + +def speak(text): + print(f"Speaking ({TTS_ENGINE}): {text}") + + if TTS_ENGINE == "pyttsx3": + try: + engine.say(text) + engine.runAndWait() + except Exception as e: + print(f"[pyttsx3 Error] {e}") + + elif TTS_ENGINE == "gTTS": + try: + tts = gTTS(text=text, lang='en') + with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp: + tts.save(tmp.name) + playsound(tmp.name) + os.remove(tmp.name) + except Exception as e: + print(f"[gTTS Error] {e}. Falling back to pyttsx3.") + fallback_speak(text) + +def fallback_speak(text): + try: + engine = pyttsx3.init() + engine.say(text) + engine.runAndWait() + except Exception as e: + print(f"[Fallback pyttsx3 Error] {e}") From a2439add74e1128aa83e7f21568f9315fd7474ce Mon Sep 17 00:00:00 2001 From: Shivansh Katiyar Date: Wed, 30 Jul 2025 01:23:49 +0530 Subject: [PATCH 04/25] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..56af90a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 kaushav07 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 304d840138a7a0bfef74eeacca23144470826bf2 Mon Sep 17 00:00:00 2001 From: Shivansh Katiyar Date: Wed, 30 Jul 2025 01:25:33 +0530 Subject: [PATCH 05/25] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6af5802..5c9bb50 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,9 @@ Clone the repository and install dependencies: git clone https://github.com/kaushav07/VisionMate.git cd VisionMate pip install -r requirements.txt +``` + +## 📄 License + +This project is licensed under the [MIT License](LICENSE). + From 14c0b8b015b909c0422d2c024fc452cfa992f29f Mon Sep 17 00:00:00 2001 From: Krithika Date: Sat, 2 Aug 2025 14:07:55 +0530 Subject: [PATCH 06/25] Add scan_logger utility for logging scans (#19) * Add scan_logger utility for logging scans * contributors guide * Coorected: Scan_Logger --- CONTRIBUTING.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ scan_logger.py | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 scan_logger.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..0afc095 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,53 @@ +# 👥 Contribution Guide + +Welcome to the Hall of Fame! 🏆 + +Every line of code, every bug fix, every pixel of design — it all comes from people like **you**. + +------------------------------------------------------------------------------------------ +**VisionMate** is more than just an AI project — it’s a growing community of learners, builders, and innovators 💡. + +🧠💻🎨🚀💬 +From developers to designers to curious first-timers — we see you, we appreciate you, and we welcome you. + +------------------------------------------------------------------------------------------- + + +## 🛠️ Contribution Areas + +You can contribute to: + +🎨Python – Core backend and computer vision +🧠OpenCV – Image processing and recognition +🗃️Flask / Django – Backend framework (to be finalized) +📊React.js / Flutter – Frontend or app interface +📊MySQL – Data storage +📋Google Cloud Vision API – (future integration) +📋Text-to-Speech / Speech-to-Text APIs – Accessibility tools + + +------------------------------------------------------------------------------------------- + +## 🚀 Getting Started + + +Follow these steps to contribute to the VisionMate project on your local machine: + +# 1. Fork the Repository +By clicking on the Fork button of the repository, you get access to commit changes and push them in github. + + +# 2. Clone the repository +git clone https://github.com/kaushav07/VisionMate.git + +# 3. Navigate into the project directory +cd VisionMate + +# 4. Install all the required dependencies +pip install -r requirements.txt + + + + +------------------------------------------------------------------------------------------- + diff --git a/scan_logger.py b/scan_logger.py new file mode 100644 index 0000000..926fad6 --- /dev/null +++ b/scan_logger.py @@ -0,0 +1,36 @@ +import datetime + + +scan_history = [] + + # FUNCTION TO LOG SCAN ENTRY +def log_scan(caption, user_command): + timestamp = datetime.datetime.now().strftime('%d-%m-%Y, %H:%M:%S') + entry = { + "timestamp": timestamp, # Key = "timestamp", value = current time + "caption": caption, # Key = "caption", value = passed caption + "user_command": user_command # Key = "user_command", value = passed command + } + scan_history.append(entry) + print("✅ Logged entry successfully!") + +# FUNCTION TO SHOW ALL HISTORY (DEFINED OUTSIDE log_scan) +def show_history(): + if not scan_history: + print("\n📭 No scan history available.") + return + + print("\n📜 Scan History:") + for i, entry in enumerate(scan_history, start=1): + print(f"\n🔹 Entry {i}") + print(f" 🕒 Time: {entry['timestamp']}") + print(f" 🖼️ Caption: {entry['caption']}") + print(f" 💬 User Command: {entry['user_command']}") + +# DEMO — WRAPPED IN if __name__ == "__main__" +if __name__ == "__main__": + log_scan("A man passing the main road", "Alert User") + log_scan("A family roaming in a busy market", "Describe the surroundings") + log_scan("Animal moving freely in the zoo", "Describe the surroundings") + + show_history() From 2cbc45a443f3ac978f591e1e29a4254f0247c862 Mon Sep 17 00:00:00 2001 From: Zehen-249 <1hasanmehendi123@gmail.com> Date: Mon, 4 Aug 2025 16:55:07 +0530 Subject: [PATCH 07/25] Feature: Add face recognition and FastAPI integration This commit introduces a new face recognition feature. It includes the following changes: - Added face_recog.py for face recognition API - Integrated FastAPI for serving the application - Created utility functions for face and speech processing - Refactored existing TTS utilities into a service module - Updated shared configuration and paths for better organization - Added main application entry point - Updated main.py to include new services and routes - Renamed tts_utils.py to app/services/tts_utils.py for consistency - Added shared utilities for common functions - Updated paths for better modularity and maintainability - Ensured compatibility with existing codebase - Improved code organization and readability - Added necessary imports and dependencies - Enhanced documentation and comments for clarity --- app/api/perception/vision/face_recog.py | 32 +++++++++ app/main.py | 7 ++ app/services/face_utils.py | 83 +++++++++++++++++++++++ app/services/stt_utils.py | 11 +++ tts_utils.py => app/services/tts_utils.py | 0 app/shared/config.py | 13 ++++ app/shared/paths.py | 19 ++++++ app/shared/utils.py | 40 +++++++++++ main.py | 2 +- 9 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 app/api/perception/vision/face_recog.py create mode 100644 app/main.py create mode 100644 app/services/face_utils.py create mode 100644 app/services/stt_utils.py rename tts_utils.py => app/services/tts_utils.py (100%) create mode 100644 app/shared/config.py create mode 100644 app/shared/paths.py create mode 100644 app/shared/utils.py diff --git a/app/api/perception/vision/face_recog.py b/app/api/perception/vision/face_recog.py new file mode 100644 index 0000000..59421ab --- /dev/null +++ b/app/api/perception/vision/face_recog.py @@ -0,0 +1,32 @@ +from fastapi import APIRouter +import numpy as np +import tempfile +import os +import cv2 +from app.shared.paths import ( + get_user_dirs, +) +from app.shared.utils import ( + load_known_encodings, + clear_user_data, + list_known_faces, + cosine_similarity, +) +from app.services.face_utils import ( + delete_known_face, + save_new_face, + detect_faces, + match_face, + crop_face, +) + +# Endpoint API Routes +router = APIRouter() +@router.post("/add_face/{user_id}") +async def add_face(user_id: str, file: bytes): + ... + +@router.post("/face_recognition/{user_id}") +async def face_recognition(user_id: str, file: bytes): + """Recognizes faces in the uploaded image and returns matched names.""" + ... diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..d54a38b --- /dev/null +++ b/app/main.py @@ -0,0 +1,7 @@ +from fastapi import FastAPI +import os + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + + +# app = FastAPI() diff --git a/app/services/face_utils.py b/app/services/face_utils.py new file mode 100644 index 0000000..a553772 --- /dev/null +++ b/app/services/face_utils.py @@ -0,0 +1,83 @@ +import insightface +import numpy as np +import cv2 +from app.shared.paths import get_user_dirs +from ..shared.config import ( + MODEL_NAME, + MODEL_PROVIDERS, + FACE_MATCH_THRESHOLD +) + +from ..shared.utils import ( + cosine_similarity, +) + +# Global model instance +model = insightface.app.FaceAnalysis(name=MODEL_NAME, providers=MODEL_PROVIDERS) +model.prepare(ctx_id=0) + +def detect_faces(image: np.ndarray) -> list[dict]: + """Returns list of (embedding, bbox, landmarks) for all detected faces.""" + faces = model.get(image) + results = [] + for face in faces: + results.append({ + "embedding": face.embedding, # np.ndarray (512,) + "bbox": face.bbox.tolist(), # [x1, y1, x2, y2] + "landmarks": face.landmark_2d_106.tolist(), # [[x, y], ..., [x, y]] + }) + return results + +def match_face( + embedding: np.ndarray, + known_encodings: dict[str, np.ndarray], + threshold: float = FACE_MATCH_THRESHOLD, + return_score: bool = False +) -> tuple[bool, str, float | None]: + """Matches the given embedding against known encodings.""" + + best_score = -1 + best_match = None + + for name, known_embedding in known_encodings.items(): + score = cosine_similarity(embedding, known_embedding) + if score > best_score: + best_score = score + best_match = name + + if best_score > (1 - threshold): + return True, best_match, best_score if return_score else None + return False, None, best_score if return_score else None + +def crop_face(image: np.ndarray, bbox: list[int], margin: int = 10) -> np.ndarray: + x1, y1, x2, y2 = map(int, bbox) + h, w = image.shape[:2] + x1 = max(x1 - margin, 0) + y1 = max(y1 - margin, 0) + x2 = min(x2 + margin, w) + y2 = min(y2 + margin, h) + return image[y1:y2, x1:x2] + + +def save_new_face(name: str, image: np.ndarray, embedding: np.ndarray, user_id: str) -> bool: + """Saves the embedding and image of a known person.""" + try: + ENCODING_DIR, FACES_DIR = get_user_dirs(user_id) + np.save(ENCODING_DIR / f"{name}.npy", embedding) + cv2.imwrite(str(FACES_DIR / f"{name}.jpg"), image) + return True + except Exception as e: + print(f"Error saving new face: {e}") + return False + +def delete_known_face(name: str, user_id: str) -> bool: + """Deletes face image and encoding for a known person.""" + ENCODING_DIR, FACES_DIR = get_user_dirs(user_id) + try: + (ENCODING_DIR / f"{name}.npy").unlink(missing_ok=True) + (FACES_DIR / f"{name}.jpg").unlink(missing_ok=True) + return True + except Exception as e: + print(f"Failed to delete face: {e}") + return False + diff --git a/app/services/stt_utils.py b/app/services/stt_utils.py new file mode 100644 index 0000000..475a172 --- /dev/null +++ b/app/services/stt_utils.py @@ -0,0 +1,11 @@ +""" +stt_utils.py + +Handles Speech-to-Text functionality for the Blind Assist Tool. +Supports both Google Speech Recognition (online) and Vosk (offline) engines with fallback. + +Usage: +- Import the stt() function and call stt("your message") +- Engine can be set in config.py using TTS_ENGINE = "gTTS" or "pyttsx3" + +""" \ No newline at end of file diff --git a/tts_utils.py b/app/services/tts_utils.py similarity index 100% rename from tts_utils.py rename to app/services/tts_utils.py diff --git a/app/shared/config.py b/app/shared/config.py new file mode 100644 index 0000000..05e19bf --- /dev/null +++ b/app/shared/config.py @@ -0,0 +1,13 @@ +# app/shared/config.py +""" +This module contains configuration variables and methods for the VisionMate application. +""" + +# User Attributes +USER_ID = "dummy_user" # Default user ID for testing purposes + +# Face Recognition Configuration +FACE_MATCH_THRESHOLD = 0.6 +EMBEDDING_DIM = 512 +MODEL_NAME = "buffalo_l" +MODEL_PROVIDERS = ['CPUExecutionProvider'] diff --git a/app/shared/paths.py b/app/shared/paths.py new file mode 100644 index 0000000..7bec703 --- /dev/null +++ b/app/shared/paths.py @@ -0,0 +1,19 @@ +# app/shared/paths.py +""" +This module defines paths and utility functions for managing user directories in the VisionMate application. +""" + +from pathlib import Path +from app.main import BASE_DIR + +DATA_DIR = BASE_DIR / "data" +USERS_DIR = DATA_DIR / "users" + + +def get_user_dirs(user_id: str): + user_dir = USERS_DIR / user_id + encodings_dir = user_dir / "encodings" + faces_dir = user_dir / "known_faces" + encodings_dir.mkdir(parents=True, exist_ok=True) + faces_dir.mkdir(parents=True, exist_ok=True) + return encodings_dir, faces_dir diff --git a/app/shared/utils.py b/app/shared/utils.py new file mode 100644 index 0000000..47cf882 --- /dev/null +++ b/app/shared/utils.py @@ -0,0 +1,40 @@ +""" +This file contains utility functions for the VisionMate application. Common utility methods are defined here. +""" +import numpy as np +from app.shared.paths import get_user_dirs +from pathlib import Path + +def clear_user_data(user_id: str) -> bool: + """Deletes all known faces and encodings for a user.""" + try: + ENCODING_DIR, FACES_DIR = get_user_dirs(user_id) + for file in ENCODING_DIR.glob("*"): + file.unlink() + for file in FACES_DIR.glob("*"): + file.unlink() + return True + except Exception as e: + print(f"Error clearing user data: {e}") + return False + + +def list_known_faces(user_id: str) -> list[str]: + """Returns list of all known face names for a user.""" + ENCODING_DIR, _ = get_user_dirs(user_id) + return [f.stem for f in ENCODING_DIR.glob("*.npy")] + + +def load_known_encodings(user_id: str) -> dict: + """Returns dict of {name: embedding (np.ndarray)}.""" + known_encodings = {} + encodings_dir, _ = get_user_dirs(user_id) + for file in encodings_dir.glob("*.npy"): + name = file.stem + embedding = np.load(file) + known_encodings[name] = embedding + return known_encodings + +def cosine_similarity(a, b): + return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) + diff --git a/main.py b/main.py index efb2409..acd530d 100644 --- a/main.py +++ b/main.py @@ -8,7 +8,7 @@ import socket import google.generativeai as genai -from tts_utils import speak +from app.services.tts_utils import speak from config import TTS_ENGINE, IP_WEBCAM_URL # Load Gemini API key from .env From d006b293329951c9fa3233c41f711cfd68fa3be5 Mon Sep 17 00:00:00 2001 From: Zehen-249 <1hasanmehendi123@gmail.com> Date: Mon, 4 Aug 2025 17:09:59 +0530 Subject: [PATCH 08/25] Update requirements.txt file --- requirements.txt | Bin 109 -> 4836 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6d7212452165cc0e5f5adf42fe4a84eef8016fb2..df218856613fe05beba83c4bbb096ec3206938d3 100644 GIT binary patch literal 4836 zcmZ{oOHX4*5QTdkDL=&#HXdLWvxu_INKuFsWre^t#sgeC_Vt+I$0s>oom=jPafHm{ zc6B{YoqAmU{pYsam0fu%qp~UA$|rqI%1`B7pR@8~`JvqE?5^y~b6J$G^!mFmtFqSb zyQB1(q^}0)PABU@Zc*ma+e`08w=IwCWuv{*Df+NH)$_6JR@*z>-b>>~cDK^72)VH& zF7!DMn=_rw%7f0ZwvpUA>}|s`dXfL2&*YtaFUhsyvu8-OQVVG!)_Z-7%b7GFfu9q3 z06sIFrv!G!5#4w=dpP>t%QukO3P~_sl~;MZ4b7mhdZCDRl9)&AeMlHjXZb$P;ooM+hxLzx3AS)A>+lo4k`+8j zmO8WeVqV{eAAQ7MIRK6yLSst7CNkB%@rNKz|(Uxqe( zb1i+<-}v3>WUrr`x0=YCt-RF*4kID%Tyq1j%uwU;-nws)>C6N7VVi3^b->|Tqwlrs z<95nUgMZG^X~~gt4$hmfbSDopI{ZC_(5#KInNW)UJCtR$zkXAoctz zRBt4+*6;J99Ga$q{zMagZ-*%^Jv3dpeR$W=Na;>Q(C6>-<_b>3yjWDKie8 zu0tj?b$@r1a_)`5vwUJEJjE&ZD{G(ibfoj|r+Uo;46v;>1BoE4f)Ouov>V+{&wHUk zPkS6B$bhT83-%@gW_89!-n-!j-j0=tw3ugG-6!X8v~Cg;p_94y=Fo{dUk9wSQ-UV> z9fvfSTn)MAPOnT;6R?;HOYCcJuoP3dcK5cj;Vd(s{*Rtz=$H&P=?X|Ng_4=Byo}MD zXM$oI1e`bDTq$cX@i3g`xlyMx!whC3`w25RC+B}s!M!^*sPt3%GS9bKO2A0^}7058C%Q}mn@f2*OM(vjBkd>?+< zBGP2bmGYZ({j774aIfdwJaP46Z5BE4Ug|D@#6(w&2i%$D(ji6Ai!UeplJhF~Nis-I&N>{oFzrcwuTcf|0AMml}gY#-5>w;bY zcNRj6INdYw3ZFoYX~0xYZnWD6y^p({>MeQe>P-Zzo#)6GHXNUKL@YQrt$xsX5pw9X zFCULN>D8J2oPFLkjWtmDOIiP1evNZ)afu0x{#zdK9@Aof9{SBdCTg8JuKlbD^5MON z=QUqD-B<}{clSD9lfmBSoR_z<)D(I40$4i(RKG*e9O2O!~ka-_~GdCkc% z5gW{PIifNnt>aI5!M4U* z@_yJ`%>1-+&`s*J?vvBN#aJG6n>Vudoxjc^Dr%!IP(Z747GokVH%=(f0mSx4Oq1T1N62yD43X Date: Mon, 4 Aug 2025 20:44:10 +0530 Subject: [PATCH 09/25] Integrate LangChain with Gemini for image understanding --- __pycache__/config.cpython-310.pyc | Bin 0 -> 225 bytes __pycache__/tts_utils.cpython-310.pyc | Bin 0 -> 1610 bytes main.py | 30 +++++++++++++++++++++----- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 __pycache__/config.cpython-310.pyc create mode 100644 __pycache__/tts_utils.cpython-310.pyc diff --git a/__pycache__/config.cpython-310.pyc b/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7da09f9e38944b1bb9f97f9bf88ab98bf48196a GIT binary patch literal 225 zcmd1j<>g`kf|i{VGO8FE7#@Q-$N(tD-~hzMJU}9aA&Mb|F^VyTDVRZ%`4&rhNJwy% zLPkkRft9|#p{0?Yp_zrAktL9_w6ZX;Fwif{Oi9i6(`35E1ymXD>gVq1=X#6RGax?P z)ydh>H$F7TXC*@s3(#mV@ykj-v^ce>SU)=>F)uM&-zBv;yClCrzcjBTvm_@qMIkLe wCndE=KPPO2Tq$;BWuS=cyO0Ol<@CjbBd literal 0 HcmV?d00001 diff --git a/__pycache__/tts_utils.cpython-310.pyc b/__pycache__/tts_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c9114e13eb067f968534b7a5c20b9bca60ba2b4 GIT binary patch literal 1610 zcmaJ>L2uhO6ecNIRutO}+OBK690(tVXh3Wf-7dvCtlN^UhZzHswy1)_P)yoUEl~nV zFR|bh1KP_56x+QB;2if8_E&V>X+L2*bbF+oEa{;V`1JT5-+Q0UOVjvib5W|e5I3p3kMt4#ta^UNxZdQwG)>ccs%!|CGzaG`?IzRF` zVcwX?4ercWPEi!FI`dzlXqBz70KN_8?4WQp{um<^Xs!AaousN$OoQONSg@2Uy33FB zrp`Ba3eE=ybT|pt?RxU>1RrD}{fMJ}b`|)7h34%u|9`Sp@CViNhjJBXE zcs$++&*9jV1BjsuPkWkAB+a-ovF#9ow`_Jghy~r}RB=rcK?k`QCL{P?I#G!jQ9#+> z>V5mLw?*&MwgKIy@Qdvw*me;71x-OAu7dxU_F(FoweVdj(s-)!iC|TI88m>sJ%3!# zO#8ovp>BdlLrXP&gBY2iH|WHDi80d9WN6xFWkZv>Gef7wM&|A*!srQ5Vh6cM*QTFh zbPS%d1v%Uq$PKNM&>Is=Xqdjt{QETlR-@vy>u`V{vD*A9YQ7ZK82wh^X6I11$;j*@m&Las|Fuy zoH+LXS~K)Mqy~4`?3DpY1Llfw5t7Q)K-bDm zV=>w;-A-2A1*6A!$~CV%H5m?*qq4bY>9`CpZ+GZ6Fvrv}jH5a~BWEYPQq>BX2rbR2 zth@z9D@VoCDv%TLK(HrqqN|myqX93>xmbYlHP4D+lJe?mFU~mIg=sEhIo&okSH(Yq z6yTAD5EaQ)69U~Zi;zi*iwy0UJTU>-SeU@Avv#qUVo0^2|LyN?u?syjZ2MLh0) z!_`>lMRy`}qEpV`bf%2U?&CxOuBvpgEUl>`p%c zn!wElG_El`Bk$0dydX;&gJx(Pl3sah&os<7>m4qHo+U};CL+L9~xn{av^RT?FNWV7-|g!!TzNkvEHy*)%$&x5BmMeTihU)9=3Aij$o553v6$t yNh7Ztv2KK|Yxd5jx=`H0FbFFD^DJkRlz(9^4rTDTsL}9k8+-udJ1|J&gZ}_X!;ZfI literal 0 HcmV?d00001 diff --git a/main.py b/main.py index efb2409..58d7acc 100644 --- a/main.py +++ b/main.py @@ -2,11 +2,16 @@ import numpy as np import threading import os +import base64 import speech_recognition as sr from PIL import Image from dotenv import load_dotenv import socket import google.generativeai as genai +from langchain_google_genai import ChatGoogleGenerativeAI +from langchain_core.prompts import PromptTemplate +from langchain_core.messages import HumanMessage + from tts_utils import speak from config import TTS_ENGINE, IP_WEBCAM_URL @@ -14,8 +19,16 @@ # Load Gemini API key from .env load_dotenv() api_key = os.getenv("API_KEY") + genai.configure(api_key=api_key) model = genai.GenerativeModel(model_name="gemini-1.5-flash") +llm = ChatGoogleGenerativeAI( + model="gemini-2.0-flash", + temperature=0, + max_tokens=100, + timeout=None, + max_retries=2, +) def is_connected(): try: @@ -33,12 +46,19 @@ def is_connected(): def process_frame(frame): rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_image = Image.fromarray(rgb_frame) + _, buffer = cv2.imencode('.png', frame) + encoded_image = base64.b64encode(buffer).decode('utf-8') + try: - response = model.generate_content([ - "Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights.", - pil_image - ]) - return response.text.strip() + message = HumanMessage( + content=[ + {"type": "text", "text":"Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights."}, + {"type": "image_url", "image_url": f"data:image/png;base64,{encoded_image}"}, + ] + ) + response = llm.invoke([message]) + + return response.content except Exception as e: print(f"[Gemini Error] {e}") return "Unable to analyze surroundings due to internet issue." From 26a8dcd5b1a140ad63b93b1d42192ceb56d7d9f5 Mon Sep 17 00:00:00 2001 From: khanak khandelwal Date: Tue, 5 Aug 2025 00:40:40 +0530 Subject: [PATCH 10/25] Integrate LangChain with Gemini for image understanding --- main.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index 58d7acc..f818094 100644 --- a/main.py +++ b/main.py @@ -25,7 +25,6 @@ llm = ChatGoogleGenerativeAI( model="gemini-2.0-flash", temperature=0, - max_tokens=100, timeout=None, max_retries=2, ) @@ -44,25 +43,49 @@ def is_connected(): scan_triggered = False def process_frame(frame): + # Convert the OpenCV BGR image to RGB format (PIL expects RGB) rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + + # Create a PIL image (not directly used but can be useful for debugging or saving) pil_image = Image.fromarray(rgb_frame) + + # Encode the frame as PNG image (in memory) _, buffer = cv2.imencode('.png', frame) + + # Convert the PNG image bytes to a base64-encoded string (required by Gemini) encoded_image = base64.b64encode(buffer).decode('utf-8') try: + # Create a HumanMessage for the Gemini model, combining text and image message = HumanMessage( - content=[ - {"type": "text", "text":"Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights."}, - {"type": "image_url", "image_url": f"data:image/png;base64,{encoded_image}"}, - ] - ) + content=[ + # Text prompt asking for a brief visual description for the blind + { + "type": "text", + "text": ( + "Provide a short, clear, and concise description of this scene " + "(1–2 sentences) for a blind person. Focus only on key visual elements " + "or signs like STOP signs, vehicles, people, or traffic lights." + ) + }, + # Embed the base64 image data as an image input + { + "type": "image_url", + "image_url": f"data:image/png;base64,{encoded_image}" + }, + ] + ) + + # Send the prompt to Gemini model using LangChain wrapper and return the description response = llm.invoke([message]) - return response.content + except Exception as e: + # Print error for debugging and return a fallback message print(f"[Gemini Error] {e}") return "Unable to analyze surroundings due to internet issue." + def listen_for_scan(): global scan_triggered recognizer = sr.Recognizer() From 4784a2407b4b4748201bfe743530ad680f4b8300 Mon Sep 17 00:00:00 2001 From: vibhuti Date: Tue, 5 Aug 2025 08:32:35 +0530 Subject: [PATCH 11/25] feat: Implement speech-to-text module --- stt_module.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 stt_module.py diff --git a/stt_module.py b/stt_module.py new file mode 100644 index 0000000..1e00442 --- /dev/null +++ b/stt_module.py @@ -0,0 +1,30 @@ +import speech_recognition as sr + +def listen_for_command(): + """Listens for a single command from the user and returns it as text.""" + r = sr.Recognizer() + with sr.Microphone() as source: + print("Listening for a command...") + # Adjust for ambient noise to improve accuracy + r.adjust_for_ambient_noise(source) + try: + # Listen for audio input from the user + audio = r.listen(source, timeout=5, phrase_time_limit=5) + print("Recognizing...") + # Use Google's speech recognition to convert audio to text + command = r.recognize_google(audio) + print(f"You said: {command}") + return command + except sr.WaitTimeoutError: + print("No command heard. Please try again.") + return None + except sr.UnknownValueError: + print("Sorry, I could not understand the audio.") + return None + except sr.RequestError as e: + print(f"Could not request results from Google Speech Recognition service; {e}") + return None + +# This part allows you to test the file directly +if __name__ == '__main__': + listen_for_command() From 264672e10546d1ee775e53c92a3f675b6f622398 Mon Sep 17 00:00:00 2001 From: Anushka Chanda Date: Tue, 5 Aug 2025 08:54:36 +0530 Subject: [PATCH 12/25] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..5b1cbf6 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# 📜 Code of Conduct + +## 👋 Welcome to VisionMate + +**VisionMate** is an open-source initiative committed to empowering visually impaired individuals through inclusive, innovative assistive technology. We believe in creating a **respectful, collaborative, and safe environment** for everyone involved in this mission—regardless of background, identity, or skill level. + +This Code of Conduct outlines the behavior expected of all contributors and participants in VisionMate spaces. + +--- + +## 💡 Our Values + +We expect all members of the VisionMate community to: + +- 🤝 Treat others with **respect, kindness, and empathy** +- 🌍 Embrace **diversity and inclusion** +- 📣 Communicate **clearly and constructively** +- 🧠 Encourage **learning, sharing, and collaboration** +- 🎯 Focus on **problem-solving** and positive contributions + +--- + +## 🚫 Unacceptable Behavior + +To ensure a supportive space, the following will **not** be tolerated: + +- ❌ Harassment, discrimination, or hate speech +- ❌ Personal attacks, threats, or derogatory comments +- ❌ Sexualized or inappropriate content or language +- ❌ Spamming, trolling, or sustained disruption +- ❌ Sharing private information without explicit consent + +--- + +## 🙋 Reporting Issues + +If you witness or experience any behavior that violates this Code of Conduct: +**Report it immediately.** + +All reports will be handled **discreetly and respectfully** by the project maintainers. + +--- + +## ⚖️ Enforcement + +Violations of this Code of Conduct may result in: + +| Consequence | Description | +|-------------------|---------------------------------------------------------------------------| +| 🟢 Warning | A private warning and clarification of the issue | +| 🟡 Temporary Ban | Temporary removal from participation in discussions or contributions | +| 🔴 Permanent Ban | Full removal from the project and blocking of further contributions | + +--- + +## 👥 Scope + +This Code of Conduct applies to: + +- All VisionMate GitHub repositories (issues, pull requests, discussions) +- Community communication platforms (e.g., chats, forums) +- Public or private conversations related to the project +- Any events, meetings, or collaborative spaces + +--- + +## 📝 Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html), version 2.1. + +--- + +Thank you for helping make **VisionMate** a safe, accessible, and inclusive space for everyone. 💙 +Let’s build a world where technology supports **everyone’s independence.** From 6ebd5c482ed2a942299c9bb1fa1095d93a9bf968 Mon Sep 17 00:00:00 2001 From: Zehen-249 <1hasanmehendi123@gmail.com> Date: Tue, 5 Aug 2025 14:39:01 +0530 Subject: [PATCH 13/25] Add load_model feature for face_detection model --- .gitignore | 69 ++++++++++++++++++++++++++++++++++++++ app/__init__.py | 0 app/main.py | 5 ++- app/services/face_utils.py | 13 +++---- app/shared/config.py | 2 -- app/shared/load_model.py | 55 ++++++++++++++++++++++++++++++ app/shared/paths.py | 2 +- 7 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 .gitignore create mode 100644 app/__init__.py create mode 100644 app/shared/load_model.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8de033c --- /dev/null +++ b/.gitignore @@ -0,0 +1,69 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Virtual environment +.venv/ +venv/ +env/ +ENV/ +visionmate/ + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Model downloads & cache +app/models/ +*.onnx +*.pth +*.pb +*.tflite + +# Temporary files +*.log +*.tmp +*.bak +*.swp +*.DS_Store +Thumbs.db + +# Jupyter/IPython +.ipynb_checkpoints + +# Environment variables +.env +.env.* + +# VSCode/IDE +.vscode/ +.idea/ + +# macOS +.DS_Store + +# Windows +*.lnk +desktop.ini diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/main.py b/app/main.py index d54a38b..7c14075 100644 --- a/app/main.py +++ b/app/main.py @@ -1,7 +1,6 @@ from fastapi import FastAPI import os - -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) - +from pathlib import Path +from app.shared.load_model import load_face_model # app = FastAPI() diff --git a/app/services/face_utils.py b/app/services/face_utils.py index a553772..30b5bf2 100644 --- a/app/services/face_utils.py +++ b/app/services/face_utils.py @@ -2,19 +2,14 @@ import numpy as np import cv2 from app.shared.paths import get_user_dirs -from ..shared.config import ( - MODEL_NAME, - MODEL_PROVIDERS, - FACE_MATCH_THRESHOLD -) - -from ..shared.utils import ( +from app.shared.load_model import load_face_model +from app.shared.utils import ( cosine_similarity, ) # Global model instance -model = insightface.app.FaceAnalysis(name=MODEL_NAME, providers=MODEL_PROVIDERS) -model.prepare(ctx_id=0) +model = load_face_model() +FACE_MATCH_THRESHOLD = 0.6 def detect_faces(image: np.ndarray) -> list[dict]: """Returns list of (embedding, bbox, landmarks) for all detected faces.""" diff --git a/app/shared/config.py b/app/shared/config.py index 05e19bf..37f302f 100644 --- a/app/shared/config.py +++ b/app/shared/config.py @@ -9,5 +9,3 @@ # Face Recognition Configuration FACE_MATCH_THRESHOLD = 0.6 EMBEDDING_DIM = 512 -MODEL_NAME = "buffalo_l" -MODEL_PROVIDERS = ['CPUExecutionProvider'] diff --git a/app/shared/load_model.py b/app/shared/load_model.py new file mode 100644 index 0000000..799e71d --- /dev/null +++ b/app/shared/load_model.py @@ -0,0 +1,55 @@ +import os +import zipfile +import requests +from pathlib import Path +from insightface.app import FaceAnalysis +from app.shared.paths import BASE_DIR + +# Model config +FACE_MODEL_NAME = "buffalo_l" +FACE_MODEL_PROVIDERS = ["CPUExecutionProvider"] +FACE_MODEL_URL = f"https://github.com/deepinsight/insightface/releases/download/v0.7/{FACE_MODEL_NAME}.zip" +FACE_MODEL_DIR = BASE_DIR / "models" / FACE_MODEL_NAME +FACE_ZIP_PATH = FACE_MODEL_DIR.parent / f"{FACE_MODEL_NAME}.zip" +FACE_REQUIRED_FILES = [ + "1k3d68.onnx", + "2d106det.onnx", + "det_10g.onnx", + "genderage.onnx", + "w600k_r50.onnx" +] + + +def _ensure_model_exists(model_path, required_files, model_url, zip_path) -> Path: + """Ensure the buffalo_l model is downloaded and extracted.""" + if model_path.exists() and all((model_path / f).exists() for f in required_files): + return model_path + + model_path.mkdir(parents=True, exist_ok=True) + + print("Downloading buffalo_l model...") + response = requests.get(model_url, stream=True) + with open(zip_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + + print("Extracting model...") + with zipfile.ZipFile(zip_path, "r") as zip_ref: + zip_ref.extractall(model_path) + + zip_path.unlink() + print("Model is ready.") + return model_path + + +def load_face_model() -> FaceAnalysis: + """Load the buffalo_l model using InsightFace.""" + model_dir = _ensure_model_exists( + model_path=FACE_MODEL_DIR, + required_files=FACE_REQUIRED_FILES, + model_url=FACE_MODEL_URL, + zip_path=FACE_ZIP_PATH + ) + model = FaceAnalysis(name=str(model_dir), providers=FACE_MODEL_PROVIDERS) + model.prepare(ctx_id=0) + return model diff --git a/app/shared/paths.py b/app/shared/paths.py index 7bec703..87a9c95 100644 --- a/app/shared/paths.py +++ b/app/shared/paths.py @@ -4,8 +4,8 @@ """ from pathlib import Path -from app.main import BASE_DIR +BASE_DIR = Path(__file__).resolve().parent.parent DATA_DIR = BASE_DIR / "data" USERS_DIR = DATA_DIR / "users" From c218c7ef41301e96e66fc5d2a5fec8def92db138 Mon Sep 17 00:00:00 2001 From: khanak khandelwal Date: Tue, 5 Aug 2025 14:54:37 +0530 Subject: [PATCH 14/25] added langchain --- main.py | 50 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index efb2409..f9df4a4 100644 --- a/main.py +++ b/main.py @@ -2,11 +2,17 @@ import numpy as np import threading import os +import base64 + import speech_recognition as sr from PIL import Image from dotenv import load_dotenv import socket import google.generativeai as genai +from langchain_google_genai import ChatGoogleGenerativeAI +from langchain_core.prompts import PromptTemplate +from langchain_core.messages import HumanMessage + from tts_utils import speak from config import TTS_ENGINE, IP_WEBCAM_URL @@ -15,8 +21,12 @@ load_dotenv() api_key = os.getenv("API_KEY") genai.configure(api_key=api_key) -model = genai.GenerativeModel(model_name="gemini-1.5-flash") - +llm = ChatGoogleGenerativeAI( + model="gemini-2.0-flash", + temperature=0, + timeout=None, + max_retries=2, +) def is_connected(): try: socket.create_connection(("www.google.com", 80), timeout=2) @@ -31,18 +41,44 @@ def is_connected(): scan_triggered = False def process_frame(frame): + rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + # Encode the frame as PNG image (in memory) + _, buffer = cv2.imencode('.png', frame) + + # Convert the PNG image bytes to a base64-encoded string (required by Gemini) + encoded_image = base64.b64encode(buffer).decode('utf-8') pil_image = Image.fromarray(rgb_frame) try: - response = model.generate_content([ - "Provide a short, clear, and concise description of this scene (1–2 sentences) for a blind person. Focus only on key visual elements or signs like STOP signs, vehicles, people, or traffic lights.", - pil_image - ]) - return response.text.strip() + # Create a HumanMessage for the Gemini model, combining text and image + message = HumanMessage( + content=[ + # Text prompt asking for a brief visual description for the blind + { + "type": "text", + "text": ( + "Provide a short, clear, and concise description of this scene " + "(1–2 sentences) for a blind person. Focus only on key visual elements " + "or signs like STOP signs, vehicles, people, or traffic lights." + ) + }, + # Embed the base64 image data as an image input + { + "type": "image_url", + "image_url": f"data:image/png;base64,{encoded_image}" + }, + ] + ) + # Send the prompt to Gemini model using LangChain wrapper and return the description + response = llm.invoke([message]) + return response.content + except Exception as e: + # Print error for debugging and return a fallback message print(f"[Gemini Error] {e}") return "Unable to analyze surroundings due to internet issue." + def listen_for_scan(): global scan_triggered recognizer = sr.Recognizer() From df5924799baa888f9d468289d6bfd76b17492050 Mon Sep 17 00:00:00 2001 From: khanak khandelwal Date: Tue, 5 Aug 2025 14:56:50 +0530 Subject: [PATCH 15/25] added langchain --- main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.py b/main.py index f9df4a4..dcb050f 100644 --- a/main.py +++ b/main.py @@ -20,6 +20,8 @@ # Load Gemini API key from .env load_dotenv() api_key = os.getenv("API_KEY") +os.environ["GOOGLE_API_KEY"] = "your api key" + genai.configure(api_key=api_key) llm = ChatGoogleGenerativeAI( model="gemini-2.0-flash", From 8f8a333276fffe97c3cf110421eda19b6022d4a0 Mon Sep 17 00:00:00 2001 From: Anushka Chanda Date: Tue, 5 Aug 2025 20:18:03 +0530 Subject: [PATCH 16/25] Updated CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 5b1cbf6..b2c9e15 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -20,15 +20,26 @@ We expect all members of the VisionMate community to: --- +## 🗣️ Feedback Process + +We welcome input from all contributors to help improve our community, processes, and codebase. + +- 🛠 Share suggestions through GitHub discussions, issues, or pull requests +- 🧩 Be open to differing viewpoints and respectful debate +- ✅ Encourage reviews that are kind, specific, and constructive +- 📝 Feedback will be considered carefully by maintainers and incorporated when appropriate + +--- + ## 🚫 Unacceptable Behavior To ensure a supportive space, the following will **not** be tolerated: -- ❌ Harassment, discrimination, or hate speech -- ❌ Personal attacks, threats, or derogatory comments -- ❌ Sexualized or inappropriate content or language -- ❌ Spamming, trolling, or sustained disruption -- ❌ Sharing private information without explicit consent +- ❌ Harassment, discrimination, or hate speech +- ❌ Personal attacks, threats, or derogatory comments +- ❌ Sexualized or inappropriate content or language +- ❌ Spamming, trolling, or sustained disruption +- ❌ Sharing private information without explicit consent --- @@ -37,7 +48,7 @@ To ensure a supportive space, the following will **not** be tolerated: If you witness or experience any behavior that violates this Code of Conduct: **Report it immediately.** -All reports will be handled **discreetly and respectfully** by the project maintainers. +All reports will be handled **discreetly and respectfully** by the project maintainers. --- @@ -51,24 +62,27 @@ Violations of this Code of Conduct may result in: | 🟡 Temporary Ban | Temporary removal from participation in discussions or contributions | | 🔴 Permanent Ban | Full removal from the project and blocking of further contributions | +### 🧾 Accountability + +- Repeated or severe violations may lead to stricter consequences, including permanent bans +- Maintainers reserve the right to evaluate each case on a situational basis +- Appeals may be discussed with the core maintainer team if needed + --- ## 👥 Scope This Code of Conduct applies to: -- All VisionMate GitHub repositories (issues, pull requests, discussions) -- Community communication platforms (e.g., chats, forums) -- Public or private conversations related to the project -- Any events, meetings, or collaborative spaces +- All VisionMate GitHub repositories (issues, pull requests, discussions) +- Community communication platforms (e.g., chats, forums) +- Public or private conversations related to the project +- Any events, meetings, or collaborative spaces --- ## 📝 Attribution This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html), version 2.1. - ---- - Thank you for helping make **VisionMate** a safe, accessible, and inclusive space for everyone. 💙 Let’s build a world where technology supports **everyone’s independence.** From 6435903aca3a8b136c09330f24b9ceb2fb67b132 Mon Sep 17 00:00:00 2001 From: Jaideep Date: Tue, 5 Aug 2025 22:13:54 +0530 Subject: [PATCH 17/25] Create Updated Readme --- Updated Readme | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Updated Readme diff --git a/Updated Readme b/Updated Readme new file mode 100644 index 0000000..0407c72 --- /dev/null +++ b/Updated Readme @@ -0,0 +1,58 @@ +👁️ VisionMate +VisionMate is an assistive technology solution designed to empower visually impaired individuals by offering real-time, smart guidance for safer and more independent navigation. + +🧠 Project Overview +VisionMate leverages a combination of computer vision, text recognition, and speech processing to help users: + +🔍 Identify objects and surroundings +📖 Read printed or handwritten text aloud +🎙️ Interact using voice commands +🦯 Receive real-time audio feedback on obstacles +💡 Access a user-friendly interface designed for accessibility +⚠️ This project is currently in its early development and ideation phase. The repository will grow to include: + +Prototypes +Research notes +Starter code +API integration plans +✨ Planned Features +✅ Object detection using computer vision (OpenCV / Google Vision API) +✅ Text-to-speech for printed and handwritten content +✅ Speech-based user controls +✅ Real-time environment awareness (obstacle detection) +✅ Modular and scalable architecture for future feature integration +🧰 Tech Stack +Layer Technology +Backend Python, Flask / Django (TBD) +Computer Vision OpenCV, Google Cloud Vision API (future) +Frontend / UI React.js or Flutter (TBD) +Data Storage MySQL +Accessibility Text-to-Speech / Speech Recognition APIs +🚀 Getting Started +⚠️ Work in Progress +Only starter files and minimal prototypes are available in this stage. + +📥 Clone the Repository +git clone https://github.com/kaushav07/VisionMate.git +cd VisionMate +📦 Install Dependencies +Make sure you have Python 3.7+ installed. Then run: + +bash +Copy +Edit +pip install -r requirements.txt +🗂️ Folder Structure (to be expanded) +css +Copy +Edit +VisionMate/ +├── prototypes/ +│ ├── object_detection/ +│ └── text_reader/ +├── research_notes/ +├── app/ +│ ├── main.py +│ └── utils.py +├── requirements.txt +└── README.md From b9f045bb7d35ab967229bf6150131c2b30c19a5e Mon Sep 17 00:00:00 2001 From: "kaushav.jr" <142465852+kaushav07@users.noreply.github.com> Date: Sun, 10 Aug 2025 16:34:21 +0530 Subject: [PATCH 18/25] Revert "Feature: Add face recognition and FastAPI integration #24" (#43) --- .gitignore | 69 ------------------- app/__init__.py | 0 app/api/perception/vision/face_recog.py | 32 --------- app/main.py | 6 -- app/services/face_utils.py | 78 ---------------------- app/services/stt_utils.py | 11 --- app/shared/config.py | 11 --- app/shared/load_model.py | 55 --------------- app/shared/paths.py | 19 ------ app/shared/utils.py | 40 ----------- main.py | 2 +- requirements.txt | Bin 4836 -> 109 bytes app/services/tts_utils.py => tts_utils.py | 0 13 files changed, 1 insertion(+), 322 deletions(-) delete mode 100644 .gitignore delete mode 100644 app/__init__.py delete mode 100644 app/api/perception/vision/face_recog.py delete mode 100644 app/main.py delete mode 100644 app/services/face_utils.py delete mode 100644 app/services/stt_utils.py delete mode 100644 app/shared/config.py delete mode 100644 app/shared/load_model.py delete mode 100644 app/shared/paths.py delete mode 100644 app/shared/utils.py rename app/services/tts_utils.py => tts_utils.py (100%) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8de033c..0000000 --- a/.gitignore +++ /dev/null @@ -1,69 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Virtual environment -.venv/ -venv/ -env/ -ENV/ -visionmate/ - -# PyInstaller -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Model downloads & cache -app/models/ -*.onnx -*.pth -*.pb -*.tflite - -# Temporary files -*.log -*.tmp -*.bak -*.swp -*.DS_Store -Thumbs.db - -# Jupyter/IPython -.ipynb_checkpoints - -# Environment variables -.env -.env.* - -# VSCode/IDE -.vscode/ -.idea/ - -# macOS -.DS_Store - -# Windows -*.lnk -desktop.ini diff --git a/app/__init__.py b/app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/api/perception/vision/face_recog.py b/app/api/perception/vision/face_recog.py deleted file mode 100644 index 59421ab..0000000 --- a/app/api/perception/vision/face_recog.py +++ /dev/null @@ -1,32 +0,0 @@ -from fastapi import APIRouter -import numpy as np -import tempfile -import os -import cv2 -from app.shared.paths import ( - get_user_dirs, -) -from app.shared.utils import ( - load_known_encodings, - clear_user_data, - list_known_faces, - cosine_similarity, -) -from app.services.face_utils import ( - delete_known_face, - save_new_face, - detect_faces, - match_face, - crop_face, -) - -# Endpoint API Routes -router = APIRouter() -@router.post("/add_face/{user_id}") -async def add_face(user_id: str, file: bytes): - ... - -@router.post("/face_recognition/{user_id}") -async def face_recognition(user_id: str, file: bytes): - """Recognizes faces in the uploaded image and returns matched names.""" - ... diff --git a/app/main.py b/app/main.py deleted file mode 100644 index 7c14075..0000000 --- a/app/main.py +++ /dev/null @@ -1,6 +0,0 @@ -from fastapi import FastAPI -import os -from pathlib import Path -from app.shared.load_model import load_face_model - -# app = FastAPI() diff --git a/app/services/face_utils.py b/app/services/face_utils.py deleted file mode 100644 index 30b5bf2..0000000 --- a/app/services/face_utils.py +++ /dev/null @@ -1,78 +0,0 @@ -import insightface -import numpy as np -import cv2 -from app.shared.paths import get_user_dirs -from app.shared.load_model import load_face_model -from app.shared.utils import ( - cosine_similarity, -) - -# Global model instance -model = load_face_model() -FACE_MATCH_THRESHOLD = 0.6 - -def detect_faces(image: np.ndarray) -> list[dict]: - """Returns list of (embedding, bbox, landmarks) for all detected faces.""" - faces = model.get(image) - results = [] - for face in faces: - results.append({ - "embedding": face.embedding, # np.ndarray (512,) - "bbox": face.bbox.tolist(), # [x1, y1, x2, y2] - "landmarks": face.landmark_2d_106.tolist(), # [[x, y], ..., [x, y]] - }) - return results - -def match_face( - embedding: np.ndarray, - known_encodings: dict[str, np.ndarray], - threshold: float = FACE_MATCH_THRESHOLD, - return_score: bool = False -) -> tuple[bool, str, float | None]: - """Matches the given embedding against known encodings.""" - - best_score = -1 - best_match = None - - for name, known_embedding in known_encodings.items(): - score = cosine_similarity(embedding, known_embedding) - if score > best_score: - best_score = score - best_match = name - - if best_score > (1 - threshold): - return True, best_match, best_score if return_score else None - return False, None, best_score if return_score else None - -def crop_face(image: np.ndarray, bbox: list[int], margin: int = 10) -> np.ndarray: - x1, y1, x2, y2 = map(int, bbox) - h, w = image.shape[:2] - x1 = max(x1 - margin, 0) - y1 = max(y1 - margin, 0) - x2 = min(x2 + margin, w) - y2 = min(y2 + margin, h) - return image[y1:y2, x1:x2] - - -def save_new_face(name: str, image: np.ndarray, embedding: np.ndarray, user_id: str) -> bool: - """Saves the embedding and image of a known person.""" - try: - ENCODING_DIR, FACES_DIR = get_user_dirs(user_id) - np.save(ENCODING_DIR / f"{name}.npy", embedding) - cv2.imwrite(str(FACES_DIR / f"{name}.jpg"), image) - return True - except Exception as e: - print(f"Error saving new face: {e}") - return False - -def delete_known_face(name: str, user_id: str) -> bool: - """Deletes face image and encoding for a known person.""" - ENCODING_DIR, FACES_DIR = get_user_dirs(user_id) - try: - (ENCODING_DIR / f"{name}.npy").unlink(missing_ok=True) - (FACES_DIR / f"{name}.jpg").unlink(missing_ok=True) - return True - except Exception as e: - print(f"Failed to delete face: {e}") - return False - diff --git a/app/services/stt_utils.py b/app/services/stt_utils.py deleted file mode 100644 index 475a172..0000000 --- a/app/services/stt_utils.py +++ /dev/null @@ -1,11 +0,0 @@ -""" -stt_utils.py - -Handles Speech-to-Text functionality for the Blind Assist Tool. -Supports both Google Speech Recognition (online) and Vosk (offline) engines with fallback. - -Usage: -- Import the stt() function and call stt("your message") -- Engine can be set in config.py using TTS_ENGINE = "gTTS" or "pyttsx3" - -""" \ No newline at end of file diff --git a/app/shared/config.py b/app/shared/config.py deleted file mode 100644 index 37f302f..0000000 --- a/app/shared/config.py +++ /dev/null @@ -1,11 +0,0 @@ -# app/shared/config.py -""" -This module contains configuration variables and methods for the VisionMate application. -""" - -# User Attributes -USER_ID = "dummy_user" # Default user ID for testing purposes - -# Face Recognition Configuration -FACE_MATCH_THRESHOLD = 0.6 -EMBEDDING_DIM = 512 diff --git a/app/shared/load_model.py b/app/shared/load_model.py deleted file mode 100644 index 799e71d..0000000 --- a/app/shared/load_model.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import zipfile -import requests -from pathlib import Path -from insightface.app import FaceAnalysis -from app.shared.paths import BASE_DIR - -# Model config -FACE_MODEL_NAME = "buffalo_l" -FACE_MODEL_PROVIDERS = ["CPUExecutionProvider"] -FACE_MODEL_URL = f"https://github.com/deepinsight/insightface/releases/download/v0.7/{FACE_MODEL_NAME}.zip" -FACE_MODEL_DIR = BASE_DIR / "models" / FACE_MODEL_NAME -FACE_ZIP_PATH = FACE_MODEL_DIR.parent / f"{FACE_MODEL_NAME}.zip" -FACE_REQUIRED_FILES = [ - "1k3d68.onnx", - "2d106det.onnx", - "det_10g.onnx", - "genderage.onnx", - "w600k_r50.onnx" -] - - -def _ensure_model_exists(model_path, required_files, model_url, zip_path) -> Path: - """Ensure the buffalo_l model is downloaded and extracted.""" - if model_path.exists() and all((model_path / f).exists() for f in required_files): - return model_path - - model_path.mkdir(parents=True, exist_ok=True) - - print("Downloading buffalo_l model...") - response = requests.get(model_url, stream=True) - with open(zip_path, "wb") as f: - for chunk in response.iter_content(chunk_size=8192): - f.write(chunk) - - print("Extracting model...") - with zipfile.ZipFile(zip_path, "r") as zip_ref: - zip_ref.extractall(model_path) - - zip_path.unlink() - print("Model is ready.") - return model_path - - -def load_face_model() -> FaceAnalysis: - """Load the buffalo_l model using InsightFace.""" - model_dir = _ensure_model_exists( - model_path=FACE_MODEL_DIR, - required_files=FACE_REQUIRED_FILES, - model_url=FACE_MODEL_URL, - zip_path=FACE_ZIP_PATH - ) - model = FaceAnalysis(name=str(model_dir), providers=FACE_MODEL_PROVIDERS) - model.prepare(ctx_id=0) - return model diff --git a/app/shared/paths.py b/app/shared/paths.py deleted file mode 100644 index 87a9c95..0000000 --- a/app/shared/paths.py +++ /dev/null @@ -1,19 +0,0 @@ -# app/shared/paths.py -""" -This module defines paths and utility functions for managing user directories in the VisionMate application. -""" - -from pathlib import Path - -BASE_DIR = Path(__file__).resolve().parent.parent -DATA_DIR = BASE_DIR / "data" -USERS_DIR = DATA_DIR / "users" - - -def get_user_dirs(user_id: str): - user_dir = USERS_DIR / user_id - encodings_dir = user_dir / "encodings" - faces_dir = user_dir / "known_faces" - encodings_dir.mkdir(parents=True, exist_ok=True) - faces_dir.mkdir(parents=True, exist_ok=True) - return encodings_dir, faces_dir diff --git a/app/shared/utils.py b/app/shared/utils.py deleted file mode 100644 index 47cf882..0000000 --- a/app/shared/utils.py +++ /dev/null @@ -1,40 +0,0 @@ -""" -This file contains utility functions for the VisionMate application. Common utility methods are defined here. -""" -import numpy as np -from app.shared.paths import get_user_dirs -from pathlib import Path - -def clear_user_data(user_id: str) -> bool: - """Deletes all known faces and encodings for a user.""" - try: - ENCODING_DIR, FACES_DIR = get_user_dirs(user_id) - for file in ENCODING_DIR.glob("*"): - file.unlink() - for file in FACES_DIR.glob("*"): - file.unlink() - return True - except Exception as e: - print(f"Error clearing user data: {e}") - return False - - -def list_known_faces(user_id: str) -> list[str]: - """Returns list of all known face names for a user.""" - ENCODING_DIR, _ = get_user_dirs(user_id) - return [f.stem for f in ENCODING_DIR.glob("*.npy")] - - -def load_known_encodings(user_id: str) -> dict: - """Returns dict of {name: embedding (np.ndarray)}.""" - known_encodings = {} - encodings_dir, _ = get_user_dirs(user_id) - for file in encodings_dir.glob("*.npy"): - name = file.stem - embedding = np.load(file) - known_encodings[name] = embedding - return known_encodings - -def cosine_similarity(a, b): - return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) - diff --git a/main.py b/main.py index cc421d3..dcb050f 100644 --- a/main.py +++ b/main.py @@ -14,7 +14,7 @@ from langchain_core.messages import HumanMessage -from app.services.tts_utils import speak +from tts_utils import speak from config import TTS_ENGINE, IP_WEBCAM_URL # Load Gemini API key from .env diff --git a/requirements.txt b/requirements.txt index df218856613fe05beba83c4bbb096ec3206938d3..6d7212452165cc0e5f5adf42fe4a84eef8016fb2 100644 GIT binary patch literal 109 zcmW;EyA8uI3`NnNyQuOaLF@$t>47GokVH%=(f0mSx4Oq1T1N62yD43Xoom=jPafHm{ zc6B{YoqAmU{pYsam0fu%qp~UA$|rqI%1`B7pR@8~`JvqE?5^y~b6J$G^!mFmtFqSb zyQB1(q^}0)PABU@Zc*ma+e`08w=IwCWuv{*Df+NH)$_6JR@*z>-b>>~cDK^72)VH& zF7!DMn=_rw%7f0ZwvpUA>}|s`dXfL2&*YtaFUhsyvu8-OQVVG!)_Z-7%b7GFfu9q3 z06sIFrv!G!5#4w=dpP>t%QukO3P~_sl~;MZ4b7mhdZCDRl9)&AeMlHjXZb$P;ooM+hxLzx3AS)A>+lo4k`+8j zmO8WeVqV{eAAQ7MIRK6yLSst7CNkB%@rNKz|(Uxqe( zb1i+<-}v3>WUrr`x0=YCt-RF*4kID%Tyq1j%uwU;-nws)>C6N7VVi3^b->|Tqwlrs z<95nUgMZG^X~~gt4$hmfbSDopI{ZC_(5#KInNW)UJCtR$zkXAoctz zRBt4+*6;J99Ga$q{zMagZ-*%^Jv3dpeR$W=Na;>Q(C6>-<_b>3yjWDKie8 zu0tj?b$@r1a_)`5vwUJEJjE&ZD{G(ibfoj|r+Uo;46v;>1BoE4f)Ouov>V+{&wHUk zPkS6B$bhT83-%@gW_89!-n-!j-j0=tw3ugG-6!X8v~Cg;p_94y=Fo{dUk9wSQ-UV> z9fvfSTn)MAPOnT;6R?;HOYCcJuoP3dcK5cj;Vd(s{*Rtz=$H&P=?X|Ng_4=Byo}MD zXM$oI1e`bDTq$cX@i3g`xlyMx!whC3`w25RC+B}s!M!^*sPt3%GS9bKO2A0^}7058C%Q}mn@f2*OM(vjBkd>?+< zBGP2bmGYZ({j774aIfdwJaP46Z5BE4Ug|D@#6(w&2i%$D(ji6Ai!UeplJhF~Nis-I&N>{oFzrcwuTcf|0AMml}gY#-5>w;bY zcNRj6INdYw3ZFoYX~0xYZnWD6y^p({>MeQe>P-Zzo#)6GHXNUKL@YQrt$xsX5pw9X zFCULN>D8J2oPFLkjWtmDOIiP1evNZ)afu0x{#zdK9@Aof9{SBdCTg8JuKlbD^5MON z=QUqD-B<}{clSD9lfmBSoR_z<)D(I40$4i(RKG*e9O2O!~ka-_~GdCkc% z5gW{PIifNnt>aI5!M4U* z@_yJ`%>1-+&`s*J?vvBN#aJG6n>Vudoxjc^Dr%!IP(Z7 Date: Sun, 10 Aug 2025 16:59:02 +0530 Subject: [PATCH 19/25] Revert "Create Updated Readme" (#44) --- Updated Readme | 58 -------------------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 Updated Readme diff --git a/Updated Readme b/Updated Readme deleted file mode 100644 index 0407c72..0000000 --- a/Updated Readme +++ /dev/null @@ -1,58 +0,0 @@ -👁️ VisionMate -VisionMate is an assistive technology solution designed to empower visually impaired individuals by offering real-time, smart guidance for safer and more independent navigation. - -🧠 Project Overview -VisionMate leverages a combination of computer vision, text recognition, and speech processing to help users: - -🔍 Identify objects and surroundings -📖 Read printed or handwritten text aloud -🎙️ Interact using voice commands -🦯 Receive real-time audio feedback on obstacles -💡 Access a user-friendly interface designed for accessibility -⚠️ This project is currently in its early development and ideation phase. The repository will grow to include: - -Prototypes -Research notes -Starter code -API integration plans -✨ Planned Features -✅ Object detection using computer vision (OpenCV / Google Vision API) -✅ Text-to-speech for printed and handwritten content -✅ Speech-based user controls -✅ Real-time environment awareness (obstacle detection) -✅ Modular and scalable architecture for future feature integration -🧰 Tech Stack -Layer Technology -Backend Python, Flask / Django (TBD) -Computer Vision OpenCV, Google Cloud Vision API (future) -Frontend / UI React.js or Flutter (TBD) -Data Storage MySQL -Accessibility Text-to-Speech / Speech Recognition APIs -🚀 Getting Started -⚠️ Work in Progress -Only starter files and minimal prototypes are available in this stage. - -📥 Clone the Repository -git clone https://github.com/kaushav07/VisionMate.git -cd VisionMate -📦 Install Dependencies -Make sure you have Python 3.7+ installed. Then run: - -bash -Copy -Edit -pip install -r requirements.txt -🗂️ Folder Structure (to be expanded) -css -Copy -Edit -VisionMate/ -├── prototypes/ -│ ├── object_detection/ -│ └── text_reader/ -├── research_notes/ -├── app/ -│ ├── main.py -│ └── utils.py -├── requirements.txt -└── README.md From ca8b65453098ea63e2c45c52a134f70d66803883 Mon Sep 17 00:00:00 2001 From: "kaushav.jr" <142465852+kaushav07@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:03:08 +0530 Subject: [PATCH 20/25] Revert "feat: Implement speech-to-text module" (#45) --- stt_module.py | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 stt_module.py diff --git a/stt_module.py b/stt_module.py deleted file mode 100644 index 1e00442..0000000 --- a/stt_module.py +++ /dev/null @@ -1,30 +0,0 @@ -import speech_recognition as sr - -def listen_for_command(): - """Listens for a single command from the user and returns it as text.""" - r = sr.Recognizer() - with sr.Microphone() as source: - print("Listening for a command...") - # Adjust for ambient noise to improve accuracy - r.adjust_for_ambient_noise(source) - try: - # Listen for audio input from the user - audio = r.listen(source, timeout=5, phrase_time_limit=5) - print("Recognizing...") - # Use Google's speech recognition to convert audio to text - command = r.recognize_google(audio) - print(f"You said: {command}") - return command - except sr.WaitTimeoutError: - print("No command heard. Please try again.") - return None - except sr.UnknownValueError: - print("Sorry, I could not understand the audio.") - return None - except sr.RequestError as e: - print(f"Could not request results from Google Speech Recognition service; {e}") - return None - -# This part allows you to test the file directly -if __name__ == '__main__': - listen_for_command() From caa4c26645a4654518f5c2188421eb7f62a48564 Mon Sep 17 00:00:00 2001 From: payal patel Date: Sun, 10 Aug 2025 19:59:24 +0530 Subject: [PATCH 21/25] enhance README.md file --- README.md | 68 +++++++++++++++++++------- __pycache__/config.cpython-313.pyc | Bin 0 -> 218 bytes __pycache__/tts_utils.cpython-313.pyc | Bin 0 -> 2458 bytes 3 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 __pycache__/config.cpython-313.pyc create mode 100644 __pycache__/tts_utils.cpython-313.pyc diff --git a/README.md b/README.md index 5c9bb50..7b80b6c 100644 --- a/README.md +++ b/README.md @@ -4,30 +4,58 @@ ## Project Overview -VisionMate aims to integrate advanced computer vision, text recognition, and speech technologies to help users: -- Identify objects and surroundings -- Read printed or handwritten text aloud -- Provide real-time feedback through a simple, user-friendly interface +VisionMate uses computer vision, text recognition, and speech tech to help users: + +- Recognize objects and surroundings +- Read printed or handwritten text out loud +- Control the system easily with voice commands +- Get real-time alerts about obstacles +- Add new features easily in the future This is the early development and ideation phase. The repository will include prototypes, research notes, and starter code as the project progresses. ## Features (Planned) -✅ Object detection using computer vision -✅ Text-to-speech functionality -✅ Speech-based user controls -✅ Environment awareness for obstacle detection -✅ Modular architecture for future feature integration +- ✅ Real-time object detection +- ✅ Text-to-speech to read out text +- ✅ Speech-based user controls +- ✅ Environment awareness for obstacle detection +- ✅ Modular architecture for future feature integration + +## Technology Stack + +| Part | Technology / Tools | +|---------------------|-------------------------------------------| +| Programming Language| Python | +| Computer Vision | OpenCV, Google Cloud Vision API (planned) | +| Backend Framework | Flask / Django (to be decided) | +| Frontend / App | React.js / Flutter (planned) | +| Database | MySQL | +| Accessibility APIs | Text-to-Speech / Speech-to-Text APIs | + +## How It Works + +Here’s how VisionMate works step-by-step: + +1. **Captures Input:** + Uses a camera to take live pictures or videos of the surroundings. -## Tech Stack +2. **Detects Objects:** + Uses computer vision to find and identify things like doors, obstacles, signs, etc. + +3. **Reads Text:** + Uses OCR (Optical Character Recognition) to detect printed or handwritten text. + +4. **Speech Processing:** + - Converts detected text to speech so the user can hear it. + - Listens to user’s voice commands to control the system. + +5. **Gives Feedback:** + Provides real-time audio alerts about obstacles and text info to help the user move safely. + +6. **Modular Design:** + Built so new features and better AI can be added later easily. -- **Python** – Core backend and computer vision -- **OpenCV** – Image processing and recognition -- **Flask / Django** – Backend framework (to be finalized) -- **React.js / Flutter** – Frontend or app interface -- **MySQL** – Data storage -- **Google Cloud Vision API** – (future integration) -- **Text-to-Speech / Speech-to-Text APIs** – Accessibility tools ## Getting Started @@ -40,8 +68,10 @@ git clone https://github.com/kaushav07/VisionMate.git cd VisionMate pip install -r requirements.txt ``` +## Contributing -## 📄 License +We’d love your help! Please see [CONTRIBUTING.md](CONTRIBUTING.md) to learn how you can contribute. -This project is licensed under the [MIT License](LICENSE). +## 📄 License +This project is licensed under the [MIT License](LICENSE). \ No newline at end of file diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a603bd0ab489e2b1cf8df78de103984e6c9427d GIT binary patch literal 218 zcmey&%ge<81YasubYAQo8LlHwTV-aIIlP2>mmh_O2;3|cT zl9B=|eSJeqBRxYi3q2!CAZ2M~VPIjPUzVAYn(wE{bc+k9GTznC-P6zY7O!VOe7LKV zv!ic(XpqlJhR+}iZYd{Q#e^2878S=76lGQ>#)M@SXXfYmCYGeeBQ-0JEDg`x3DL*NoAk~YLR;EQ8du^F^N)T5O3bT_vXDf zGw*%loj^cBFm~scX20?v^gI1<2U}rwz5wP1QV>B3qp%aqI7?Ved2WIu9L)R#KkgwO zN9LIj#swl&^j_k1>_j3?vx+eAF+yq>p=mB&=Z2}yQPf}gAd=#3Mx;g&f%>zY>{B}# zge1!{XNp!XZ}t>QlJudfr}LVLr?h#i+cLV9f~KWrai*xJtel~%`J7e48G~SJR>L3U zb9x#Nnr6X>t@dd-0#o4JT1;-2>>@*pJYg{Nny!k#5W-@zHP0xbX z#GmJ2K}OBzFQ}=DJ(83#)vPukb>p!)>d^^k7Bux@Ox{n&ahZZOcux~88AXEUG?T84 z%CLCE@s3lfjxT7~)GVCSamvs$xh(7#7tNfW#gOI9$mE%^$q{@KM`_Yg3|ov=l8s8z zpY#xA#+It4lkmw?TbO-?yjn7iqMo+Bl|?By+x;N`$HD)O4h3)nCHHj-lXOc01(Cug zfcEkI6+K2(t-?7M{T4#4D9O8?<6f7m&Ixp2ebv%ewQxDNG%(5@jO1}5m7Pcd*EWF^ zLGhkobv7AvW$}>9Rp%&DM8&5_Cs-EgT!M|)S9LCz;NlG~U!4zR{e~-jouvXTq@e!F z8Nzurxhvz%E?1qS==^IUXW=B;QPOE(y3UJK@TfBfZj4Vba7S!4+cwBRX9k&UWzH}e zbdqaB8Kxa|p;#q+8tya$E#8JO{7oiYix*;bycDa3#!~!!Ts2zqh`XPI_x%4k$breS z1YN9Nq?H~kbMgQtv>wZ$q}z-mgc#&gOlYy#tftGX&07EfHlJ7Z>}Z+qnJe^xP)KWe z&C+baEM_vf`EnrXG)}$>|oMZD0#~O>c9iTCycl z)CcwSc{OL*zLEKqR-j0;myBp>bA?PUui15z>YSFIf=`2}q%=xpys2ISs)L3A(n9Wr zX$wS~Ge8`4v1G=<2ALy#rcl=D$ELqb=TdW&FGHVt)DPa(emPn$)$ycmLrHFMe|0+q%v2zGGYd zx`pwp^T@gtQiEj%>4{uYIeoacOwjTCeN6GPD(rY=*n; zg}Z(n`K9w-c-Lg+J&)e zV~eSqv)5-Kz;*yhtxtEoC=}U23{51w*3hy1(elt*U2M}Yulwca+Z-sKJ@Hcy55i;5 zAt`FjLO%ZR;@Rc)<@&XbQ)_jnH~jB!`J0!HZ~F1NA3xvrfXOrS44lFD@=yq^G`0;3 zXr=${p?>by&KU5kA!+CxZnZf$)XlASdnn&84RhYr(_YZt6{O+g+}%*~a4&ba*8}_u zph<7k0nML*xj|tM=DiW$2TfOkQ1zwLnFJH3t6v%i8wM<10i6c{5nw=c9aLa|P1d*) zg-NilfB|-pbzlJIDh$Z%WI2+gt>LuAOI;_!%MM;`KBwm_QVT4huu9-bM})$!%sG`y zDD0955R;w?R4r+t5?Y52>87f)KrW+g*5m2j3OC(s`KIOD)+@q8F}NUIl@^b0h)uw6 zijj3O@<2TNbgQNT$^vY~z*lQvQ_Gq$kzq&nSQ*-jQ3$7y1xH3|J~LK-P)qr}+^Z6hc3AJ7i4 z$k~uBzBgy2i+Sx7c@t#xDKt+4fpi$=FIHmsf0_`}`UnLdqeG8T+apx_2>G@J#0M86 g_qpbWfrf?YYtvtUc6sz~zMg5{IVLc@qys$s2Q0q?>;M1& literal 0 HcmV?d00001 From d65d08bc4b2f1289ab7be4beb0ea7c51afb67d80 Mon Sep 17 00:00:00 2001 From: khanak khandelwal Date: Sun, 10 Aug 2025 20:08:56 +0530 Subject: [PATCH 22/25] updated requirements.txt --- requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6d72124..e98ebe5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,6 @@ Pillow SpeechRecognition pyaudio playsound -python-dotenv \ No newline at end of file +python-dotenv +langchain-google-genai +langchain-core From 8a28f82c63255c05fd68a21592d2bd2340d1b866 Mon Sep 17 00:00:00 2001 From: Mehendi Hasan <117719513+Zehen-249@users.noreply.github.com> Date: Mon, 11 Aug 2025 02:09:23 +0530 Subject: [PATCH 23/25] Refactor to include face_utils only (#48) Co-authored-by: kaushav.jr <142465852+kaushav07@users.noreply.github.com> --- dummy_user_data/pictures/Paul.jpeg | Bin 0 -> 39784 bytes dummy_user_data/pictures/Peter.jpeg | Bin 0 -> 61013 bytes face_utils.py | 77 ++++++++++++++++++++++++++++ load_model.py | 54 +++++++++++++++++++ tests/test_face_recog.py | 44 ++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 dummy_user_data/pictures/Paul.jpeg create mode 100644 dummy_user_data/pictures/Peter.jpeg create mode 100644 face_utils.py create mode 100644 load_model.py create mode 100644 tests/test_face_recog.py diff --git a/dummy_user_data/pictures/Paul.jpeg b/dummy_user_data/pictures/Paul.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fb881c9468965c6056ad8b5e7606ca276f45f5f6 GIT binary patch literal 39784 zcmb5Vby!?M(=T{%5AHq;?(ROg1$TFM5-bFQySoH;cXx;2A$V{JNpMft$@|`Wzx`u( zpJ#jK^weqZu3uGk^*QtU?e#l=r6{W)3&6m@0P@fe@VX0l$-K9>0RR;hfC&HqWB>t% z1VDgNFwjd8hV=i?8ZZn1+<($x0RR^Ff6>rVV}Ai?3V;p044~J)0B!j{_5brL=jv+f zWKE^uV#!9u#lgu3?R5|4n}W2o>01poSp{Vo=y0ILC;nB0=Kug_7cUPDIVmbVeFG|_ z@6dMsjRYFZEj``-OZ`8_&{B6_|66v6_5ZQN|92vam9?iOw8#bY0((F^hmHvkO5@r7 zmuC1!Tl|+6`A5I=a`S?gdHav{(9)2G(pFHK!S??~Tm0W>OE-^y07D-DaOVL4)$l)g(CGhVY*f%JGU&Km zp&who39tsJ00qDWumsqk6c@k&Z~}a<8-O%`2#0FQ`>fQW>Ih>VJbii(1QiuVQ+ z9g7f;h=>r6fPjRYmXd^&hKzuKiiL`Xj-HW;k(iQ|gO!1UmVuGsUn4L`NJyy2sJN)8 zxC|r&Bnj4J?0${OW;ILs{M*vdj%;El_|9=7uEF5&aNYG4TXvV+r zKY74^GGEsLbT}9Q77Gpw%C3etuYiChfCz9vztH=S00t)ptXU=iO9EIxzfcg*XO3i2 z7ovlBs0-;rOCl?oqLcqcsTNG~(a9ia0wi*{YK#sTFoQ!jd&>bu4k8__8Gvj?9r7PM zK-mEeC?Oa9FTJv|xyx1PVuVaz!PGNj}yV2Ra^ee1;(v zWVnhYzzq&D6Yeu$28;k4Sc9C<#$YhCkB+(m`sf1ugcJ8Gd%t}zD;3KA0#>3|jx(7X zH1++1cby+mo~}a3iY@_bCoQFnV~(8$s~(zNQ5IPVVl1S?j!mU{^BE47XaF`m7efeu zwmyJ02vA8NyN@5z{gF!;>wMBw^-_^n&!nrPD*Zf4ovc%ozY6LWOMeNn{h&IC#?FHP zpl~P@Vj$ZoR7Eb}Geq&oD1uZ_xzw>ER6;R0Kb4?EXU{=m2Aw^Sjbj(D_+sNHQsVox zj$qeOv7|t7AUlM{%sr#-T~9stTCBNr7^C06?Vv3}9nlwZ2!r2~+UAja6LUBUCr9=gB^9YG_^J!VL{0 zh~h#FGho-|Y41O(@3_n9Q7hTWsgN}|0-ykZu6HUV8&p!oq>g75Sr(cN;u10&EC=w` z5rK6x03CpV2P$TZ$87^%sOP?AGMfo9gzD8+Ti2Q>DRoVHlIzD@Lv3hdX_+GGiQ zqfTyYSW>jzbiDdoTptO0pn?o#DUXbT7IgFrctebZvhtC`B})_bAMw`BmZ0c_qJs;^ zTKl@cIADYPhl=ImN3tJ|7Jl4S>`V0-2E6vG<9&i&b;nByt`_^`IkxQdd8hl82Ml+D ztqJ6Fw>|Ma?^Vx4Dg147n~fN8UIFj#ffOB2Z-sm%B(ibLQV@tC3Pp@n3eaw$(}efR zb{jbXoH^`ckx8J+P7#R2*S;<&dbuV)!5uGAd2@0ymY;cYxNY!bWx92}0vfGqe{ia+ z+n}{*f3ND}D0sGJaLwt%aJV$}m{8=aCYKWi{_{Z|1N_vJAm{t!D-{@E2CD*VCxOZZ z(bP(TXueI+DrSf@UxX#f1y1Z^VLoyIWK<5}&}=d1n}QtMR#p)|*({fy^~alL6XV=K zf*qO7r_-ezUA7Fn@F+_slhUQawJKlhniFlsp_tvAh&jJ_p7#QdlfNIYAl?~2UvwAR zhX(kM0Ic~GDP<4^loiLYHCb6`SLkAFZ=}-aiBBjt1`&{!zJ|;ye z$kAr%=l=TiwPAdAt7d(H(!0HlxwA0&R(JG5APzD zE=2QL&~!d*W-PqW_wA%h+z$dMpJR|eg6C7yWO!tFz)+|{%;)V71`zW&5SI{h0Zmu{ z4*-pr2!DI*T$*foe5UAdIG&G6cbK$l)>{$z;#fU@&Hd%is@m}V!~GAZeQ)lrE4dWU z#mP_nCc@|6?YI3_tbF?lOrvkMgJibV*7ijR-n27seE;!G$$RSmUY6vD3VuF36e?H> z|6y|E0^a;bAqz5jp2B z9^cdb%mOJx!h`=~NV0LPp$J&OE@Dy-MR2v7lCp%&i6NCZBtWOKUxym4d5;&{u8ZxU z;%2_s_dn}po#|%3-MjtvK72S)^)R?N-_xI{Fz)c_4NAXx2^8Mq`<+&)-(#Dbmz|>#e&oeg9 z;Rd6OA_3hpZSPNe-n!$HbUZsRWhm$PT;E>ac-?$oo2wf)WVqhyXYDyy()p6xi&S(? z5s?vit0*+`YmPZIJ4pjc#vj2|!#>DdXe}W`OF>&j;SiJ9BnBnEcD(x%Udys!E-Ar_P5z4_5;! zQnxXgPoaD@5oP0x{7o82m~kW0ElpW}!0s>mCNAq{!Fp_Rg)KMQR)=4gxpeAq)vI;Y zIUw%+pMEf0e-wZWk1T=0tMG63Qc!yXojH%yItr=;Fi7Onxr4-h5H!IGfR%@&RZf@!M zwsJXhflo}wej+WO?*bChuwda)sw9H{+aU_FLLuM+M+dB1;vz;TX09W`a|&6Q!GE3y zJOk?6F3AEjPUhYfY+3!_uGG&cvS6q?F4tx4y7M=Yw();*7PFWP>2 z&PU7a0Jpn=7F zT$(wOZd9=NP~=z-^eKFtnZ(veE-h-rp>RmeokeZuCg_LoJ)n>NHVoTOx*#8)FqzAF+%Cm32}x? z;Y(!Jl;sx#Lhe`q)ciPv!m6O~f?$jOsYPf%FpcHe>t+KMmVgE%C_SDpd&q%e{xRqUqD`N3Mg?A|t8CL=|be=90 z1;_p^827&b07%w-Ye(bCFyONhmjK2VC`;g!p?fO0*-N3#0`^6x46)NToujjM>!#sA zQMN$#lUk9xpBiX14ubSWW$T`9y4FE*dw};IH2@2n2!w{f(1nKJI7GG}Q_HGwPr@;C*|pzcmMYIcCW&)yY#LACSS=7>7YxU7@hd?!+G#-T}*tWOsG8g9l_zggC&LX`JdFx zLvfAr4*<30*&}1V0lj7#DXyC5@yOF)CeyB^O^ z`fa6;LeR&TT;x*HEkz1G1PhtB)y6JX`qxr=d)T-Sa* zEeloEx@=u^UJB!NpjsbDUh?BBz<=X={p0G_apm;z!c2Ly99!dNoN?W`P2m?=O`0rciZXf z-hR^Zf{@ZT`EGD;E5FoM{up<-)whA}EEowB3pAYiJ*Fc)H!(jd{dzoJKC7slR#flWGX z?X|-`FHSP97)|9$< z<$C-(rIhFAv`R~=yKsQ7P+-02$!bQk=;E|3-`TpXF$a&nW$Z^7P8=yxiIFj|ymCa= zjfst^V#6(G#n^~8(@$i@rsX|my9Ul*wApU-Eb!`_9<5?MB~MyCqE*z?P*0ieC&Y12 zBI-!z!M_qFTfa8h8GPen`RWqZ516pGU7BpJ$UIh)(c_r}^$*15 z*H8M59(wxa>ig`F^LbmXDkoW|ZfQ+#>M=s-48^xeJv_VKt2tjR_XKvo5?kJA0WuPns!e+EePL&ai#=t<$=4l;J7GW(YI7YPc7p z!ZKzE#WRsl{mhuIKYR3ckl3Ml>fq=e4=nxocyuY{_+h@e7V9)UWa!f>l4WjTNGzAbv>IOk@_SOec!7d2ia;rT6Ew{AZW&Nos2MjX8@qbHSADZ z3=0DXivSP%?@R}3s{S38 z;F@1Hr^;uH*kD=aCtt9{c#|r+@Zws^-cPwVh$2*4*19B~zG8|Y;@YOWb}C)-ORihb zoip>eWU`?0CM*w6wEw(!i6MC=uz<08#g}(Y&`?~F=BD4F;KT5lVr3aowUjeoE&kIjn*87!6;FV;acZyR> zQxDJOB!yMIXDqjL;qP!A1Bf`>1u{2on{Ld8d9L01)%XQof?^D(UIAS=(%oqEt1m2j z42h-5#U+&kKTgMKVmP}X%G4@HMpivs_tX338|rMjPafVJ3`sR{5C?pV&#wSk7`eHI z(ln%!zMLXo{uLl@x5-zSB73JN`28qzQ}N(Oety92WfRLwekl$o4GuO94ksuc6j=l| z8yxTkX%n38O;_!y65T#1?@-3&j5wXz7NTHFLDcbNkmcp2WYLK@%P7_?2k8$gt&h zebr~-|A6~dWNt)&@+w*Ck`{bhnYb+QC8yYerB;4rewThd@P+*(pjvehft(?cnTExX%xoLyxdr5w{rPWNX4Qhba{q|?tQ&di~C{aBPBt7e%8AvT=;yXDVGX&dQ-+>89`Az ziX0W6@Q2y8BX!587P?&Pg+t>h6KyxQ)SIhWyt93hRHlWs&rdCN4+7rA=KGW>L)2IN z??WHiv73pWlE_QRaycYEMUjFM#FTZE+X5T|txNP6D3AeZu-|LMD0~28}!tQc;J|MZ6&1;wZ2~d3qeR>^EAna{WVUjWE69xHa>d z1W|`4omR!6uvfrzKS1RbSm6!}vVsKTx#P*;B3Yc8>s`~xY{yUACCl=egzKr;8XFuq zsK3c}jr%%0vm_JfT%xKk9|a2!VJ&g6;u1AU!uK(h`#Pp)N>A#w9`C4rUZ5x@bmIH2 zO~zWT1sTgqKE@G4n)HVT&q<+GE{9dj+4l7OBth!R5w?l`be>SbyYcrW?(UkWIAHlE zmMHA>zU<1|P$5aPrEk$T!a^+a=Ld8U!zP)dV2eD>ABum4O_{}nN2(8%E3NhiM-L$o zeMFh4EMBgmoY`J#!xg3U{9iJB`P4N{6%QZ!R-J4o3aqz5Yq3d=KOhAe2ZvJ%a{KEV zx+_f1$p>tq5D-fYE-Cw&zCNh|nI%0ccoqlW-Qf@YmHiKQX=4l4%*nf!X!V$I6-d`h zMAT|#Bla3LXrghtBs>c8cCxshuK1y*^oV$nuxl$ei>)b;ygpV;rlz_@)OATUliDeC zlqQMKO5G_GgDE<^)i*&V*PVpRN^OZtjX+dmG+nSiOqEX#QrgSGhmhnQINs#FkXxU|N zw=TB$uT{X5?JVmWpHly{F(%t#(>lfJIM14<3MAA*dnD8nq#m7Xmiax&irMN#jIZ;( zlbLAANjSiP5EE^Mt4eIcHd~uXE^)2DmZOB^swc8O^6GfVt6w{?q_)o21kJs38xyiF zJ=hW78B$|YMM6SV>Cl}fakCgZ6|)~C?;jHg@6bMHC9^0)^hzX?Ky+4~gXUT0tsZ8v52k%-~ek8=-O z8rG!HH4JWR1A{$Tat;|ku-GfWxwn&Y4weNoGuFhyw@KZ|XF!XqAFJQtQ0d}y?1EWW z3zP2yTGzAB2qRafeu!-J4S}>G3;l3zIO}w#m3S#rzn=B93U@UKrFps zgc@0D?I$c48#}O;_k(q}T8YjpP!`itnNs)mf$l=EIVK5eQ6l1Fipw{@QbwKnI)y^P zEt*6ilVtJC@u}%;bf`~f%nCzU?ILby;h&=mVNwSq+^CUWbKV!uyU9T9=c6vU!aWjn zY^<;zWiK2MBr=p;+s#Mldv*NJBh$i!B?d-yS-g7^-q2L)IG2a3bG-)tYXVADLun2Hjc>A=G!SInRTAYp|?R_Jvi1r z!4oQD%cA4RW|UOSC?Rb3HQJ4>Y8#)u0vJt*90zSRwQp$RkgR4^Ong(n{ZmRrkGx^^;*G^KV_J zH+1}yIHJW`N4jMpx3ibA;)T}k+3oTR;Jv@s>6ldzvryGX$GivYuKdFxmeEiSAt!H1P(DX54}=+D+Q;epc}@-z?UjUriLbgJMyj zTa&Q`f*F4YKg9xPM~s@EIs!jG#YiO<+#EbA_z_nAsc~AUSUhmVoZo(PK)nDN$dCf9 z5z)>^wpkL_+^hd=K3%>inN)LC!>yc{3bGZere6*4OP{m8=N0m{NOt!Z#EK${BI0Z! z_~9r#U?}hJsKPwM8x-BXa9>}(Hki=u-9v*ZrzW-LOq~?uiCC4u>6TRA8x5zRvdmtsj{s`j)_+{X+_$r*(~QgV^U;mNlFe3okkEuuwS5K6s2oA`hA zoG}VY(d@G$Ua~(_iI%P<6FR?Z9}*{f1t{|MdA+Momrq;qWE`ArL(e)3YBO%Yj$a)w z#9d~jeo{N##eemA1swj~JdwQnQiFfDMOoQ{WwAcA`m*k7LB9?Ob?nW@eJE(d#67+p z3Ur>gZv`z(D+&1Xn|eFb==2pJoI3n`+DgJ2gFupOn_J{{xeZjbZw+nLy#%tjY`(r1w5al|iaG zbwvsGoWJXS?y8;0HmIF71`4@c+&SHuI>-1JbUFNu`Fu?&jnxj}Yoz?GPjiobzN4IU zD|yjHZb=ItoF&idp-8#`nUJ3$4# z)81qns(NDojN9WdgT*c>7IA4dmR!5l9*)l)7dCN&zTlNnSufSzO-%Lg?y5*gmJv~~H8l9>Z zPp4hvHlz4Pxxt-VKrp2zTjSxzzPa_-B36WpmF00bVkBSxl903X$9;y8aK-Q!G^6929(a^; zJ9_8cZ1L@U5`J~XdhubY2M;ncE9Z)7+1w+@E7z1(vr`p?fFP9mRK~U8dx>I-i9loA z#FBhNUOt-CD&wK_yB*>s4O*4)kYW#>ehZz^#DYSfoJI}bR>kNKD4OoSpbfqP7CNh_ z=~pu4A@dh$GB_F@=U;#SBta_=eseC(kK@g zc&j)%id~lWTRpr2Ycx8E(Au73x;4`7WwKQHer=?gzjG1OSnP=DYpDb6v4MWS{yUBM zhg#@q1OhaMh5O&A#m0i8lE9(<4`|`vg3M{u|BG7K|DtwLf8`H(Myn8ef#nC%qxJ)% zwwDUE03UwKZIO3P710^n^@f=(h zD`8Fxktpj_p0`Ph40&+jUWbm@2O@m5)|7h!kif{Mk%e#eTz$`sX!`U<~vo|dsNAbsK zjcIM!#KcQmE=Sy-WJu2%eesVjzvi}`U5&{s`)W?*Z)frd_9xL}wcDe)?P=1j(x*D( zc+2&x=Hl9=wP=Nyq-Flz7@veQV^kxZ=~08>Z}(%O%8K2XC{a6zM8}BN{D8oRgvx!jx5CRAn9rNE%P+)MQ@7$>PI52yzKwo|1#x#8ETz zel@))O}s?=vrkgeT#d;jOcf*?^F;sj0$?T6w)2n(vUV3Cku z;o%XXFAx1wV$j!+sNt}vplDFX0ZF_ycMs-DqR}X9#FaAhfaeZb*uAj$IN0>R4yq8v zp$Anp&Hi#}*qlo@Vu&NBMB){!ihLZVtDWS#@hg%86{<}L83>&0GjCxXtx zO=)NWX>{$Im8hJzrnB#&SohRC8c;Quye-4g-c3w8FDMGy6`{Yeyg|ekqHCPDvV}=B zYz*Lb?_GD&YJU78P zb?^{#GeROf4ZS3%M6d#cJ0!kFC^B-}-W#zdO>ojGk$^ys70nATyexY5r{XgYZWWk_ zJzRu$gH|Hz_Q=u|eTdyRug2k1!`nOcmvSQOuftty@hMdlP7{$88LpW1G6K%cXLxcP zY`%#r&cx{9=||0Vx^!Q~WeS=`=w=r3qekb~V|ODsUN}FA-Cehbq?syXS9r@QnXcKi zK3B@0v>9(?YLFGXGRJ8xhZ*x|MBj{0g&IV+e+pp1a$~>_#wP2o^0KiU z`raPuU$550b&tQRgIJ7dwfiW?2Bv?vd!aF?v{ITMQwt7dcORLSROHaKzsLO-Q5V}mA?;b@DRC|8>Gku- zu2JMP@!q=`$}Y|{)ul`g^q+G-b(9c7I9f?b?llX%Po30bDi3$vB6NKZSozC>w@@kJiS-I(ZKIrR|VyKUchSdk7m=_DlZB zLU@GW7@L=RS>f6nL@wn3>K2Y4Rz><}T<3Uex2oTq42fB@#YZfIykM;XQa2KYftE8Y zXBG-Er*r-$&lgY15WuArTS;~`rjoJvZA};gZQn{rS`}LvG7m8g8J=PA;d1^;+b=>Q zqaZ}_V=ZweQB1aLLp2kI`rR%_#i9C{uV=W0cOF}u#e-lcW*2FLx|Z}DdkG0i-WuA; zw#GYrK^{B7fDh*Cgn{po&lEH?XUZu|$gfsb;5>vY>g5ecB6gdfqSs1uJ;T1)afQU> z(Xt?MP<_|TDqX0;M5T7AJ=Y=w1s6MPj~!GXAWu5QB5^uXP08MuN?p8ZrLcwzdC;@d z+1N!MI`f`%)p9{~awy;llEP>z*HTPV2hqw81}Ma7#ZCO4tt1lX2}>>*s?cLomjK)#N+O$h*ZaX{i;RrSS(i zB3pQq63!p!kk1c35S&()n) zbea94$DX*&TcUO?OiUlA9Vv}lGbc!Ry#J7tkB(q3_)xf+!P#6-@=-WC8rYAj_;%Li zVPBW_W=eXp3T0*vEIA$(b;JK#zm-6~c6Z{S+z{`moT>$%#E<$p0=sF47O@@1h;>#b zS(D6bnWWr`99<_yyRv5S6?nrR#4T&Y_lu;0Z;+qcFy_6xN1J9htBPh~gQ+B9Ki`46 z;|Lj-2$?;YN276hTSYcr>AgE{r>A0g`mXY~+Zl$10NFoU{3^WoEFU>uYkXIlkG+?E6W*i2Amh%mWX8E&w zoiKcwH7EmSg%=*fUX44e6lj_edBH$ASw-lEkLo%D< zvY$!*xopfP=PxU@SsG+|{u76N5RUl{`ljO^EjgyVk z50n)dI$w^qTnBAHz2;p#2%7+|^(yS|JGr^cAa&maT~U;q<7O5oTCAz*8hwOuQU^f`<*&(UjY(ZviYnV|8ONGkjlMM7pc{`=byyI%Ca_<(VK##54?v9 zNwmw`ODJXjI3H>#Y7RT{@6-e?{33mXU2+TgX^djZ8?D8zHa<7}&~yk2GRq1mU3&$V zovo8v;M1=brPjvxolKIE)jaQp$5lrq2en*p&)9MarPVNk*cOyTeb~u3e68s15g+K~ zb1B`qwJmlIoYFUN@tP>;R!@wp*?;v9TecBx5ZJ!p(>1kd7}8h^*ZjHX>`}U(H!@_A zuB86uj^4pXl<S=;i!#jfvhc!BvN#z@6Xfi$>Hv+ot{CC2X3& zoihTPX|bKtgkc)iL94sDJ34e6%H$wzU!7gPP1;W2aHnm|l>B8T$nA*1UE(n>^8rjd(jkVeioXPG` z0E^gCx~Kj6vOuLEYA}d6?4cQ4%QV_}F2uM>65wUkyXz}=>@P^GsOg+Dlu5h!rOS(S zQ8boRjU3)7e?)T&kGVlDKCf?BF?q4uzkXtN+U!oe{z4x&V#T#cj4Q!?qv+~sqIzC$ zk(hoog=}_0^*1g{TED4!F@wt$J%h?~vg-LO0B%V~dH2Ss2$N5Szu_rb2kCGpOW{kh z+|97&3{ug8SBS5CFvTv8eTCaD2GqxPyiyh%4`!@9R|_O2;%^+>hYQA|C0AT>M;txZ zI6J{@DJ-v0SCrE)ocX#GKyh*USLSoXZkJ244h$t%U6*aUj1r7hjYF$NAs5v&QS(b$Yca67lSH3>LAad#0)EO`e^V`X%G z_u0Oh0nlm>ShMUzqg0&ghjOLuB$HhE-7qK9LZ( z>GE4ZMp5_>#$RQL=*-|=bN+8xvVt6@R(fHfY(ufaZYH3p<)THddgen!>hAJ(jrmx5%~rbINJCEMQ@?dErk7wETlM|woqS*Q&cTQ(;C|`exS@w{R;UWJmiO_UFfJd-?z@x zie=zoHSP-VpVNg-zNB!TuGQtBtndFy?PD_fpDULA;? zL61c+SbX>OyZ!<x^8w|ei4JL8E@3c^ zIG`sfgO9*24Q9qgRyV5%W5uxY>%n#(Wc((JY2MpB!j{l7)lyNr^|! zgPM507J(pO(jP08gk?TkkKTDKq2X`+Cwlc|U;{p4~Gh$%431v$xw3(C0YRoFzBe`{c4>!7u zO~1&%p`TWcFXau*GbL`SP|O2G#dXvJ8L8s5QQ>*pcC<6uXd_+fd=AH?V8$=9M;lSy zC|{(hnd8r4pWLG`P%i}gLI(Mk>A@Ey@BGnh>1j6Kmv(BIXaAX$2x#*HH{UDU(Ee&B zd<7tz+ydE|he=C^UC<{iVk1ANTv0^sa0k5?kUz_{=-<3V=zp-%oZ+XjQOp;9{(DOv z-`t#pqHx6giL4F@RvN5&(Ng??Q1#TXm#Mfo&+2u;H!qhcxvQp#o7(kRZN;kl?K!Ui z;_qmNt?$3l5IO2$l$r`zWrwTEJ`kSLA(UXv22_{ zuCwR9ejq%ynN3uh0?RrYd>I*=F=0_NfA=9KNg(aMaG7GxixF+s$~P8`NtMYm!D5$b zJ`X}(XP%1Dp~Kne%E&w5$des7+8BqIf`PdYVSR&hH8<4Lf)d8fiBj=ZJ;+LV@2`ny z6pD2dt3bGJ8V5vq9G{cPAGHdf-Bm-B`WJk*|45`Qd3$hUZi1CK!Udkvr|!?kHVl5K zw!9PNZXup9F8Ik|a4M!hz3{;e$C?tK3Vc#`-)!(}QqS8bvn?wVUB{gch< zAVH~%^5b&DSQxcoF12VFQK*Mm<~P;^(0=ebd5a4~t-*Lt7*!7shiWh(Di+1t z^3wi=w7v)r1(~58Vqthx-DFK~6K`xw4-4P1Zz|$Y;HOH{Y=;PXFv}}KP8=yBr9dqf zE(AAUdUw8$HWXkN2DBAK`LaC-lY%tYsgGN%MC`=zZcT*ZlxvgiQj_zdWr6qhPA3ZH z)DD{>YDzTI!G7#FPG_j-jVG6nwnq;B?B85QJy459buPa0fFk2!jABjc!eS4TN*4Nv z@kR7R(}X+&&&{&HF99W=qx3E?sma5xJCxq_Ie zZ$yc18tt4T+Vu&HWM7ao((PO&LPF0JG1NOI;bUcsiT#jZyQqxd$|rrt#Z7+9o&N*-i8d)IQ&wAuu186 zZ1%IgFv}dwk0@zMZ}6!l1#=;;WSz?BW22I#Y=(9d1Uce&f+*s?O~h$eare7-*fwPG zc3eZvb8Xz$klfZvqxfBxb(!(6K?;wP(5)Zm-z-+fX+ArhHZRt0ET@wTkm5M@U3&Ph zL;EwqTY^daP7XRnciBCh-YR_-Nj@hR{)VY1LmVr;45wEBzDG&smOPbLIF4bHURl|d z4!Pnff*FN;**S$^7rl;vgNf)WatWNj-=JH}T)mCRq1I7gCN=w0+Qh?&KM?7M{~N_- zSY`5;VamAotE;NSIfXx(of#Y{Fy-5*8{1S7zgRFGeBsF`BuAcAKmYoML?b?=!fHuF ztxPZRY4H}0jBl8Y+D_bT2Oc@gMZIH*-6@D2wL?waY`~7d%aEhYnmD?|V{%?5(sCC4 zhaR~i@)re7cqc&w#dnh*^DyN!bU|+!GyfV_4vk*ik>G={&&LG7j!T`n){CDVEhv5t zZxqvzNJgO~M{#fpep}BkaXk1i#P$lz6yx+>;q#Bkx0r`wQ}s`Ra8a=uB%+hWLw*}B z7r@&0Q5fzgffuCouB*SW-lRxLdC&>8ux3&e%EC)j&|Fc))g|*rD(t}Gm0G&&qH3}` zZDqaW{3T}l@r-O6E`YVdm5qn4xQWf{CiC2JCS>;Bw%8|($%W^SmHjhnLF2ay?8dfI z__x#Tla#ZVna_4%j8hY(4=DE>`XUska9Oo+=j}06#)brWJDa==InmNa^k-hy)kCaI z_F#JyRuKZn`|oiAB&=cwvi94Cbs-DPS`s}`;(L9r=hUPG+jk5d1i0ae+0K(>qZ@y$ zezsj}m>vEpNunM0k5N9to8FGVtIH|L0)Prw&^`usC zUf?7;6z&d;1y~e3SV*z9kKHFyM7THYv0QX8Zzky9JsXH#vhQ;GzVHh6?d29E(Oj{= z9c{3csgT~#-ozx7w0=a<+JK&ZrdYbOQlO*10t4)@gsH>niYiVFUiW3mBT}tlqQ>j*gsN*tXQ4%C>2<}e z0g5;J@(KC%abl0sk8fP0#H>+g^PyncB6!+j5KiwrB%Oq^Dj|t2f6oSF{DP?*n{!8u zp{9jttVlFp8-&m3$kd&$C?VT;lBM^he{fzK0( zN>tPbXMH!PvXtU^sb28aNgo2^DJ8Di@TsvRH)XaK!ec2_q?K7Pl=zEA{Ir2t3JDyc z`Nc~7vAsxt1Qz8falWX`gr|<^7(}`F!M8&noX8L9z#~Mf{B6{T$w(BZPEq1$fGZ^} zWp^gTh@u;)?0&^ZFKm+ku-aE6S#IfF;Hm#h5@a3r4&A8o@Sq?y5%ISRJm_2|F&XEO z4I#}*+N3X?6A^pZ1Vsdv7MUgCmrrD{AO4sE?nNy~pFAsn*KXj}zFp|;N)_!h@Qdol zK}Mpg>>@LPw1IWW1 z{s>e>BPZo^%c&Weden`hiEvgZX-{8x-X2tp9zZr?5{f00A4P%bKVTGA8oQeLM~pS!;pXG6VtlQoN#vb8n3mnN|i{(W~UWU6vqWfRcO^Ax=1x zs?Fo%rfa$gq4gi0Qba-`gIg537p2pVtO>g{>Qt{KFm)BZ9+)e{{qs7SG{sl3XXSwB z_f-M~C!{f=^>XE6L{v7=zgJp&fEC2yp8nh@iYAd55U0R9O4(HWy$4}vpHHS&=9vyF{jYKxIRRLT~;!2^6uihoxONbkJ2x^R(YjrtdbM_xh60*d=Yo?JNG3d zTR$)2I=3~PibtAfSS7RU6AHYCPxfz6NZWL1cbU+sUFFa&2Cofdq1zkK7J`szCie7moTqV=J_)adk=fn8Cn4&m z+a{v&<7a=H_-jW>_9volht{W5=?#41F7y`J&_brA0slCf2#}H*l7dzui(r1q6jg9_ zpvv6*9uM_*6WUz^1)+BMmVNp76VaiwLYtE_y4!Q^m#CP*zMQ1OT7)k(pK_B)F6uix zvyj{gFj7k7CAnB4g)nF<5iO79+$}4U6g5mraKbtWRy;h^#NZ((>cjcRZ@ba39}Ws| z6r-P-u~W`%X`G}LYlc1Ph8K>d#n&PN5`>yv;W02U-e`G{Xrk0K(fY_QrO-FjJPdX@ zDZ$EzY7&~j7Z&cz!H5htNp7&Se%a_|AoZ-$lk7)+#G|f0lY{DlY2BMl-5pO zail^DXQJ&u(FUc8#q8Yd1HD;OcC&vaCK(7_&Cfy*#t(yGkbD8|0gt_`hgEv<^kulL z?k5J*t^DkoNNH)mCKB|sqe${BM$rnvokA^Yq;F|p5@Oaz3MYUi!62F_yDWzOSq|+xJ6xJ z6q!n%t*%>TK#cKhHo2oQn@cr=9Vm_zBOf z8yuy+>I_SBQF8c#=WErF`Taz(;RCbuPAYRA0nWQIckyyejZvsCn|>#)3C@FfqAMJp zFCqde{2I^M737*x$6|H&E5QSnua@Jq`Wj7s{yA}eYIvM#X1MfEfb)?59rGi^a_md2 znbISH_qT?3nsY08+vhe8S*6Sx>g(|YD}8Sraa5P18fR0(+KJc1=&3H5J@{^N&n1b` zlV{`YI78*X_f_U;mQdQNIT2y{9Llgg4d0xmm_%c~rou}9^}6$nbIbZM0e92USijaf z&Y0(wEwgFPfXrs%hExScP4SGw!be|zs)U0O9+>YJMZ88YZP4mRjgd0?sGo`bO@C7f z`vs&z)Yl2AsD-grA0XDQw4~Y=hjIN0U!~hMq^0dE%a$!dJ=5Wd(!17c zpzof94}FIz$lZ-N>en zWtI;j;JHDTJnXZGyQL5XshAzh)!sccyDBu*mtEhWjp30gz^fqXp>+boK2-NDI7ZBC z`iFqaIRf!n3s}g(E5rU_nCSOztP-zR-RM7)jH%dh-s|ZJpt=^{Vjd;0b}(SfW$%Ig zbyPJ5Cy@BMw_#M>;H6d39y=VH&7nfRCjtErMVAbe($|@Ti#_`D0_Oin{*+ z+9Vm8=bs~nUIr(8*7*lef)bO#ZxhsQWiUhj0es%Rl(B$adGSLa@QKE6;f2Mw!!E8B z$QJnj>@fc400Sh&!hfd@@Uh^Wn{d8L6}!#i^iZ*GUj6Hcvo%8;yroXIq$Wz4%Y=n# zdZ7uvjFj}ypuSMGZ~jVV)hXxsO_(HAEQ&bzyil^3{DBzrd}|Vz5YzBIioXaZ*IZY( z{Z&rb!sgn-x{Nsm_3FDWB5vdfOlLeodR|v zpvoPNt5~T+7a(RI6jc6|l8wa-Q^URq4-`3;v&d-j4evey_S+y4e_ zNSR58eJuM%1K_z2#>T@}ttU4yK}x!F!ABBGlY+p2%yhjimA{!la$^SY`1V8NF9WaqwtGWh zzsD8&tM7C&!Fx0KTSK&0;j)euDP}9$?aTW2HoC7Sb-9oyEs&91h?{rQSuYy{upY~@kMy{g%T9AZL$$j0E^+%(9Be-=`1}fuL z!X5ZhldOHh-N48_?x>EMl{LrM{SHYR7KDN6(Z}gR>1$F5ys|HJTh&7tv%4x7^ejg7 zu?|Gp1YTGH@a5jPD>}4;=CBNctX&Jf@YJ*EmzVLPq)1{D%)J1;V~44FkF5j?QOg~k z^w#W288C+>Sa7^T)rVtX_tXE*N9SyL7ksns>BHXk2y3vleDx~L99Q0Kl7EZQp;C}U ze9F`;ZB}#Pb=wEDV+Ahj5y6QAqkb}vA3u z*5%c?RyIP~KGD}g4#wRgu)MS8-Ny!OG8G}g#ap+#PxH1w`1 znHPa1Q<-Z$PYxJClBmix_wup7IKdgTVM7j2q?4!c$mn+@qXS(iB`0O#jc+rQ^K+$A zPTV{PUGiVfpbx@mt=L3I66vw_B_+CnyT_8wBCm%;m5GQzGHjAWXkYP{u#*)Bl3N8J zT0Num#TgV{=^XUM)9m463k}8Mv0G<+b)?jN26U~9R?q1Z_-(foXp#}e6u&LQz(j5Y z??ytkSj3x>U5qkCh^kWQtUcirO6&)XBg0gA0_Y=(B|bQNQ*pj0!tJ(sPNeu0n(x-Y zBk!KtzBG#G{EjiB%CTx*!jH^l9K(qe_83^mASmUvrKiqa>46U8iQ92I)sXe?HrsEa zd>;V693vHdNF+TzED$XQ4Y&A;?MM7=I>~sYF=a^nC6BmO!1ZVS;#jrct*^+ZT8-@^ z(g-)BFXK}!5bLiK=ez0LzfWxyibrzckPoaeJ3fZOn!o7e?AE?bS3OD-oyqR8b`fR! zUgE<@OBm(R?j~<^nhfvD5<8w4rB|W+E;zxbc~tB{xSWYm=We}I{{Zd3#oXy!_Pv+@2&z&({{y(Cbi>8~s~!q&Qtf_>qnpES6wD-MMsZf5 zs)W|+(jB(JpYg5e6iA?u;cgr?bKb{PHo=F4do;8#5dt|9B_WAzO7}{EHYM%R?@qx1 z;B#3Q%qWnb__yF3Ll!OTh!^Li*#>_%7CG2x{3ZDCpUDn`t*#?RlE-u$N5wneIKK97 zP)19(;_M~peI@l9r^xU5DyN@Pp>C;D4qt9eyMH9UhsJc0X%>Dr^NaG0vYljVKQ*N5 zV=9(tj;(YW44auRgBFLk_NtI^>N$iKS_;dz8Y3!3X#=_u(~aT#HM-2?j_r)`H;ACq z=2Mym#pUMyRrb}o&sZ$rPdRa)ca4lqAGRxh`UjxA6;=+v?=svyPTxB36BRq2sE9}Y z+$ik-L%MabTEIXkN{@5JQir!6w-I;gnm(~B%APTV3@s+&|03&uK3o42zWpbCBL*@t zLilC>W7M_&7g_&FAc1%C8?Y;#zMYC1k1cgzcpu;@n6-o_C!t%GzMDPsyfynCvrYco zHNBUu;m_f`$pv+4d>`6gwFT2owMm^E(Q93kt;jD*Y>bX*cmv(ZigtvX(<}5gFMCUx zX4O^ArXx^R+SO2O4W?goxYvuF7h^Ml+wpuN{e+K`r!NB(2QhK2_%KGAB>1op3_Hi) z52H&Y5`0Mnf=+c7JsJs1*xekuWrxNd33jd$AwEftB)ui#v3rI?4!7#(t6N|Y_@h64 z2A%Sky14HXcxO0ggc%*G#H+Hp`ns={`WHOJcU?0rML1T_R=y;%y!xXkLR8yKc*7Mj ziS~8NU#n8x)XOH_6}25zY1_QW$QUFFh(r&P=C9{KNbDOzon=eF$>T5Z*)S|8qTQIG z>;=cNpEq1yuudA6=w?qTD;S`1rED;?AkA&0cog*B2q%$az66As4Msaswk$+RP5?f@@w*>KKk1tK$f}u|#Cx&ig)6#ASw$;rk(Ds0@x9BawV=eSXu+l7OF0+dn~5=RCs1k!a0!_ z-*97kV+dU>Pm=HnlQGAIXC#pV-*7m>k$MQEwbB%Ec%2kZGZFpHyRu}%&Ct?jR0Wg{@t6~f`+nsVDiP&@JgaOC zEzk^V%lpD8=QVm3@>~?Pb<%e1pu$lGbeC;A@rgf?X+OW6TY3m3*xZ}tSMF4sA%;1d zg7Pbso)js{d*A=@u&{(@UXo91cSYhV zUtHtEz~}q5KbHH3>D!m{JM_yyk z-aq<`v$zaYk|wLPk#25fE|Q}!D)W-QLxy2WY*gA=Xuv2Y{QmGYT~=Ad_cAYWhT%ht z@#2(<^X)&ngy;YJXI&Q83mYZfSLq_4bY`WO6@D47()ZpV|1=xJL>SK1i4~GHn>8EG zr7J#P7X$xU7D_5JJXt%QMWS0}=BQgaykeu0Me3fUcBBg@fh4Jq<)*WD6MkZq2Su@Z z31E{H8N5MyE!>NTUNZgV(yh`dCDE-+XH`i-j_tCPvu#<$lR$oxKp3-7vHZ1S0!ZqB zUN2QD;rGY^Pga%8P?}?pZG1Vz&kZVVXOrcZgd9$k1`g39M|a@$gF^mK9WOWkR_j)d zLb4>rT>>y9{dAfgv;;Fsq}_t zTNHXRD0bA#OQo~;koWkyU@LdlxPN{Kkz z!roQS@*b5(A)`?(WhT%QyfhQxA8M1Ogocl5j0g}Oc{`b9a1Wi7TgAa#%aO7wiR-!) zR+V_rN80oQm;&v>1HY-Hb}RIwL&2*yFN>`QJ7$I3?C* zb<>{8c3YSCu(GDCg`MUg=L=eT%WXo87lc*LpY!Oxvzd@<1X`MfCGdqXey^)pj0<%Z+<$DU&auDTIhfSogXC_GLCV6 z$a3^}1bBkKNl}eUX@sK_R^)mMeeX=m;x1FxPL-`6kLs-2aPn!gXo&SY-W^2a zBSY=Qm4ad938)z4JQ^t_z6q~S9L9n@Wh`@1tOi)!L3r;wnA04|HJyGT?Ba80?Ex0- zzxel!Gx1RTsHA-DV%alZ7=tbs`&^M1X?Kpw3Fqq}&6+Te%cz-e7R)HkSz?#$#Y}r& z;(npD1pEID>NiB?_BQa3)HwM#_1EG%mAagBwOp`PGz1y{V|zlP(f7w(`fUG?E4|9DV(d|Y0p z&w)HJ_Iw37@Td#nrd(Y#p?wZZa{P3zg`tVbVdrm`B&Ed|G~L=TrwsF?)Zo+LS9f(s zPGW-a*2QL1h~+tlb}iaegR3{lWP(0mFrZbla*#DzU(1-Us537C>H3lU1e$Pxo(SE% zwz6GU022jR5ThvJ{y{z2effvc{CudD=XmZ1@X_|e3R>ktfU5?z;D+6x@ zKB>Cu>(SsJC2YWM&d*$z5$Ke!Qi#EtbQ-zG+9_ok7vJcHlU|MGHj035sI(5`Np*^G z%&;ki2)x;f=MKh7dxlB+OAvA!Xz;fm$AMcog7bYDpziN6bhF?!#Sz}q5J%X zDFBMtLF4W>2k%pibWSjO2(=`c#pOy2$pZ9~7`RB&s*Y97J&WR&0k>MoU^muwWC_PmQ6L=sK-W!e$qeJVi z-x(!tjaCQP7)0PyIp%aQf8bx{ofHwnpK=aPg`%69cTaj0>elS9rq;xfpz!rcrxZGb z1i$wXZ`UBZHJ>Sbhr=$mWcDL%*-9-lQouGLN3=~CHI*?QHty>vywlYkZM8IeENNXY zOhaisDj^xqQTK{)f#deu4#?7^V_`>RG&k%GcapG06H#|FUApwc0s zN9rE)PsP6CNAnBekU&AgW7FtaBDL@Kj+!C0W(&;W_rJ-0Kw_q$^>54Y6z4+cr zx$pf2`fe|^eU_c*8KLF--)}J}vFU3?+0@0i zhNOp~FIU1^&kG}usp7MUFpiJiE0sBwr{pT=B^XZj>}AjxjFV|pRV2%MThURL_?)$` z4c1^^xXcDR@7@#ZpXCMiwD^QOl!Vob4h$$S<5*qz66NJHCGXO6SO>+E#jEpkelUji zs)o9An?b^^ZRj<9;TX!0C zXCbhy>jf2ck;E=TBWn9Gxz1@eR}uZ01j9!KFkL?XcV?5U#avkPkqqZ;3WX6x&W>g+ z$>|%Vwd~p8r?M8Gl%sQ$GB8S%L;N(?Pn3x?6YZ~+7j9WU`jj9kaMEsMCe4dyAWjO% z;cCTJ_h!na!-uwr!>FG5)EWf)AkkdT{(!c7z@G#s@KDpsSbH9wwv+8En#z-S*V@`| zs4M)wtSghrS3Z%y`JE;<P$KI9x1ywVNqmU$iG z;LOo}(05{IZTJ>Tn5ym}B|U{8ep67A$MEb0TlCjKF<|$V?aO`+^|;R^1bRP0oPv~m zjKwJy3`R*NMSn2JzK*^zb$x?cjw7c|k2Jkl(jKz$5?r9WN)?xU_RGBKSN3G zK}Jy>7Oh4ZngHH{KPD19S59 zCm;~xcZBnVz}{{2Y}|h=rVWq@8mUcr_k8{{wWttg)9_I1{H|a+WcE)T#Q8VITLX31 zAKeu!Gv5IydLI@F`~vqF!;6rkp409p4YqYq8;N-PMKOB$({tH9c1LMQXV&NsB!4vt zP9nr;dQV_3#oFpsG8q&et1)mJrwC|3@p+TJ0k|B+T$VfOGN^XK;Duqm;m$PR*8Gus z%_d6x*nGN$GtDMHAA}bI`xa=_6gY<-uU3(E-5Nh4q_WzpnmTDwr2A`mgu(GTd@Wi3 zoOtRK=&-8#R^Aw84m13e?jInU&b%JN0vdy)ecneO?VP+yz(JoMd4gNTv4e(wr>Lx%wFXu@wJt4t+}Pb>{c zn>EH+sMu|!QqFHM^S957clh@BRPH^pWGc=xPBX)h27NR^sSVq!v;F>ni7G1B#k*l8 z@&cDkFJ!zI@~g4mtrXd#lM#OH34F&`)Lq9VtZo({G5Ad zQ;QyNys+ASWm-6y+{|n1nd64ANJ!&8Wa%tVwruE~L?`YwUtw_2!j?X!YfG!=HWA~7 z3$9)AxqtecFw<^OGZ_F$f+H^+Wc8Bz#%*3aElLOmI1y;PIFmLDpL3e$~1noIc86$oukYY*CxTYjGHJ9&xm| zjPZeUE^nW|1*54M*<5NEV#;aSUc;!6vfwL|>j&vDna41Ray^>&v|ogz3&*WjAQ1Kr z-i3ED8;X=)=We7xY}mK}r~b0c;}l4TAhB~pJ?qu)^hN|AJ@Y5+pGV~;F?~5H)lV1n zuN@7oHHaym)867tm71p%Mlf5yl`6a4q@5tg)u+7;X6SA^K&8Nwb565Ye@|T%=d}Ro7TN&qfj+$Qi_wmbCHZ~~#YUc5sq1cRui!>gbb&Hr=+T?%HWUrc;h=SXem9IGT z6d*}0Z*WTt1^WwC*`h`d3F(HaFkFD*W_g#%GCc`~-hm0)i1=az?fBvPePaq7bPY*` zB2kvtb}`O+716d%1@WYRL>Mz(czG%OP5yyD-b8`z;%}{KUYWP(RMW-NHo%uePMKM> zKi<3Rg?nt!+N$EZPL?!S^4(`-a*5@&iq;X6U&{`= zokl{NA`7{5!fjk?JA@__~m7{_7W9nU4&LAz-8?dm4H+swmd!Rs-Q{Zqqx_r^>R!LOeDL;2N_pTDih+;%F3`g;oh7t}9OJhI9~t)`#@=5O@bLdKIlW zFJk$*@ay{q`Yc?=lsPWxiV)dzO>gR)U14V5!BNBMv7}o)h76}Ad@%x|^r*`#nrHydt(?$QES;)?QdW3MQb!Z+182@cwm9EHS_=+eg&6Gkx+ zMu`(?G7OgD3EU;xz0ILkF7g9v{9V6n0U|y|ZF=86jH=<$`pYPTF>J;cH=pjJ-~DY0nSYBZ=4oz@G`Fx+ z;bV^)DvW%VJ;mgnIjlE~_QJTYU;k7Uobfg6d+yF+cexte!}`>i z^T~n`xV~69<|~vbVAl5sNYd-d;iMIJBu;_3Kn|c<^WwmHb`CG`2QQ?BGo_~LbO}A! z;);uL|j}S6g_}T3WbzHFjQ2Ur0c9H9YAJD!`pFY$_5m z$%RKT1{z|44&l8^gWN*fwnx#&GralBQk=4_X+KR5*46>QPWxfTGN52+cIhvCnZy!c ziBU~Rzf_KnQ@=4*iUheA6ym9nc>1zIoJudI-$gM+$ZDVh*%ri6Nya57tN*CV<{$YB z%(YgBa;WvuFxb|5)-5yyZlW)75LWB6cXC(dBmCVun3Tbg!v3^z_4?|HyV60a`q^un zGS(!LYlOOZD}6zF%|^J5ROwQz4s85gA6CRQ(3Ig-E#W??5VJ7lL6Q_r_p5v1qWC7> z()K{eY~?9pqTEi}SS{?s4Wtik%hZ`V26e^li%3#VA}LB!d9_5V_By#6;1lysTW;Ab zvH4MKbSJK286Mt*725dY9`k1m6%bx^!5>;(S#4cv151TFzV6RvuQ%Q{U}v=rkJu-X zv_`L&T>5$ra;%IIAPOYqIuramq`D?PlsY0un%oNF!MNXlBd7%I(<1U19MvrYFjSuL z5y%t~k6f^MPtd3oHkAJWTBBl*_Dmc*^aew`AmHBX^>A7Zt;O`gnDJR?WL+ zEo!U7R=JL<^YzJ|Di`3dE?Roc@9>H$^Np?!d&a2bvp^Stsxz%}*tktNc0zitV%L=$ z807F&mFh9{W_=z~tQ?f{he`5R=I=eB!OfD{FrK2eAKCdL5x=vTFz0RbUt1}8ykImf zO7W2BQ{ntG->E?(O+87rpv)8=(^|0i4-hK_8hei%&b)yn1%Sr1bFk&zd4aL=zyoiY zSUOdCO~)4sDzDCBNg1z%Yy*B;DNZC|O0}bD$?hQ#97QaxOa6RXLcVPd_5O0*;AuukV)B8&xo6pCrJ%lE7~aS2 z3%6_aMuGuX`pc}RCA71V=#>G@;x`0Bf`u{9?+yV!dxDv=>}T~6Y#Jh3BGXCy8ecOD zNF0EapXpZu{f31cE;wEYJEeV%JYNiqGrPr`MCXw6dnTVdID<@9ju9Ur8=AA@2O3%j zblCEA1kiiZV{E5;(})`s-CVt^&{yZUY=NxFz6c<>H{BHihukVFMEP9dlPb09c213Z zqZy4#gJS|gy2&u1RgsZHKrb{ei=9Tb*$WlyfH_RV$;zVtmY^o{OiT=cV|j4D{Wq+r z^=;s!&Kg&#SyyNKF)%x;-?4z9Tf4>*;2fx1{%GHROaG>Th&LynAUumMF~ju5?C9QQ z7{xrvQ9VAP9*P3*BzER%fhuppX{+OE9ki+Ulj9GE@BScD!0Nipid6RJqm8zMVX32H z58)4&@~^l|=}L3%8E)jmtr;b z@hJYAc}EIjV3N&-05$T_GS-#p4nZUTxvo+ltRTDZ+mVUkQi-=={_0wZv;{>Gfa&yJ ziT^_j+Xe$S>Q_+(}CK7x$5rqlZPE_ zPfj;8gaBw8c1F}VZ(h8_Z0zHY?anqWwSTm}&dNp2N$18v#Gw7Yw@`wl>O+3eDM5Te zef^bC;DKBvzguDnjR+1}+PKEq-MnhssgqlZw4Gv4ST`jWGbhdMhhN zilP5hlJQE~>K(NwiBg3-w_>H=^(pwn@BRI_1S}2D$32P#s2zMP^hF6*8Q~ye!Qu9b zH&XbC3B{*wVapKWgjnPBi^fRF?cg1(qd*$4ajSUj?Q(!kDr>d4gnh6^7!BWNrcWcK z>^&1Lxb_f$Gl5=N|EzBHAJf3eX3k!##0~Rk!2OD&`o4bKa`_%HYt>i{S86~kk@2ya z#He_ZH?k<%@`&$9Kd_M}xx-eCVoHhHq9fYy>RqMMLzn)n%CR)klEL5$iak)c4*ga5 zGPZ5W3@^wh`@)g7!VL^U^tz|~>}5RqSylbY}#i${juSvvD8^GMr0#E_~p zIj&7-!SU~qw}Ueh0DSEm)%IKl@(u-thIXKa$F>ec+6A&Mg*2;iotpQZ;D+5~P8h#H z2->v}t*-5{B;Fb+nV%{!LFNNQkvUg?%Rmtd zwDWTWLT2TGd9l#?+IfN5OlZM1&tJ9h)nUg-g}NAwg3z6@ms{M#^X^IQek>5$+ut~7 z(btm|&PH0~u8b<)USIE`P)~lWnf{oGn3=jD<<4ctEYWsm2$=(q`uJQYbo~P`6ZGsV zhNQhj!*Vcrye|M#_dYlLocV+gVF_R1gnMfJ5$juy;IB7l)Cpkb?w8@a;no5g0$>dc z3|BP^Ndb-X0aEyI(2+AQGIR((G40`lRAa9?V$M=o-UXT3C5W5?b)Jd|N@B^*bP@}$ z;^pvnyXxOJ>WG95qk(^4V868aaDh4o?{4gd_ab#QtV4M1zK?hBKa<2R+Z8hDvrP$A6cTfApwrS@(l}-YLAbb1Lmsd9BtjGElf0?cAc>$+-UlvF%mb;$ zCu~ii4We@5*h~O0J3+pZ-3Gpdh8X4aFtNM zf{N>H8OVYF>JZ}jE4(D6DfO((c|qDNJ#XlLVFSq_JmMh7G z8PDm%2$DyyvAOFEQejR{n&1gXqg%qPM0(Y$!50d8NFej-qY##PTTqk;wo@^|5OA1@ zu$(DZ<%2lHw4ox4<+?JG!gliNm>-%HYVqnQ`?$rctnF61q0zsH3w62Kf`1vuZfQk4 zYTAMif|p;{)%$TX;?{PBopR@4BFVHRxCn)Z@+j_-LRdCjkLu(utooeR_e-$W?@?)+ zNGNHG;2*j{3D21O^+!Iv-F+@s8NopL!IisSG54J)Q$4#lkZrS&`xdKj_Wi>^+Z24E zD-2+*XYjV7NB>c`TIoXBue_gfcCy1??!fYyu%I@eGs!$_ZV%aHn9afY@~IQa=5B#v zp;E6xaid@7pQ)*y{9tf8gXw)rMebKb_0v_yj&t-gYq_s)>$$2*YYq3EnnepfwuwoI@;h=|MK%BU zx1TYL0m8ld-4J&{ZsjJBa!fIL>(F#FCXX;meQp|dHCC$Ys&Xn}%GM?ekS~Vi{p%1m zrQk|-8V~-ecJx7^nSsmRyWaEq>|N!)~1^IG}BPYo5xf8tGZYa3&o zSNFSNlxagM2J8IghDLbv&Mb@w35O8M`=$r+RNYkjQDhgOa#RZ0^}&V~A-N`K*)@b{ z$Hm8TXQ?+uYWr&;M5L#@hvAm-tZuc`-05A(XAy0%m)%btQdMQ0#P2Dd>qrXbHkj#+ zgNtOwnWF382m%%&x}SF1Y!uYvtzDlf_evFIJFzHst|IsN`8{+a=DIv}?J{p;ba_m~ zM)hi+U@gWUYX0*=^-uxzU6PY;cTfM}o72q$QaiPMHy>r~ z`)lj!aZ&**-mN7yH=!nfzdm&5#&G0++hNDI;ph=L>&2uu8$j|vrxuDE{rMwYhItE=67E7;uvx%7 zSehu-~K5~bW{@Qk-Ob82pPT9?s14P9Zm~T^rXNmd*DZ&1RjHXfF zB*Xg@IMu{`Zqy3vATVE^AOKoCdm!}>kfuW>qm^1trbOu9%X*YKMSmVKCLXvafo4a3 zi0n%yZL==YH|=3g_?;3npF0GtFfp#>J@(6%HS%5R4GDkwUVhf?&h?Z6 zyJuTu&4n>>y5l-x%K44g@r=t;(Saj*MEzW^v@MYkZc~?U{Tf^6yYGqH!6jcfRq#IB zQAXV%wk%19#=9C+Za8y*CQvG;#Ih^rZg;!{O?unKg8MIB+aa1BI9K5rnuSa!>Qo}^W6pZ)V%WR+&A3@~z zGL&?ot+npcNSN?So!I7+pg6?u%}Br37tvx(hFqqDT<6TDF9ynMj9MaYi&!gCB|x*U zX4aRFgF0?ipJ)F%Ka23be0W)=T!YLRdyqx#$rDCGdC_0)4&C$j;Wq&Ias$PlZ;%~I-)3x2r z(Vn(4^zoO_w$yQmVOFl2ic!e&mKlC{BxiYnSmp?{F;8zB7R+MNu%UG{ZEskwhc_ts zm@N$|GdAOqWPUypbWeo+h+23)0|v6z=$6?}YtrYBCGon7Qe09Q3>WD~b=E9Auk7Pjg8MUm3I5WodvSy`o>umE4V8o^RP+l~8+e-rtQzj9i<`S4v=HWQ~Q@hU?)=rEedce2sz%j1IzjUR)9 zNpPi5lJN6woZ)MLli2T@dWU>tp5J>iW7{AG2WzsbDDNyysEH%aTuKQ)RH%=S(B)1P6;p$1E33m&{ zy!CyYz5VGBI2&!6!BCl3@JH+wm^p#E@s>%K3zt`8t~%4s?NkLpkgjjalrm)<(z;l%|U7Ti-xwSnkF_Y#=vVMumRAZL z|6M{p?ijHz1u}T%lHlJTfb$4!d8%*%C_l2j4X^OiwAlBkEUNhiHP4hz&&B3&_wtOJ zub}JxxZ4RO)|sg%N#Uoi&7j2W+bLNbs};(eAqhKhtGoMRl+Ydcyr+{Knh$uPLBU1t^!vRT!};cEO7b;6VUy$fGi^h^n|kRa{~)J%uYG&{^Bgj01)7*n(&fbBI; z<#t$Cp1$*7m3l+ko-vawU)E!bNa0KNi5O~SgIO^g8CBprTisUvDOTw)TnOxkRc$9- zkqa1l8r~%~c?I;fUQw1f&Ha`B-mn+fns;NR3T1vOjb2O2D(96mr6QEaLk-%&0TXqh zBzZz1-M%;ZuQs_SQJJdw?h1jmxONgXr+Y`zKD-cT&QUKXyN{-O387jAZERtj1`Gmb^pYyO%i{soOB z!Ny7}k)VK22me1lgb>*d0UC42usN7*JXky`n!_#&gKKABifZ#!#ZwF>`QtUDHkv^!mz! za=Gdm0)!?1A;N%E$Hq?D4D#$7XE3%DWQ49R|q#->DxgPtjQEff`3pW;9TZ=|P@ zlNMbxloV2%Nye6HIQwmWR~=6H9ex@EtG93)iSM)fPSYV4uT<}dyadd1s+uThxYqVA zY9Hj73{7JJ_Q7w7z{0c+F%X-2Ml=7+R+CD9e`;UHSc*T<{sZb84IW1a<&EBZcm(Jz zM)jugK4xDsA&y&NL{gWl$DlAfZu|*cfR8f0;Sa%Bby?hpH7TB9+yVTv#*y2{v2V>L zTs_$G3tN~YxwjoXPI>v>2)_FjIA{V%<;{IW_LJ>e#Ie0V^1wxHYYqj0?3<1f* zP$#&ioTz#SCg@NcD0K;TCG4egvn!nQ&CL9(iGqQ(=t{NJUB3@KUzbPlv+5%b-S7Bu z8;rvpKTPPnOKX@8C)D>lbyUz_ctc5jO^ekz&hO+u*z*?{7KFzyv%+E(dq=mWvqS3L zypSa`HB-C&)b#*oyg+MunMjiRH%$!08eG%hU zqjg>a#1^9^>IuQG)u%}sz@3rnXw6S5Mat#V&`MMz{Y#fVQi3G+KUdrnGz*&b&wK{% z2RHw#50DVXKilU3DutyX{xa{t7Fo`{cN^}I+8v0!vePme&W>YjwMp~;Y$cbjf3kj#y8UvgIchFnCM;q_5}K7Q!oKDRP!fPQ9WklM zm2^b&zChhDJf=+}I9=IaM*n2c+#YbTMUYU@2*C3lhipQ4oS7CRX6zJj-)gJnkv(G^wIi@Ze8Z^B z^vmk{ln<8NM#yu=VoVjTx8DJCr`M%v9)KKUIC3!)Xxt*Ma12qn<|tPuc;^7eJt1t2 zol9*8!dW=w#By1yyF)y4S`mhtnYK;gT+$y`H%|> zr~j`3f50Ep7v|LgK{l8DVyp-&a{CStED%&DcRT+MfoZB_A1OU__h0&VzATdq#W)jUj0C{(~O8ya4A;{ zJ^n-ELk-P@MK8M(wg1?%xl1A5WGlk-Pn0R;lZwt~TS_*uzXOAHR+j-U7aW(gdZd-` zUVIT_vF^zzyN1ufEB^to-mf7acrMAE3;1yplc9fpaP$2*mOLGf$AhVc+j#AlrRva6 z0m9)QQ2s=T$6(y95ZL;3Z0R?#vqGzf{3F|cTK~|5SsT+0)kA8vPyE6i9IELNDLh9@|ut0Z1uJ7gqYkwc6SV_+%N;DYJ&SgFW><{gr?4VVu=LMOj#*uBCH`I}b_`mO; zHh71zBn+-m&2AbI9b2=<-J~SneoDf_%IK*5jP&?6^4Qtqn$oU$Ewq32CCRZ; zKH@!72r?}Xvm*f|Qg!nIjFv4~93)p}OrWxWxgQD>{>s$DKwQMe9(J2IDNoI?(;vkL zT#I{KcpdRu=5?aQj%YVkV5 zA>$iHEBzo&hXD%z*2~?*Z_552Lkf+Zf&D0Tgyuv({G~EAA&@}NRCbb$i5&2Mg%}-Dfg4P5i#)MWl7qg;MUDb_iHkei?}jHAwDis? z>Q|FgB{J+ zhg(~v_EPG*<#WUkJc^DSXby&3L|AKG-naz|gr1s)< z_j6Ko*RkDNgtMNA$#KqA2`eJuSCg_vO|hg1z#3`7o+HzUI|e#=35K1vo$Dvz;4>b3 z`knnP`$ z7}(u@e#K&bQxStMXlG& zcg^ot<9U+WFi-u&Z;fXeBXCS|nC;36RIM3)s|Ty~qg!vmgW8zZ>FpjUqThxGDh^aL zvbejxH~sCS=BT@2N^{sH(`<`Yc}aTj0vXLT#+iSRIzZGKVC+r0Ra%C3)f>CZoK9q}Pd zPodgBvx3zsSFu|kB0zq{H5EY5l)Q}~rWQfPD5qzkN$4Z4Nww9R+E17?6;xZacB)%Z zg_efl88moIWGYQ#y5Rx-XI| ze$&V8$A0pf^QeyBSy+5xY34C#!XyD4m(%@64JQ|;(TsY!=w>4mw?i<7AqaI4p0F+- zLMa^=kkx*(GB6Ox0`y0?Z5Qzi@t2?9SW#=|(h6mqM`pF+Jpo=mAm2~}n;sxTEua>+ zqrDXcm47BIBNDqIOn2L+ui*<%Q}w zn~qm*80}D+*~ThZEHAXbwG#^-KJd`BjmYl`uJhVr{`i_HE+$B1yCwn*0Fzy=suW($ zdiXZ|r4<^oWuAtE(s$`{>Mt?eB6Dir@&K#{W=1mVJ4z0gscbMna zHV-^R6@BG#6}ZAuTe2o=?md{$ON5s$FGqfr9%aG|Aj3TfLlYTy*~>LW>k@Rq1tc|dY7^?fg1$>B|;(+0@v*O{i zU?#C;HQz)61K6>?Xp|}2<$MH1Pz_n1gHUr$#=SgD8mKL%;K_W8loC}AC!@3GI9f4x zpbVb(6Cpev?U!El3aD_#V^%EFXXJ{LONj13#}dwEX&@As#-rAZ^X4co`$l1fH)j!` zrwa9m2=*FRaN7miSt~{Hr_I6u00jpJLTX)RTLnh}eSAWx3uR*1g@pHhV`8Ouf4EZ$ zcR4?}X;FEs>GLY{%uBrOBSrX~+w%+8Y)>y~P-ARO>IyERyXQ5N(Vg9U;XNK;@_aap z7o!$E4uTNG8-oLF^bs(_+st;-o!@vttQR?a=239EzCJ$?TB|{I={VJ^KQ}cds-YPN zkG!UVJFvbX!1)QJU1(kJI-1UO@W-UbR3K0PlQGNdakKMAb-Vi~(Aw9}tKznE2WQ=kP z^kq|DWpC0^2;&G(n6oj;57muULu~#7^A;8vpnohlqMFG0VB8@0gDwww?+_W72n?54 zydN-~T`_mKhYcS;>=y+6J3tcJtcIs$)tT)a=f%u?Hv=AZ220{{3wt86!;iE~y|3>R zyY!UXiRF!k{URy6#5nC75PW3!mo2`|Pe+*HO{#E`<;HjDViSl$CsB!BSPI*N%oDxc z`oE+;?SJ2;{UCxT3;XX-0#-wQpYfS!bOZbGI0Bo`h{C%8^b?&DB_i_kkY&oY$?IWptUrAoC^ zP3P879pN5sJZEN2`}c#RPVCd|2?)8Z8nzE1YUr$W|qLJ*vb5GKJid8|f4W(t}% z0p5{sIe;o{?^X08$5a-}zee;&U}*(W%<@?IK#CN5Zcw*M{T-z*^q=J2J)+LNVNfR$ zr9r-jh!D>}%nVGWuP}x!bq#jf7#ElE1w||sT>En@paOhT@d5^Lhl9s*0k~1x7r}~RBoK*?F70%d7pPMb2tiS;4bZMpH!5zoL?1R6Bfp|!hNMyntt-Ny$nLd z?#S|a%td-i95Tx&M~?90kCzA2vl1pUCU2!e9w3!xVGAl~;M8GhI37QK@J0qqdO%Ve zR~@a#(pFXNzb*ZUR-5DT0USA_ULWdPkYoJ*;4-ey+xvvKW@*nkiJzgp>LMx1{o%Y> zy4SDw0;^>o(FzwuRJJ*+8DcIa=bi#(z*S$0%&;{|o}$`RqDU>4Ym`2O16&HYT5Y}6 zUvg&zwqfJ6UFzCk+Aq-~KpWGp@8@N0| z{vnt-ne7LdMR#Q7M746l$#UUAfYb*dae9_fd;;2_8GBjj;rE4NrB!?T*R-`9E7|YA z?kejU)8m!(a7xmg6|Gc4+pp1qMHPvIMZ#S{^vA0XA)}p_+pGjBhtWEh=g&*B3_j{gUghtvI(R=oX4fmf&LpXwCMUYDc zb*5lkTUdP}jCNm0OT6ibSBE@#N#Mmto7rv?lF&VKxHgal@N?Q;;DA>dzv?>ZEET{i zzTgtyJS$i|UTi(si8Vl_(3YQF##-5`m3QZuTAOGxw1HV=lvF!+nX44_m3YhtY|5!u z#BLFAMwC1-n=iY`1e@^=RPU%Sb_1NdzepfU#4!<>W?GUP+E4mCp!Gq1U-d#^Vy#D}Ex<ZS`38v{9JdyA|BHK-KEZus{M02P;9e^F4*6#Bp9&0YRf%sE>UEjk|du`WfGABfSc6t~+@Ho>4{hk1b2 zWjA@H$?!0fh^lfWQhj5}J55__FTN9q+62ZH@!Z5H-85qv@2J6dU=J5Gaf!{|<+-@W z)@g}Qo$h1219L@7?aUtx5awO;DO-X?Alp}MnA{bdZiCVn{fk2zau#Ti5yRC4F) z-oCLi4%q(yAt6i_^M>Hr%Dv^aTYV}EDIBj%3%`l6U`NCLF$fCct6G)@jbx7fGn_!h z6}p^KaqTR(6-Z`RXSor#JfC@7ce&2Fjssk9`GKe66L!Uzu#`QzW?{}BG)1-Td{w{E zA9SU??62}sSFCsBh!<(TF@KodRJZ9aH%$T_hNS~RiYPm*yJLJ~);h9ooOv(t3$s9d zKe@#E#teH^dqFKrS(fwKC1^Gd9?gB>ssoH3#;Dyx zP+U`zQDXK>JBh<7s>G|}4r-C_7AaxnhNtJIJIwbpGIRBU)iU|6Vd*o%M#H?fv>UQ$ z;&NBkTPhH0>a+NmDFC201tEhs>oZ6hKHTTh75E?Dyk|}a(0GVRTwg)o%(`XHPdg)~ z{Jz=tmqm7oP7x~^#^!37Z@u^TnWdLzJ(vosDc%#axPt``OU*^ivJGU<@5CzWU|r~I?*T<}%axf1 zUX_-o@4+u`ohwy;GN>IkXyy?mQz@Nc{LBsHm8(*|%qk3J^*`8%K38D?iphLyF*5W2x}P|Hq{sz%4wE^Rebpa#}4%|~Ib7kGS-?NgNzp`IpY zr5)par8!CTxO!qxT@bG_vEDwcJh8G}^A~l9?3U3r%%EF`7cNC|!yFHr?jE?*eb1W~eyo!al* zl%k9Gls!c#)e?$8G|TAELzn59PHSL)*j9U&_huF5*7p-F@-w%VaP2A6<_1?VZ1$d% zq(gsH5R5{*XFq7sBl0TGi-gcGx#{_ZBRQcfc&SK7B{Sgu;Bz)O?Y0tQiZQLtUag_+ z+xuZ!#Rlso*YrR|A~bwz6G}boT_Z`$EyiE8iUa_qfajY*Aak`uCK_UP*5F_ot$zWC!lAy&q4@qMrycVjCphHDat&XVq{3^giH4=7ez-Yzh! z*ts|5p75~ld_h~RTgUYaDN|lJlt#Iu-q~SzC6?=y_P_RC1sZwcBJ9D3=5qSLqm4ZI zlxI6<80LFQi${~hrJ) zlNU+;v4pTkxX}Boc(uFD#Muki+}vdq=bsSKI92bKCemR{^NVl1t4_=@b!e3U*l1jP z8{=^b8o~E7EFc8Uk)s&&fP?}Q6pCQJ$KK{78v%Y*@v17rv^t^z>>!%9yA@C-$W4eO zQ@Kf=@Pp7FNM*wVS#c1%F%-9G*(i8|g+e|kg|5P)&LX?qyzX~dFudFsSoeno-1I|e zF6SQV6$no2HVOHK#`aGxSnV4=_8-2{H{{TzY3zLcC5VS8Rc%vW)@mG>5jV3b>|^33 zD%WFO@D}m1Yi*kJEje#q2ikGdNG2Rz`0`D#ImhqBK~QO%;}(2&h%KrOsCeak#?sAU zIKDp;)wBJ(ER=2Qx`VaY{9NKEwZ?Mae3`^^o(}dgOM+Oov z0SVXw^gNf75gepu@47NqmTzL6HAZjyox!7#@he4?@S}*_%I$)}(9g`Gl`}=|t;O?L zfPxxfPt2iF*tfFFgCz!icfSy{4=f|Fc{8ek^@pZH`P3HZWM|QScjhqwygy5Z>wB$+ zN(dJGZFp3g`HS0lW(pcplAH0oz|J`{Wm>maPU{`>2-%mLYS+9=g(2bbC}`Qm%4W*X z#7f`NTf0!I-_lnX9N5QKYX+{4Mv^{C?S3> zqZZbVRIcB=2+%Wn<=LNS=4@S{bF81|)*C2bL$Gn*i-j!g1;*2U?J~w&YdLv7myYqb zf|LPP%Ejk6510_a!%J0WAB;?bj!ih;J$@lLOSSr!Rr9hig5>VJTYLrM`(<*{o^LPP z7?;&Oq6Mvnt$4k9r_4$Pq2j9X+ab4|O2e=pMEreb^#(chV-pRRCwj{-q^g@X)9%O0 zn9hH=)yr#J^V{AC+PU-l-USPhtlfk3!Sfy*YWYG^J2C4T)@3sLOZ14`7TrPA)sB=$ z*|Xvl97NZtUui|ljCcGnTXX9Ymo(sDY8^JLQ#76kgR~Ie%&{_A58M6I8Snf-;53w?_5eWQM4k zGNDxaL5Md?No$eRu7~C!`fvyF04*G zK4xOvRt!+yV$UXwZt-_5wwtRXNoFtnfk4nux+pPS^S>~XYz37Z=EFNX?hXWLSnhbK0M2K)a^kLT8P0j@hI~K+koBp+}g$- z6WR;BN5XP(7%|KHP-X%R6FJ{~*Jl#&A*x(+t|bs9(j3w&UkB1xBy{i2DEjt{!FwMW zs;}w+fdR_m%s5-bs2UFb!&omkHrxO~lr+`1&yHmh7iHh3Ydzxx+ge&}8uHitf~=^z zuHmA)u2bG3-wJ25Y;B`>$FAkcP2v0Z^pCiQ42oU~y?B@he}Rkbt--0lYMg`#=zu5T=!<@-Yb*LY0cD zyw*1F0R$NbN?_x@Lo%0;-fs7r@l6u4vq`)NCHxSo<&B6u9CO6Y35thmJlw^fPj)p0 z*srVsrJ!!E+wb{+TI3W9(|NB*8cO9#@Oj=REIZ@UUd=6K$#x_TBb~L9uD)ExSqXUX zdmnydC=?ZZrgwg^v(80pcl|NcT*fNO19|R5ji!g5-eE2U4d8WS#Kh@EITWH%3r#%X!#$j9qycH&1_3 z5%CT-AHL878w%$NnCD;N9<$5sp~rG4WR5=9%*r)DIHsH5qQNYB1fdn*za9KbK&t~) zP4nm7EBvzS0(cP;uFD|@x$Z9RMQw(hOLV?@88l;Au@-dzr@RiLbJQ9Q`q`N zg6sg^Zx{QB4sAzgArV~TedYZ-@iW`&57FjhSL#mW#_-wb`?IyO)K7jNW*=wnPp5uo zBa8cEZ#VSKM-}!aMZ5l4tkdiJM3^q0%u1Eb{_<_;LR%gFrq)@b^}Z&|WGpYDEh zZ*qQ9@tdbFS@jd`pPBS;+@0ZvbN7k#584n62lz89`+gbqljzQM6@~{ePCUNz?7wN0 zrRR?^k%N@p(3ZzBkkjw@ndja6&Tl2k`PA3%_JF=Pe>3#^&#go_8$T0Aq-&c00NFNr RzQot#@etw6KVIEG|JjfH(ro|$ literal 0 HcmV?d00001 diff --git a/dummy_user_data/pictures/Peter.jpeg b/dummy_user_data/pictures/Peter.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8b645b646d66f06b1712dc2448c3d76c5932bf3d GIT binary patch literal 61013 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 literal 0 HcmV?d00001 diff --git a/face_utils.py b/face_utils.py new file mode 100644 index 0000000..0ad584b --- /dev/null +++ b/face_utils.py @@ -0,0 +1,77 @@ +import insightface +import numpy as np, math +import cv2 +from load_model import load_face_model + +# Global model instance +model = load_face_model() +FACE_MATCH_THRESHOLD = 0.6 + +def cosine_similarity(vec_a: list[float], vec_b: list[float]) -> float: + """ + Calculate cosine similarity between two vectors. + + Args: + vec_a: First vector as a list of numbers. + vec_b: Second vector as a list of numbers. + + Returns: + Cosine similarity value between -1 and 1. + """ + # Check length + if len(vec_a) != len(vec_b): + raise ValueError("Vectors must be of the same length.") + + # Dot product + dot_product = sum(a * b for a, b in zip(vec_a, vec_b)) + + # Norms (magnitudes) + norm_a = math.sqrt(sum(a * a for a in vec_a)) + norm_b = math.sqrt(sum(b * b for b in vec_b)) + + if norm_a == 0 or norm_b == 0: + raise ValueError("Vectors must not be zero-length.") + + return dot_product / (norm_a * norm_b) + +def detect_faces(image: np.ndarray) -> list[dict]: + """Returns list of (embedding, bbox, landmarks) for all detected faces.""" + faces = model.get(image) + results = [] + for face in faces: + results.append({ + "embedding": face.embedding, + "bbox": face.bbox.tolist(), + "landmarks": face.landmark_2d_106.tolist(), + }) + return results + +def face_recog( + embedding: np.ndarray, + known_encodings: dict[str, np.ndarray], + threshold: float = FACE_MATCH_THRESHOLD, + return_score: bool = False +) -> tuple[bool, str, float | None]: + """Matches the given embedding against known encodings.""" + + best_score = -1 + best_match = None + + for name, known_embedding in known_encodings.items(): + score = cosine_similarity(embedding, known_embedding) + if score > best_score: + best_score = score + best_match = name + + if best_score > (1 - threshold): + return True, best_match, best_score if return_score else None + return False, None, best_score if return_score else None + +def crop_face(image: np.ndarray, bbox: list[int], margin: int = 10) -> np.ndarray: + x1, y1, x2, y2 = map(int, bbox) + h, w = image.shape[:2] + x1 = max(x1 - margin, 0) + y1 = max(y1 - margin, 0) + x2 = min(x2 + margin, w) + y2 = min(y2 + margin, h) + return image[y1:y2, x1:x2] diff --git a/load_model.py b/load_model.py new file mode 100644 index 0000000..61bb9ae --- /dev/null +++ b/load_model.py @@ -0,0 +1,54 @@ +import os +import zipfile +import requests +from pathlib import Path +from insightface.app import FaceAnalysis + +# Model config +FACE_MODEL_NAME = "buffalo_l" +FACE_MODEL_PROVIDERS = ["CPUExecutionProvider"] +FACE_MODEL_URL = f"https://github.com/deepinsight/insightface/releases/download/v0.7/{FACE_MODEL_NAME}.zip" +FACE_MODEL_DIR = Path(os.getcwd()) / "models" / FACE_MODEL_NAME +FACE_ZIP_PATH = FACE_MODEL_DIR.parent / f"{FACE_MODEL_NAME}.zip" +FACE_REQUIRED_FILES = [ + "1k3d68.onnx", + "2d106det.onnx", + "det_10g.onnx", + "genderage.onnx", + "w600k_r50.onnx" +] + + +def _ensure_model_exists(model_path, required_files, model_url, zip_path) -> Path: + """Ensure the buffalo_l model is downloaded and extracted.""" + if model_path.exists() and all((model_path / f).exists() for f in required_files): + return model_path + + model_path.mkdir(parents=True, exist_ok=True) + + print("Downloading buffalo_l model...") + response = requests.get(model_url, stream=True) + with open(zip_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + + print("Extracting model...") + with zipfile.ZipFile(zip_path, "r") as zip_ref: + zip_ref.extractall(model_path) + + zip_path.unlink() + print("Model is ready.") + return model_path + + +def load_face_model() -> FaceAnalysis: + """Load the buffalo_l model using InsightFace.""" + model_dir = _ensure_model_exists( + model_path=FACE_MODEL_DIR, + required_files=FACE_REQUIRED_FILES, + model_url=FACE_MODEL_URL, + zip_path=FACE_ZIP_PATH + ) + model = FaceAnalysis(name=str(model_dir), providers=FACE_MODEL_PROVIDERS) + model.prepare(ctx_id=0) + return model diff --git a/tests/test_face_recog.py b/tests/test_face_recog.py new file mode 100644 index 0000000..917a362 --- /dev/null +++ b/tests/test_face_recog.py @@ -0,0 +1,44 @@ +# tests/services/test_face_utils.py +import pytest +import numpy as np +import pathlib +import cv2 +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))) +from face_utils import ( + detect_faces, + face_recog, +) + +APP_PATH=pathlib.Path(__file__).parent.parent + +def test_detect_faces(): + # Test the detect_faces function + name="Paul" + image_path = APP_PATH / f"dummy_user_data/pictures/{name}.jpeg" + image = cv2.imread(str(image_path)) + faces = detect_faces(image) + assert len(faces) > 0 + assert 'embedding' in faces[0] + assert 'bbox' in faces[0] + assert 'landmarks' in faces[0] + +def test_face_recog(): + # Test the face_recog function + name = "Paul" + image_path = APP_PATH / f"dummy_user_data/pictures/{name}.jpeg" + image = cv2.imread(str(image_path)) + faces = detect_faces(image) + assert len(faces) > 0 + face_embedding = faces[0]['embedding'] + + # Assuming we have a known face embedding for comparison + known_encodings = { + "Paul": face_embedding # Using the same face to guarantee a match + } + match_result = face_recog(face_embedding, known_encodings) + assert match_result[0] is True + assert match_result[1] == "Paul" + assert match_result[2] is None + From 5cb2b39160cda40ce42826d0513f68069233f26e Mon Sep 17 00:00:00 2001 From: Zehen-249 <1hasanmehendi123@gmail.com> Date: Wed, 13 Aug 2025 12:22:06 +0530 Subject: [PATCH 24/25] Add mising insightface missing depency in requirements.txt #52 --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index e98ebe5..9f37db8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ playsound python-dotenv langchain-google-genai langchain-core +insightface \ No newline at end of file From a8fa8985659eee596dc153d128fa87e0bb845b31 Mon Sep 17 00:00:00 2001 From: Mehendi Hasan <117719513+Zehen-249@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:29:31 +0530 Subject: [PATCH 25/25] Add app directory structure (#54) (#55) --- .gitignore | 70 ++++++++++++++++++ __pycache__/config.cpython-310.pyc | Bin 225 -> 0 bytes __pycache__/tts_utils.cpython-310.pyc | Bin 1610 -> 0 bytes app/api/__init__.py | 0 app/api/perception/vision/__init__.py | 0 app/data/__init__.py | 0 app/data/users/dummy_user/pictures/Paul.jpeg | Bin 0 -> 39784 bytes app/data/users/dummy_user/pictures/Peter.jpeg | Bin 0 -> 61013 bytes app/services/__init__.py | 0 app/services/authentication/auth_utils.py | 4 + app/services/authentication/password_utils.py | 4 + app/services/perception/audio/__init__.py | 0 app/services/perception/audio/stt_utils.py | 4 + app/services/perception/audio/tts_utils.py | 4 + app/services/perception/audio/voice_utils.py | 4 + app/services/perception/vision/__init__.py | 0 app/services/perception/vision/face_utils.py | 4 + .../perception/vision/gesture_utils.py | 4 + .../perception/vision/object_utils.py | 4 + .../perception/vision/scene_analysis.py | 4 + app/services/storage/database_storage.py | 4 + app/services/storage/file_storage.py | 4 + app/shared/__init__.py | 0 app/shared/config.py | 4 + app/shared/logger.py | 4 + app/shared/paths.py | 4 + app/shared/utils.py | 4 + tests/__init__.py | 0 ...{test_face_recog.py => test_face_utils.py} | 5 +- 29 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 .gitignore delete mode 100644 __pycache__/config.cpython-310.pyc delete mode 100644 __pycache__/tts_utils.cpython-310.pyc create mode 100644 app/api/__init__.py create mode 100644 app/api/perception/vision/__init__.py create mode 100644 app/data/__init__.py create mode 100644 app/data/users/dummy_user/pictures/Paul.jpeg create mode 100644 app/data/users/dummy_user/pictures/Peter.jpeg create mode 100644 app/services/__init__.py create mode 100644 app/services/authentication/auth_utils.py create mode 100644 app/services/authentication/password_utils.py create mode 100644 app/services/perception/audio/__init__.py create mode 100644 app/services/perception/audio/stt_utils.py create mode 100644 app/services/perception/audio/tts_utils.py create mode 100644 app/services/perception/audio/voice_utils.py create mode 100644 app/services/perception/vision/__init__.py create mode 100644 app/services/perception/vision/face_utils.py create mode 100644 app/services/perception/vision/gesture_utils.py create mode 100644 app/services/perception/vision/object_utils.py create mode 100644 app/services/perception/vision/scene_analysis.py create mode 100644 app/services/storage/database_storage.py create mode 100644 app/services/storage/file_storage.py create mode 100644 app/shared/__init__.py create mode 100644 app/shared/config.py create mode 100644 app/shared/logger.py create mode 100644 app/shared/paths.py create mode 100644 app/shared/utils.py create mode 100644 tests/__init__.py rename tests/{test_face_recog.py => test_face_utils.py} (95%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..70f4f7b --- /dev/null +++ b/.gitignore @@ -0,0 +1,70 @@ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Virtual environment +.venv/ +venv/ +env/ +ENV/ +visionmate/ + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Model downloads & cache +app/models/ +*.onnx +*.pth +*.pb +*.tflite + +# Temporary files +*.log +*.tmp +*.bak +*.swp +*.DS_Store +Thumbs.db + +# Jupyter/IPython +.ipynb_checkpoints + +# Environment variables +.env +.env.* + +# VSCode/IDE +.vscode/ +.idea/ + +# macOS +.DS_Store + +# Windows +*.lnk +desktop.ini diff --git a/__pycache__/config.cpython-310.pyc b/__pycache__/config.cpython-310.pyc deleted file mode 100644 index e7da09f9e38944b1bb9f97f9bf88ab98bf48196a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmd1j<>g`kf|i{VGO8FE7#@Q-$N(tD-~hzMJU}9aA&Mb|F^VyTDVRZ%`4&rhNJwy% zLPkkRft9|#p{0?Yp_zrAktL9_w6ZX;Fwif{Oi9i6(`35E1ymXD>gVq1=X#6RGax?P z)ydh>H$F7TXC*@s3(#mV@ykj-v^ce>SU)=>F)uM&-zBv;yClCrzcjBTvm_@qMIkLe wCndE=KPPO2Tq$;BWuS=cyO0Ol<@CjbBd diff --git a/__pycache__/tts_utils.cpython-310.pyc b/__pycache__/tts_utils.cpython-310.pyc deleted file mode 100644 index 9c9114e13eb067f968534b7a5c20b9bca60ba2b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1610 zcmaJ>L2uhO6ecNIRutO}+OBK690(tVXh3Wf-7dvCtlN^UhZzHswy1)_P)yoUEl~nV zFR|bh1KP_56x+QB;2if8_E&V>X+L2*bbF+oEa{;V`1JT5-+Q0UOVjvib5W|e5I3p3kMt4#ta^UNxZdQwG)>ccs%!|CGzaG`?IzRF` zVcwX?4ercWPEi!FI`dzlXqBz70KN_8?4WQp{um<^Xs!AaousN$OoQONSg@2Uy33FB zrp`Ba3eE=ybT|pt?RxU>1RrD}{fMJ}b`|)7h34%u|9`Sp@CViNhjJBXE zcs$++&*9jV1BjsuPkWkAB+a-ovF#9ow`_Jghy~r}RB=rcK?k`QCL{P?I#G!jQ9#+> z>V5mLw?*&MwgKIy@Qdvw*me;71x-OAu7dxU_F(FoweVdj(s-)!iC|TI88m>sJ%3!# zO#8ovp>BdlLrXP&gBY2iH|WHDi80d9WN6xFWkZv>Gef7wM&|A*!srQ5Vh6cM*QTFh zbPS%d1v%Uq$PKNM&>Is=Xqdjt{QETlR-@vy>u`V{vD*A9YQ7ZK82wh^X6I11$;j*@m&Las|Fuy zoH+LXS~K)Mqy~4`?3DpY1Llfw5t7Q)K-bDm zV=>w;-A-2A1*6A!$~CV%H5m?*qq4bY>9`CpZ+GZ6Fvrv}jH5a~BWEYPQq>BX2rbR2 zth@z9D@VoCDv%TLK(HrqqN|myqX93>xmbYlHP4D+lJe?mFU~mIg=sEhIo&okSH(Yq z6yTAD5EaQ)69U~Zi;zi*iwy0UJTU>-SeU@Avv#qUVo0^2|LyN?u?syjZ2MLh0) z!_`>lMRy`}qEpV`bf%2U?&CxOuBvpgEUl>`p%c zn!wElG_El`Bk$0dydX;&gJx(Pl3sah&os<7>m4qHo+U};CL+L9~xn{av^RT?FNWV7-|g!!TzNkvEHy*)%$&x5BmMeTihU)9=3Aij$o553v6$t yNh7Ztv2KK|Yxd5jx=`H0FbFFD^DJkRlz(9^4rTDTsL}9k8+-udJ1|J&gZ}_X!;ZfI diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/perception/vision/__init__.py b/app/api/perception/vision/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/data/__init__.py b/app/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/data/users/dummy_user/pictures/Paul.jpeg b/app/data/users/dummy_user/pictures/Paul.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fb881c9468965c6056ad8b5e7606ca276f45f5f6 GIT binary patch literal 39784 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 RzQot#@etw6KVIEG|JjfH(ro|$ literal 0 HcmV?d00001 diff --git a/app/data/users/dummy_user/pictures/Peter.jpeg b/app/data/users/dummy_user/pictures/Peter.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8b645b646d66f06b1712dc2448c3d76c5932bf3d GIT binary patch literal 61013 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 literal 0 HcmV?d00001 diff --git a/app/services/__init__.py b/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/services/authentication/auth_utils.py b/app/services/authentication/auth_utils.py new file mode 100644 index 0000000..e9878f6 --- /dev/null +++ b/app/services/authentication/auth_utils.py @@ -0,0 +1,4 @@ +# app/services/authentication/auth_utils.py +""" +This file contains utility functions for authentication-related tasks. +""" \ No newline at end of file diff --git a/app/services/authentication/password_utils.py b/app/services/authentication/password_utils.py new file mode 100644 index 0000000..066e788 --- /dev/null +++ b/app/services/authentication/password_utils.py @@ -0,0 +1,4 @@ +# app/services/authentication/password_utils.py +""" +This file contains utility functions for password-related tasks. +""" \ No newline at end of file diff --git a/app/services/perception/audio/__init__.py b/app/services/perception/audio/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/services/perception/audio/stt_utils.py b/app/services/perception/audio/stt_utils.py new file mode 100644 index 0000000..dbaf069 --- /dev/null +++ b/app/services/perception/audio/stt_utils.py @@ -0,0 +1,4 @@ +# app/services/perception/audio/transcription.py +""" +This file is for Speech-to-text (STT) logic utilities. +""" diff --git a/app/services/perception/audio/tts_utils.py b/app/services/perception/audio/tts_utils.py new file mode 100644 index 0000000..8a8ecf3 --- /dev/null +++ b/app/services/perception/audio/tts_utils.py @@ -0,0 +1,4 @@ +# app/services/perception/audio/transcription.py +""" +This file is for Text-to-speech (TTS) logic utilities. +""" diff --git a/app/services/perception/audio/voice_utils.py b/app/services/perception/audio/voice_utils.py new file mode 100644 index 0000000..94135e0 --- /dev/null +++ b/app/services/perception/audio/voice_utils.py @@ -0,0 +1,4 @@ +# app/services/perception/audio/voice_utils.py +""" +This file is for voice related utilities. +""" \ No newline at end of file diff --git a/app/services/perception/vision/__init__.py b/app/services/perception/vision/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/services/perception/vision/face_utils.py b/app/services/perception/vision/face_utils.py new file mode 100644 index 0000000..49db945 --- /dev/null +++ b/app/services/perception/vision/face_utils.py @@ -0,0 +1,4 @@ +# app/services/perception/vision/face_utils.py +""" +This file contains all the utility services related to face. +""" \ No newline at end of file diff --git a/app/services/perception/vision/gesture_utils.py b/app/services/perception/vision/gesture_utils.py new file mode 100644 index 0000000..5d50d0a --- /dev/null +++ b/app/services/perception/vision/gesture_utils.py @@ -0,0 +1,4 @@ +# app/services/perception/vision/gesture_utils.py +""" +This file is for hand/pose getures like utilities. +""" \ No newline at end of file diff --git a/app/services/perception/vision/object_utils.py b/app/services/perception/vision/object_utils.py new file mode 100644 index 0000000..8ce1a18 --- /dev/null +++ b/app/services/perception/vision/object_utils.py @@ -0,0 +1,4 @@ +# app/services/perception/vision/object_utils.py +""" +This file contains all the utility services related to objects. +""" \ No newline at end of file diff --git a/app/services/perception/vision/scene_analysis.py b/app/services/perception/vision/scene_analysis.py new file mode 100644 index 0000000..d6c675d --- /dev/null +++ b/app/services/perception/vision/scene_analysis.py @@ -0,0 +1,4 @@ +# app/services/perception/vision/scene_analysis.py +""" +This file is for scene analysis and description utilities. +""" \ No newline at end of file diff --git a/app/services/storage/database_storage.py b/app/services/storage/database_storage.py new file mode 100644 index 0000000..ca3773b --- /dev/null +++ b/app/services/storage/database_storage.py @@ -0,0 +1,4 @@ +# app/services/storage/database_storage.py +""" +This file is for utilities to Save & retrieve from database. +""" \ No newline at end of file diff --git a/app/services/storage/file_storage.py b/app/services/storage/file_storage.py new file mode 100644 index 0000000..31eb877 --- /dev/null +++ b/app/services/storage/file_storage.py @@ -0,0 +1,4 @@ +# app/services/storage/file_storage.py +""" +This file is for utilities to Save & retrieve files locally. +""" \ No newline at end of file diff --git a/app/shared/__init__.py b/app/shared/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/shared/config.py b/app/shared/config.py new file mode 100644 index 0000000..f3d3c1c --- /dev/null +++ b/app/shared/config.py @@ -0,0 +1,4 @@ +# app/shared/config.py +""" +This file contains configuration variables and methods for the VisionMate application. +""" \ No newline at end of file diff --git a/app/shared/logger.py b/app/shared/logger.py new file mode 100644 index 0000000..7660851 --- /dev/null +++ b/app/shared/logger.py @@ -0,0 +1,4 @@ +# app/shared/logger.py +""" +This file contains Centralized logging setup. +""" \ No newline at end of file diff --git a/app/shared/paths.py b/app/shared/paths.py new file mode 100644 index 0000000..daffb53 --- /dev/null +++ b/app/shared/paths.py @@ -0,0 +1,4 @@ +# app/shared/paths.py +""" +This file defines paths and utility functions for managing user directories in the VisionMate application. +""" diff --git a/app/shared/utils.py b/app/shared/utils.py new file mode 100644 index 0000000..7361ccc --- /dev/null +++ b/app/shared/utils.py @@ -0,0 +1,4 @@ +# app/shared/utils.py +""" +This file contains utility functions for the VisionMate application. Common utility methods are defined here. +""" diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_face_recog.py b/tests/test_face_utils.py similarity index 95% rename from tests/test_face_recog.py rename to tests/test_face_utils.py index 917a362..4f939ac 100644 --- a/tests/test_face_recog.py +++ b/tests/test_face_utils.py @@ -11,8 +11,8 @@ face_recog, ) -APP_PATH=pathlib.Path(__file__).parent.parent - +APP_PATH=pathlib.Path(__file__).parent +print(APP_PATH) def test_detect_faces(): # Test the detect_faces function name="Paul" @@ -41,4 +41,3 @@ def test_face_recog(): assert match_result[0] is True assert match_result[1] == "Paul" assert match_result[2] is None -