Update app.py
Browse files
app.py
CHANGED
|
@@ -27,29 +27,28 @@ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(
|
|
| 27 |
logger = logging.getLogger(__name__)
|
| 28 |
|
| 29 |
# =========================
|
| 30 |
-
# Setup PARSeq path
|
| 31 |
# =========================
|
| 32 |
-
# Add current directory to path
|
| 33 |
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 34 |
-
|
| 35 |
-
sys.path.insert(0, current_dir)
|
| 36 |
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
try:
|
| 39 |
from strhub.data.utils import Tokenizer
|
| 40 |
-
|
|
|
|
| 41 |
except ImportError as e:
|
| 42 |
-
logger.error(f"Failed to import
|
| 43 |
-
|
| 44 |
-
logger.info(f"Files in {current_dir}: {os.listdir(current_dir)}")
|
| 45 |
-
# Check if parseq folder exists
|
| 46 |
-
if os.path.exists('parseq'):
|
| 47 |
-
logger.info("parseq folder exists, checking contents:")
|
| 48 |
-
logger.info(f"parseq contents: {os.listdir('parseq')}")
|
| 49 |
raise
|
| 50 |
|
| 51 |
-
import torch.hub
|
| 52 |
-
|
| 53 |
warnings.filterwarnings('ignore')
|
| 54 |
|
| 55 |
# =========================
|
|
@@ -128,17 +127,15 @@ def load_model(model_path, lang_name):
|
|
| 128 |
|
| 129 |
logger.info(f"Charset length for {lang_name}: {len(charset_str)}")
|
| 130 |
|
| 131 |
-
#
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
#
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
else:
|
| 141 |
-
state_dict = checkpoint
|
| 142 |
|
| 143 |
# Remove 'module.' prefix if present
|
| 144 |
new_state_dict = {}
|
|
@@ -147,13 +144,15 @@ def load_model(model_path, lang_name):
|
|
| 147 |
k = k.replace('module.', '')
|
| 148 |
new_state_dict[k] = v
|
| 149 |
|
|
|
|
| 150 |
model.load_state_dict(new_state_dict, strict=False)
|
|
|
|
| 151 |
model = model.to(device)
|
| 152 |
model.eval()
|
| 153 |
|
| 154 |
-
model_cache[cache_key] = (model, device,
|
| 155 |
logger.info(f"β
Loaded {lang_name} model successfully")
|
| 156 |
-
return model, device,
|
| 157 |
|
| 158 |
except Exception as e:
|
| 159 |
logger.error(f"Error loading {lang_name}: {e}")
|
|
@@ -301,7 +300,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 301 |
margin: auto !important;
|
| 302 |
}
|
| 303 |
|
| 304 |
-
/* Make tab text clearly visible */
|
| 305 |
.tab-nav button {
|
| 306 |
font-size: 18px !important;
|
| 307 |
font-weight: bold !important;
|
|
@@ -324,7 +322,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 324 |
transform: translateY(-2px);
|
| 325 |
}
|
| 326 |
|
| 327 |
-
/* Button styling */
|
| 328 |
button {
|
| 329 |
transition: all 0.3s ease !important;
|
| 330 |
font-weight: bold !important;
|
|
@@ -338,7 +335,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 338 |
box-shadow: 0 5px 15px rgba(0,0,0,0.2) !important;
|
| 339 |
}
|
| 340 |
|
| 341 |
-
/* Gallery styling - prevent expansion */
|
| 342 |
.gr-gallery {
|
| 343 |
border: 2px solid #e0e0e0;
|
| 344 |
border-radius: 10px;
|
|
@@ -355,13 +351,11 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 355 |
transform: scale(1.05) !important;
|
| 356 |
}
|
| 357 |
|
| 358 |
-
/* Box styling */
|
| 359 |
.gr-box {
|
| 360 |
border-radius: 10px;
|
| 361 |
border: 1px solid #e0e0e0;
|
| 362 |
}
|
| 363 |
|
| 364 |
-
/* Primary button styling */
|
| 365 |
.gr-button-primary {
|
| 366 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
| 367 |
color: white !important;
|
|
@@ -369,7 +363,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 369 |
}
|
| 370 |
""") as demo:
|
| 371 |
|
| 372 |
-
# Header
|
| 373 |
gr.Markdown("""
|
| 374 |
# π Multilingual Scene Text Recognition System
|
| 375 |
### Extract text from images in Telugu, Bengali, and Oriya languages
|
|
@@ -383,7 +376,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 383 |
with gr.TabItem(f"π€ {lang}"):
|
| 384 |
create_language_tab(lang)
|
| 385 |
|
| 386 |
-
# Footer
|
| 387 |
gr.Markdown("""
|
| 388 |
---
|
| 389 |
### π‘ How to use:
|
|
@@ -391,24 +383,17 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Multilingual Scene Text Recognitio
|
|
| 391 |
2. **Click any sample thumbnail** - it will load into the main preview above
|
| 392 |
3. **Click "Extract Text"** button below the preview
|
| 393 |
4. **View results** on the right side
|
| 394 |
-
|
| 395 |
-
### π Note:
|
| 396 |
-
- Sample thumbnails stay as thumbnails - they don't expand when clicked
|
| 397 |
-
- Only the main preview area changes when you click a sample
|
| 398 |
-
- You can also upload your own images
|
| 399 |
""")
|
| 400 |
|
| 401 |
# =========================
|
| 402 |
# Run
|
| 403 |
# =========================
|
| 404 |
if __name__ == "__main__":
|
| 405 |
-
# Check directories
|
| 406 |
for lang, config in LANGUAGES.items():
|
| 407 |
if not os.path.exists(config["model_path"]):
|
| 408 |
logger.warning(f"β οΈ Model not found: {config['model_path']} for {lang}")
|
| 409 |
if not os.path.exists(config["samples_dir"]):
|
| 410 |
os.makedirs(config["samples_dir"], exist_ok=True)
|
| 411 |
-
logger.warning(f"π Created samples directory: {config['samples_dir']}")
|
| 412 |
|
| 413 |
demo.launch(
|
| 414 |
server_name="0.0.0.0",
|
|
|
|
| 27 |
logger = logging.getLogger(__name__)
|
| 28 |
|
| 29 |
# =========================
|
| 30 |
+
# Setup PARSeq path - USE LOCAL FOLDER, NOT TORCH HUB
|
| 31 |
# =========================
|
|
|
|
| 32 |
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 33 |
+
parseq_local_path = os.path.join(current_dir, 'parseq')
|
|
|
|
| 34 |
|
| 35 |
+
if os.path.exists(parseq_local_path):
|
| 36 |
+
sys.path.insert(0, parseq_local_path)
|
| 37 |
+
logger.info(f"β
Using local parseq folder at {parseq_local_path}")
|
| 38 |
+
else:
|
| 39 |
+
logger.error(f"parseq folder not found at {parseq_local_path}")
|
| 40 |
+
sys.exit(1)
|
| 41 |
+
|
| 42 |
+
# Import from local parseq folder
|
| 43 |
try:
|
| 44 |
from strhub.data.utils import Tokenizer
|
| 45 |
+
from strhub.models.parseq.model import PARSeq
|
| 46 |
+
logger.info("β
Successfully imported Tokenizer and PARSeq from local folder")
|
| 47 |
except ImportError as e:
|
| 48 |
+
logger.error(f"Failed to import: {e}")
|
| 49 |
+
logger.info(f"Contents of parseq folder: {os.listdir(parseq_local_path)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
raise
|
| 51 |
|
|
|
|
|
|
|
| 52 |
warnings.filterwarnings('ignore')
|
| 53 |
|
| 54 |
# =========================
|
|
|
|
| 127 |
|
| 128 |
logger.info(f"Charset length for {lang_name}: {len(charset_str)}")
|
| 129 |
|
| 130 |
+
# Create tokenizer
|
| 131 |
+
tokenizer = Tokenizer(charset_str)
|
| 132 |
+
|
| 133 |
+
# Create model instance from local PARSeq class
|
| 134 |
+
# Get model parameters from state dict keys
|
| 135 |
+
state_dict = checkpoint.get('model_state_dict', checkpoint.get('model', checkpoint))
|
| 136 |
+
|
| 137 |
+
# Create model with default parameters (it will be overwritten by state_dict)
|
| 138 |
+
model = PARSeq()
|
|
|
|
|
|
|
| 139 |
|
| 140 |
# Remove 'module.' prefix if present
|
| 141 |
new_state_dict = {}
|
|
|
|
| 144 |
k = k.replace('module.', '')
|
| 145 |
new_state_dict[k] = v
|
| 146 |
|
| 147 |
+
# Load weights
|
| 148 |
model.load_state_dict(new_state_dict, strict=False)
|
| 149 |
+
model.tokenizer = tokenizer
|
| 150 |
model = model.to(device)
|
| 151 |
model.eval()
|
| 152 |
|
| 153 |
+
model_cache[cache_key] = (model, device, tokenizer)
|
| 154 |
logger.info(f"β
Loaded {lang_name} model successfully")
|
| 155 |
+
return model, device, tokenizer
|
| 156 |
|
| 157 |
except Exception as e:
|
| 158 |
logger.error(f"Error loading {lang_name}: {e}")
|
|
|
|
| 300 |
margin: auto !important;
|
| 301 |
}
|
| 302 |
|
|
|
|
| 303 |
.tab-nav button {
|
| 304 |
font-size: 18px !important;
|
| 305 |
font-weight: bold !important;
|
|
|
|
| 322 |
transform: translateY(-2px);
|
| 323 |
}
|
| 324 |
|
|
|
|
| 325 |
button {
|
| 326 |
transition: all 0.3s ease !important;
|
| 327 |
font-weight: bold !important;
|
|
|
|
| 335 |
box-shadow: 0 5px 15px rgba(0,0,0,0.2) !important;
|
| 336 |
}
|
| 337 |
|
|
|
|
| 338 |
.gr-gallery {
|
| 339 |
border: 2px solid #e0e0e0;
|
| 340 |
border-radius: 10px;
|
|
|
|
| 351 |
transform: scale(1.05) !important;
|
| 352 |
}
|
| 353 |
|
|
|
|
| 354 |
.gr-box {
|
| 355 |
border-radius: 10px;
|
| 356 |
border: 1px solid #e0e0e0;
|
| 357 |
}
|
| 358 |
|
|
|
|
| 359 |
.gr-button-primary {
|
| 360 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
| 361 |
color: white !important;
|
|
|
|
| 363 |
}
|
| 364 |
""") as demo:
|
| 365 |
|
|
|
|
| 366 |
gr.Markdown("""
|
| 367 |
# π Multilingual Scene Text Recognition System
|
| 368 |
### Extract text from images in Telugu, Bengali, and Oriya languages
|
|
|
|
| 376 |
with gr.TabItem(f"π€ {lang}"):
|
| 377 |
create_language_tab(lang)
|
| 378 |
|
|
|
|
| 379 |
gr.Markdown("""
|
| 380 |
---
|
| 381 |
### π‘ How to use:
|
|
|
|
| 383 |
2. **Click any sample thumbnail** - it will load into the main preview above
|
| 384 |
3. **Click "Extract Text"** button below the preview
|
| 385 |
4. **View results** on the right side
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
""")
|
| 387 |
|
| 388 |
# =========================
|
| 389 |
# Run
|
| 390 |
# =========================
|
| 391 |
if __name__ == "__main__":
|
|
|
|
| 392 |
for lang, config in LANGUAGES.items():
|
| 393 |
if not os.path.exists(config["model_path"]):
|
| 394 |
logger.warning(f"β οΈ Model not found: {config['model_path']} for {lang}")
|
| 395 |
if not os.path.exists(config["samples_dir"]):
|
| 396 |
os.makedirs(config["samples_dir"], exist_ok=True)
|
|
|
|
| 397 |
|
| 398 |
demo.launch(
|
| 399 |
server_name="0.0.0.0",
|