|
|
""" |
|
|
ISL Sign Language Translation - TechMatrix Solvers Initiative |
|
|
Main Streamlit Application |
|
|
|
|
|
Developed by: TechMatrix Solvers Team |
|
|
- Abhay Gupta (Team Lead) - contact2abhaygupta6187@gmail.com |
|
|
- Kripanshu Gupta (Backend Developer) - guptakripanshu83@gmail.com |
|
|
- Dipanshu Patel (UI/UX Designer) - dipanshupatel43@gmail.com |
|
|
- Bhumika Patel (Deployment & Female Presenter) - bp7249951@gmail.com |
|
|
|
|
|
Institution: Shri Ram Group of Institutions |
|
|
""" |
|
|
|
|
|
import streamlit as st |
|
|
import sys |
|
|
import os |
|
|
|
|
|
|
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|
|
|
|
|
|
|
|
st.set_page_config( |
|
|
page_title="ISL Translation - TechMatrix Solvers", |
|
|
page_icon="π€", |
|
|
layout="wide", |
|
|
initial_sidebar_state="expanded", |
|
|
menu_items={ |
|
|
'Get Help': 'https://docs.google.com/document/d/1mzr2KGHRJT5heUjFF20NQ3Gb89urpjZJ/edit?usp=sharing', |
|
|
'Report a bug': "mailto:contact2abhaygupta6187@gmail.com", |
|
|
'About': "# TechMatrix Solvers ISL Translation System\nAdvanced Indian Sign Language translation using deep learning!" |
|
|
} |
|
|
) |
|
|
|
|
|
|
|
|
if 'app_initialized' not in st.session_state: |
|
|
st.session_state.app_initialized = False |
|
|
|
|
|
|
|
|
loading_placeholder = st.empty() |
|
|
with loading_placeholder: |
|
|
st.markdown(""" |
|
|
<div style="text-align: center; padding: 50px;"> |
|
|
<h1>π TechMatrix Solvers</h1> |
|
|
<h2>ISL Translation System</h2> |
|
|
<p>Loading advanced AI models...</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
os.environ["KERAS_BACKEND"] = "torch" |
|
|
os.environ["OPENCV_LOG_LEVEL"] = "ERROR" |
|
|
os.environ["QT_QPA_PLATFORM"] = "offscreen" |
|
|
|
|
|
|
|
|
try: |
|
|
import numpy as np |
|
|
import pandas as pd |
|
|
import time |
|
|
import tempfile |
|
|
import json |
|
|
import uuid |
|
|
import platform |
|
|
import shutil |
|
|
from PIL import Image |
|
|
from typing import NamedTuple |
|
|
import subprocess |
|
|
|
|
|
|
|
|
cv2 = None |
|
|
try: |
|
|
import cv2 |
|
|
|
|
|
if hasattr(cv2, 'setNumThreads'): |
|
|
cv2.setNumThreads(1) |
|
|
|
|
|
_ = cv2.__version__ |
|
|
except ImportError as opencv_error: |
|
|
loading_placeholder.empty() |
|
|
st.error(f"β OpenCV import failed: {opencv_error}") |
|
|
st.error("Please run the setup script: `setup_windows.bat` or `./setup_windows.ps1`") |
|
|
st.info("π‘ Alternative: pip uninstall opencv-python && pip install opencv-python-headless") |
|
|
st.stop() |
|
|
except Exception as opencv_error: |
|
|
loading_placeholder.empty() |
|
|
st.error(f"β OpenCV configuration error: {opencv_error}") |
|
|
st.error("This might be a headless display issue. Please use opencv-python-headless.") |
|
|
st.info("π‘ Try: pip install opencv-python-headless==4.8.1.78") |
|
|
st.stop() |
|
|
|
|
|
|
|
|
import keras |
|
|
from keras.models import Sequential |
|
|
from keras.layers import LSTM, Dense, Bidirectional, Dropout, Input, BatchNormalization |
|
|
|
|
|
|
|
|
import ffmpeg |
|
|
|
|
|
|
|
|
from huggingface_hub import hf_hub_download |
|
|
|
|
|
|
|
|
from pose_models import create_bodypose_model, create_handpose_model |
|
|
from expression_mapping import expression_mapping |
|
|
from isl_processor import ISLTranslationModel |
|
|
import pose_utils as utils |
|
|
|
|
|
|
|
|
loading_placeholder.empty() |
|
|
st.success("β
TechMatrix Solvers ISL System loaded successfully!") |
|
|
st.session_state.app_initialized = True |
|
|
|
|
|
except ImportError as e: |
|
|
loading_placeholder.empty() |
|
|
st.error(f"β Failed to load dependencies: {e}") |
|
|
st.error("Please ensure all required packages are installed.") |
|
|
st.stop() |
|
|
except Exception as e: |
|
|
loading_placeholder.empty() |
|
|
st.error(f"β Unexpected error during initialization: {e}") |
|
|
st.stop() |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
.main-header { |
|
|
background: linear-gradient(90deg, #1e3a8a, #7c3aed); |
|
|
color: white; |
|
|
padding: 2rem; |
|
|
border-radius: 10px; |
|
|
text-align: center; |
|
|
margin-bottom: 2rem; |
|
|
} |
|
|
|
|
|
.team-card { |
|
|
background-color: #f8fafc; |
|
|
border: 1px solid #e2e8f0; |
|
|
border-radius: 8px; |
|
|
padding: 1rem; |
|
|
margin: 1rem 0; |
|
|
} |
|
|
|
|
|
.feature-box { |
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
|
color: white; |
|
|
padding: 1.5rem; |
|
|
border-radius: 10px; |
|
|
margin: 1rem 0; |
|
|
} |
|
|
|
|
|
.stat-card { |
|
|
background-color: #ffffff; |
|
|
border: 1px solid #d1d5db; |
|
|
border-radius: 8px; |
|
|
padding: 1rem; |
|
|
text-align: center; |
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1); |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
<div class="main-header"> |
|
|
<h1>π€ ISL Sign Language Translation</h1> |
|
|
<h2>TechMatrix Solvers Initiative</h2> |
|
|
<p>Advanced AI-Powered Indian Sign Language Recognition & Translation</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.sidebar.markdown(""" |
|
|
<div style="text-align: center; padding: 1rem; background-color: #f0f2f6; border-radius: 8px; margin-bottom: 1rem;"> |
|
|
<h3>π TechMatrix Solvers</h3> |
|
|
<p><em>Innovating Accessible Technology</em></p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.sidebar.title('ποΈ Control Panel') |
|
|
|
|
|
|
|
|
with st.sidebar.expander("π¨βπ» Meet Our Team"): |
|
|
st.markdown(""" |
|
|
**TechMatrix Solvers Team:** |
|
|
- **Abhay Gupta** - Team Lead π |
|
|
- **Kripanshu Gupta** - Backend Dev π» |
|
|
- **Dipanshu Patel** - UI/UX Designer π¨ |
|
|
- **Bhumika Patel** - Deployment π |
|
|
|
|
|
*Shri Ram Group of Institutions* |
|
|
""") |
|
|
|
|
|
|
|
|
app_mode = st.sidebar.selectbox( |
|
|
'π― Choose Application Mode', |
|
|
['π Home & About', 'π₯ Live Translation Demo', 'π System Information'], |
|
|
index=0 |
|
|
) |
|
|
|
|
|
|
|
|
class VideoProbeResult(NamedTuple): |
|
|
"""Structure for video probe results""" |
|
|
return_code: int |
|
|
json: str |
|
|
error: str |
|
|
|
|
|
def probe_video_info(file_path) -> VideoProbeResult: |
|
|
"""Probe video file for metadata using FFprobe""" |
|
|
command_array = [ |
|
|
"ffprobe", "-v", "quiet", "-print_format", "json", |
|
|
"-show_format", "-show_streams", file_path |
|
|
] |
|
|
try: |
|
|
result = subprocess.run( |
|
|
command_array, |
|
|
stdout=subprocess.PIPE, |
|
|
stderr=subprocess.PIPE, |
|
|
universal_newlines=True, |
|
|
timeout=30 |
|
|
) |
|
|
return VideoProbeResult( |
|
|
return_code=result.returncode, |
|
|
json=result.stdout, |
|
|
error=result.stderr |
|
|
) |
|
|
except subprocess.TimeoutExpired: |
|
|
return VideoProbeResult(1, "", "FFprobe timeout") |
|
|
|
|
|
@st.cache_data |
|
|
def load_test_data(): |
|
|
"""Load test dataset and file information""" |
|
|
try: |
|
|
with st.spinner("π₯ Loading test data from HuggingFace..."): |
|
|
testing_cleaned_path = hf_hub_download( |
|
|
repo_id="sunilsarolkar/isl-test-data", |
|
|
filename="testing_cleaned.csv", |
|
|
repo_type="dataset" |
|
|
) |
|
|
|
|
|
test_files_path = hf_hub_download( |
|
|
repo_id="sunilsarolkar/isl-test-data", |
|
|
filename="test_files.csv", |
|
|
repo_type="dataset" |
|
|
) |
|
|
|
|
|
testing_df = pd.read_csv(testing_cleaned_path) |
|
|
test_files_df = pd.read_csv(test_files_path) |
|
|
|
|
|
return testing_df, test_files_df |
|
|
except Exception as e: |
|
|
st.error(f"Failed to load test data: {e}") |
|
|
return None, None |
|
|
|
|
|
@st.cache_resource |
|
|
def load_translation_model(): |
|
|
"""Load and configure the LSTM translation model""" |
|
|
try: |
|
|
with st.spinner("π§ Loading AI translation model..."): |
|
|
model = Sequential() |
|
|
model.add(Input(shape=((20, 156)))) |
|
|
model.add(keras.layers.Masking(mask_value=0.)) |
|
|
model.add(BatchNormalization()) |
|
|
model.add(Bidirectional(LSTM(32, recurrent_dropout=0.2, return_sequences=True))) |
|
|
model.add(Dropout(0.2)) |
|
|
model.add(Bidirectional(LSTM(32, recurrent_dropout=0.2))) |
|
|
model.add(keras.layers.Activation('elu')) |
|
|
model.add(Dense(32, use_bias=False, kernel_initializer='he_normal')) |
|
|
model.add(BatchNormalization()) |
|
|
model.add(Dropout(0.2)) |
|
|
model.add(keras.layers.Activation('elu')) |
|
|
model.add(Dense(32, kernel_initializer='he_normal', use_bias=False)) |
|
|
model.add(BatchNormalization()) |
|
|
model.add(keras.layers.Activation('elu')) |
|
|
model.add(Dropout(0.2)) |
|
|
model.add(Dense(len(list(expression_mapping.keys())), activation='softmax')) |
|
|
|
|
|
|
|
|
model_file = hf_hub_download( |
|
|
repo_id="sunilsarolkar/isl-translation-model", |
|
|
filename="isl_model_final.keras" |
|
|
) |
|
|
model.load_weights(model_file) |
|
|
|
|
|
return model |
|
|
except Exception as e: |
|
|
st.error(f"Failed to load translation model: {e}") |
|
|
return None |
|
|
|
|
|
|
|
|
if app_mode == 'π Home & About': |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
## π― Project Overview |
|
|
|
|
|
Welcome to the **ISL Sign Language Translation System** by **TechMatrix Solvers**! |
|
|
This cutting-edge application demonstrates real-time Indian Sign Language recognition |
|
|
and translation using advanced deep learning techniques. |
|
|
""") |
|
|
|
|
|
|
|
|
col1, col2, col3 = st.columns(3) |
|
|
|
|
|
with col1: |
|
|
st.markdown(""" |
|
|
<div class="feature-box"> |
|
|
<h3>π§ AI-Powered</h3> |
|
|
<p>Advanced LSTM networks with 82K+ parameters for accurate sign recognition</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
with col2: |
|
|
st.markdown(""" |
|
|
<div class="feature-box"> |
|
|
<h3>β‘ Real-time</h3> |
|
|
<p>Live video processing with OpenPose body & hand detection</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
with col3: |
|
|
st.markdown(""" |
|
|
<div class="feature-box"> |
|
|
<h3>π― Accurate</h3> |
|
|
<p>Trained on INCLUDE dataset with 263 words across 15 categories</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown("## ποΈ Technical Architecture") |
|
|
|
|
|
col1, col2 = st.columns(2) |
|
|
|
|
|
with col1: |
|
|
st.markdown(""" |
|
|
### π§ Core Components |
|
|
1. **Body Pose Estimation**: 25-point skeletal tracking |
|
|
2. **Hand Landmark Detection**: 21-point hand keypoints |
|
|
3. **Temporal Modeling**: Bidirectional LSTM networks |
|
|
4. **Real-time Processing**: Optimized inference pipeline |
|
|
""") |
|
|
|
|
|
|
|
|
try: |
|
|
st.image("DataPipeline.png", caption="π Data Processing Pipeline", use_column_width=True) |
|
|
except: |
|
|
st.info("π Architecture diagram will be displayed when available") |
|
|
|
|
|
with col2: |
|
|
st.markdown(""" |
|
|
### π Dataset Statistics |
|
|
""") |
|
|
|
|
|
|
|
|
stats_data = { |
|
|
"Metric": ["Categories", "Total Words", "Training Videos", "Avg Videos/Class", "Frame Rate"], |
|
|
"Value": ["15", "263", "4,257", "16.3", "25fps"] |
|
|
} |
|
|
st.table(pd.DataFrame(stats_data)) |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
### π€ Model Statistics |
|
|
- **Architecture**: Bidirectional LSTM |
|
|
- **Parameters**: 82,679 (322.96 KB) |
|
|
- **Input Features**: 156-dimensional vectors |
|
|
- **Temporal Window**: 20 frames |
|
|
""") |
|
|
|
|
|
|
|
|
st.markdown("## π₯ TechMatrix Solvers Team") |
|
|
|
|
|
team_data = { |
|
|
"Name": ["Abhay Gupta", "Kripanshu Gupta", "Dipanshu Patel", "Bhumika Patel"], |
|
|
"Role": ["Team Lead", "Backend Developer", "UI/UX Designer", "Deployment & Presenter"], |
|
|
"Email": [ |
|
|
"contact2abhaygupta6187@gmail.com", |
|
|
"guptakripanshu83@gmail.com", |
|
|
"dipanshupatel43@gmail.com", |
|
|
"bp7249951@gmail.com" |
|
|
], |
|
|
"Phone": ["8115814535", "7067058400", "9294526404", "9302271422"] |
|
|
} |
|
|
|
|
|
st.table(pd.DataFrame(team_data)) |
|
|
|
|
|
st.markdown(""" |
|
|
### π« Institution |
|
|
**Shri Ram Group of Institutions** |
|
|
|
|
|
### π Documentation |
|
|
For detailed technical documentation, visit our [comprehensive guide](https://docs.google.com/document/d/1mzr2KGHRJT5heUjFF20NQ3Gb89urpjZJ/edit?usp=sharing). |
|
|
""") |
|
|
|
|
|
elif app_mode == 'π₯ Live Translation Demo': |
|
|
st.markdown("## π₯ Live ISL Translation Demo") |
|
|
|
|
|
|
|
|
testing_df, test_files_df = load_test_data() |
|
|
|
|
|
if testing_df is None or test_files_df is None: |
|
|
st.error("β Cannot proceed without test data. Please check your internet connection.") |
|
|
st.stop() |
|
|
|
|
|
st.success(f"β
Loaded {len(testing_df)} test frames and {len(test_files_df)} video files") |
|
|
|
|
|
|
|
|
st.markdown("### π Select Test Video") |
|
|
|
|
|
col1, col2, col3 = st.columns(3) |
|
|
|
|
|
with col1: |
|
|
category = st.selectbox( |
|
|
'Choose Category', |
|
|
sorted(test_files_df['Category'].unique()) |
|
|
) |
|
|
|
|
|
|
|
|
category_filtered = test_files_df[test_files_df['Category'] == category] |
|
|
|
|
|
with col2: |
|
|
class_name = st.selectbox( |
|
|
'Choose Class', |
|
|
sorted(category_filtered['Class'].unique()) |
|
|
) |
|
|
|
|
|
|
|
|
class_filtered = category_filtered[category_filtered['Class'] == class_name] |
|
|
|
|
|
with col3: |
|
|
filename = st.selectbox( |
|
|
'Choose File', |
|
|
sorted(class_filtered['Filename'].unique()) |
|
|
) |
|
|
|
|
|
|
|
|
st.info(f"π Selected: **{category}** β **{class_name}** β **{filename}**") |
|
|
|
|
|
|
|
|
if st.button("π Start ISL Translation", type="primary", use_container_width=True): |
|
|
|
|
|
|
|
|
progress_bar = st.progress(0) |
|
|
status_text = st.empty() |
|
|
|
|
|
try: |
|
|
status_text.text("π Preparing translation model...") |
|
|
progress_bar.progress(10) |
|
|
|
|
|
|
|
|
translation_model = load_translation_model() |
|
|
if translation_model is None: |
|
|
st.error("β Failed to load translation model") |
|
|
st.stop() |
|
|
|
|
|
progress_bar.progress(30) |
|
|
status_text.text("π₯ Downloading test video...") |
|
|
|
|
|
|
|
|
video_file_path = hf_hub_download( |
|
|
repo_id="sunilsarolkar/isl-test-data", |
|
|
filename=f'test/{category}/{class_name}/{filename}', |
|
|
repo_type="dataset" |
|
|
) |
|
|
|
|
|
progress_bar.progress(50) |
|
|
status_text.text("π¬ Processing video metadata...") |
|
|
|
|
|
|
|
|
if os.path.exists(video_file_path): |
|
|
progress_bar.progress(70) |
|
|
status_text.text("β¨ Ready for translation!") |
|
|
|
|
|
|
|
|
st.success("π Video loaded successfully!") |
|
|
st.video(video_file_path) |
|
|
|
|
|
|
|
|
st.markdown("### π Translation Results") |
|
|
|
|
|
result_placeholder = st.empty() |
|
|
with result_placeholder.container(): |
|
|
st.info("π Translation would be processed here in the full implementation") |
|
|
st.markdown(""" |
|
|
**Expected Output:** |
|
|
- Real-time pose detection |
|
|
- Feature extraction from body and hand keypoints |
|
|
- LSTM model prediction |
|
|
- Sign language translation display |
|
|
""") |
|
|
|
|
|
progress_bar.progress(100) |
|
|
status_text.text("β
Translation demo completed!") |
|
|
else: |
|
|
st.error("β Video file not found") |
|
|
|
|
|
except Exception as e: |
|
|
st.error(f"β Error during translation: {e}") |
|
|
progress_bar.progress(0) |
|
|
status_text.text("β Translation failed") |
|
|
|
|
|
elif app_mode == 'π System Information': |
|
|
st.markdown("## π System Information") |
|
|
|
|
|
|
|
|
col1, col2 = st.columns(2) |
|
|
|
|
|
with col1: |
|
|
st.markdown("### π» Environment") |
|
|
st.write(f"**Python Version:** {platform.python_version()}") |
|
|
st.write(f"**Platform:** {platform.system()} {platform.release()}") |
|
|
st.write(f"**Architecture:** {platform.machine()}") |
|
|
st.write(f"**FFmpeg:** {shutil.which('ffmpeg') or 'Not found'}") |
|
|
st.write(f"**FFprobe:** {shutil.which('ffprobe') or 'Not found'}") |
|
|
|
|
|
with col2: |
|
|
st.markdown("### π Libraries") |
|
|
try: |
|
|
st.write(f"**OpenCV:** {cv2.__version__}") |
|
|
except: |
|
|
st.write("**OpenCV:** Not available") |
|
|
|
|
|
try: |
|
|
import torch |
|
|
st.write(f"**PyTorch:** {torch.__version__}") |
|
|
except: |
|
|
st.write("**PyTorch:** Not available") |
|
|
|
|
|
try: |
|
|
st.write(f"**Keras:** {keras.__version__}") |
|
|
except: |
|
|
st.write("**Keras:** Not available") |
|
|
|
|
|
try: |
|
|
st.write(f"**NumPy:** {np.__version__}") |
|
|
st.write(f"**Pandas:** {pd.__version__}") |
|
|
except: |
|
|
st.write("**NumPy/Pandas:** Version info not available") |
|
|
|
|
|
|
|
|
st.markdown("### π§ AI Model Details") |
|
|
|
|
|
model_info = { |
|
|
"Component": [ |
|
|
"Translation Model", "Body Pose Model", "Hand Pose Model", |
|
|
"Feature Vector", "Temporal Window", "Output Classes" |
|
|
], |
|
|
"Specification": [ |
|
|
"Bidirectional LSTM", "OpenPose 25-point", "OpenPose 21-point", |
|
|
"156 dimensions", "20 frames", f"{len(expression_mapping)} signs" |
|
|
] |
|
|
} |
|
|
|
|
|
st.table(pd.DataFrame(model_info)) |
|
|
|
|
|
|
|
|
st.markdown("### β‘ Performance Metrics") |
|
|
|
|
|
metrics_col1, metrics_col2, metrics_col3, metrics_col4 = st.columns(4) |
|
|
|
|
|
with metrics_col1: |
|
|
st.metric("Model Parameters", "82,679", "Compact & Efficient") |
|
|
|
|
|
with metrics_col2: |
|
|
st.metric("Model Size", "322.96 KB", "Lightweight") |
|
|
|
|
|
with metrics_col3: |
|
|
st.metric("Input Features", "156", "Rich Feature Set") |
|
|
|
|
|
with metrics_col4: |
|
|
st.metric("Sign Classes", len(expression_mapping), "Comprehensive") |
|
|
|
|
|
|
|
|
st.markdown("---") |
|
|
st.markdown(""" |
|
|
<div style="text-align: center; color: #666; padding: 2rem;"> |
|
|
<h4>π TechMatrix Solvers</h4> |
|
|
<p><strong>Innovating Accessible Technology Solutions for Everyone</strong></p> |
|
|
<p><em>Shri Ram Group of Institutions | Β© 2024</em></p> |
|
|
<p> |
|
|
<a href="https://docs.google.com/document/d/1mzr2KGHRJT5heUjFF20NQ3Gb89urpjZJ/edit?usp=sharing" target="_blank">π Documentation</a> | |
|
|
<a href="mailto:contact2abhaygupta6187@gmail.com">π§ Contact</a> | |
|
|
<a href="https://huggingface.co/docs/hub/spaces-config-reference" target="_blank">π€ HF Spaces</a> |
|
|
</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |