Lemontropia-Suite/vision_example.py

426 lines
15 KiB
Python

"""
Lemontropia Suite - Game Vision AI Example
Demonstrates usage of the Game Vision AI module.
Updated for multi-backend OCR system with Windows Store Python support.
"""
import sys
from pathlib import Path
import logging
# Setup logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
logger = logging.getLogger(__name__)
def demo_hardware_detection():
"""Demonstrate hardware detection including PyTorch DLL error handling."""
print("\n" + "="*60)
print("HARDWARE DETECTION DEMO")
print("="*60)
from modules.hardware_detection import (
HardwareDetector,
print_hardware_summary,
recommend_ocr_backend
)
# Print full summary
print_hardware_summary()
# Get recommendation
recommended = recommend_ocr_backend()
print(f"\n📋 Recommended OCR backend: {recommended}")
# Check for Windows Store Python
info = HardwareDetector.detect_all()
if info.is_windows_store_python:
print("\n⚠️ Windows Store Python detected!")
if info.pytorch_dll_error:
print(" PyTorch DLL errors expected - using fallback OCR backends")
def demo_ocr_backends():
"""Demonstrate OCR backend selection."""
print("\n" + "="*60)
print("OCR BACKEND DEMO")
print("="*60)
from modules.ocr_backends import OCRBackendFactory
print("\nChecking all OCR backends...")
backends = OCRBackendFactory.check_all_backends(use_gpu=True)
for info in backends:
status = "✅ Available" if info.available else "❌ Not Available"
gpu_status = "🚀 GPU" if info.gpu_accelerated else "💻 CPU"
print(f"\n{info.name.upper()}:")
print(f" Status: {status}")
print(f" GPU: {gpu_status}")
if info.error_message:
print(f" Note: {info.error_message}")
available = [b.name for b in backends if b.available]
print(f"\n📊 Available backends: {', '.join(available) if available else 'None'}")
def demo_ocr(image_path: str = None):
"""Demonstrate OCR functionality."""
print("\n" + "="*60)
print("OCR TEXT EXTRACTION DEMO")
print("="*60)
from modules.game_vision_ai import UnifiedOCRProcessor
import cv2
import numpy as np
# Initialize OCR with auto-selection
print("\nInitializing OCR (auto-selecting best backend)...")
ocr = UnifiedOCRProcessor(use_gpu=True, lang='en', auto_select=True)
print(f"Selected backend: {ocr.get_current_backend()}")
if image_path and Path(image_path).exists():
print(f"\nProcessing: {image_path}")
regions = ocr.extract_text(image_path)
print(f"\nDetected {len(regions)} text regions:")
for i, region in enumerate(regions, 1):
text_preview = region.text[:50] + "..." if len(region.text) > 50 else region.text
print(f" {i}. '{text_preview}' (confidence: {region.confidence:.2%})")
print(f" Backend: {region.backend}")
print(f" Position: ({region.bbox[0]}, {region.bbox[1]}) {region.bbox[2]}x{region.bbox[3]}")
else:
# Create demo image
print("\nNo image provided, creating demo image...")
demo_img = np.ones((400, 600, 3), dtype=np.uint8) * 255
cv2.rectangle(demo_img, (50, 50), (200, 80), (0, 0, 0), -1)
cv2.rectangle(demo_img, (50, 100), (250, 130), (0, 0, 0), -1)
regions = ocr.extract_text(demo_img)
print(f"\nDetected {len(regions)} text regions in demo image")
print(f"\nUsage: python vision_example.py --ocr path/to/screenshot.png")
def demo_icon_detection(image_path: str = None):
"""Demonstrate icon detection."""
print("\n" + "="*60)
print("ICON DETECTION DEMO")
print("="*60)
from modules.game_vision_ai import IconDetector
import cv2
import numpy as np
detector = IconDetector()
if image_path and Path(image_path).exists():
print(f"\nProcessing: {image_path}")
image = cv2.imread(image_path)
# Detect loot window
window = detector.detect_loot_window(image)
if window:
print(f"\nDetected loot window at: {window}")
# Extract icons
icons = detector.extract_icons_from_region(image, window)
print(f"\nExtracted {len(icons)} icons:")
for i, icon in enumerate(icons, 1):
print(f" {i}. Position: {icon.bbox}")
print(f" Hash: {icon.icon_hash[:32]}...")
else:
print("\nNo loot window detected. Trying full image...")
h, w = image.shape[:2]
icons = detector.extract_icons_from_region(image, (0, 0, w, h))
print(f"Found {len(icons)} potential icons in full image")
else:
print("\nNo image provided, creating demo image...")
# Create demo image with icon-like regions
demo_img = np.ones((600, 800, 3), dtype=np.uint8) * 200
# Draw some icon-sized squares
for i in range(3):
for j in range(4):
x = 100 + j * 60
y = 100 + i * 60
color = (100 + i*50, 150, 200 - j*30)
cv2.rectangle(demo_img, (x, y), (x+48, y+48), color, -1)
h, w = demo_img.shape[:2]
icons = detector.extract_icons_from_region(demo_img, (0, 0, w, h))
print(f"Found {len(icons)} potential icons in demo image")
print(f"\nUsage: python vision_example.py --icons path/to/screenshot.png")
def demo_full_vision(image_path: str = None):
"""Demonstrate full vision processing."""
print("\n" + "="*60)
print("FULL VISION PROCESSING DEMO")
print("="*60)
from modules.game_vision_ai import GameVisionAI
import cv2
import numpy as np
# Initialize vision AI
print("\nInitializing Game Vision AI...")
vision = GameVisionAI(use_gpu=True, ocr_lang='en')
print(f"✅ Initialized!")
print(f" OCR Backend: {vision.ocr.get_current_backend()}")
print(f" GPU: {vision.backend.value}")
print(f" GPU Available: {vision.is_gpu_available()}")
if image_path and Path(image_path).exists():
print(f"\nProcessing: {image_path}")
# Process screenshot
result = vision.process_screenshot(image_path)
print(f"\n--- Results ---")
print(f"Processing Time: {result.processing_time_ms:.1f}ms")
print(f"OCR Backend: {result.ocr_backend}")
print(f"GPU Backend: {result.gpu_backend}")
print(f"\nText Regions ({len(result.text_regions)}):")
for region in result.text_regions:
text_preview = region.text[:40] + "..." if len(region.text) > 40 else region.text
print(f"'{text_preview}' ({region.confidence:.2%}) [{region.backend}]")
print(f"\nIcon Regions ({len(result.icon_regions)}):")
for region in result.icon_regions:
print(f" • Position: {region.bbox}")
print(f"\nExtracted icons saved to: {vision.extracted_icons_dir}")
else:
print("\nNo image provided, creating demo image...")
# Create demo image
demo_img = np.ones((600, 800, 3), dtype=np.uint8) * 240
# Draw loot window
cv2.rectangle(demo_img, (400, 50), (750, 400), (220, 220, 220), -1)
# Draw some icon slots
for row in range(4):
for col in range(5):
x = 420 + col * 55
y = 80 + row * 55
cv2.rectangle(demo_img, (x, y), (x+48, y+48), (180, 180, 180), -1)
if (row + col) % 2 == 0:
color = (100, 150, 200) if row % 2 == 0 else (200, 150, 100)
cv2.rectangle(demo_img, (x+5, y+5), (x+43, y+43), color, -1)
# Save and process
demo_path = Path.home() / ".lemontropia" / "demo_screenshot.png"
demo_path.parent.mkdir(parents=True, exist_ok=True)
cv2.imwrite(str(demo_path), demo_img)
result = vision.process_screenshot(demo_path)
print(f"\n--- Demo Results ---")
print(f"Processing Time: {result.processing_time_ms:.1f}ms")
print(f"Text Regions: {len(result.text_regions)}")
print(f"Icon Regions: {len(result.icon_regions)}")
print(f"\nUsage: python vision_example.py --full path/to/screenshot.png")
def demo_backend_switching():
"""Demonstrate switching between OCR backends."""
print("\n" + "="*60)
print("OCR BACKEND SWITCHING DEMO")
print("="*60)
from modules.game_vision_ai import UnifiedOCRProcessor
import cv2
import numpy as np
# Create demo image
demo_img = np.ones((400, 600, 3), dtype=np.uint8) * 255
cv2.rectangle(demo_img, (50, 50), (200, 80), (0, 0, 0), -1)
cv2.rectangle(demo_img, (50, 100), (250, 130), (0, 0, 0), -1)
# Initialize with auto-selection
print("\nInitializing with auto-selected backend...")
ocr = UnifiedOCRProcessor()
print(f"Default backend: {ocr.get_current_backend()}")
# Try switching to each backend
backends = ['opencv_east', 'tesseract', 'easyocr', 'paddleocr']
for backend_name in backends:
print(f"\nTrying '{backend_name}'...", end=" ")
success = ocr.set_backend(backend_name)
if success:
print(f"✅ Success!")
regions = ocr.extract_text(demo_img)
print(f" Detected {len(regions)} text regions")
else:
print(f"❌ Not available (see error above)")
def demo_icon_matching():
"""Demonstrate icon matching."""
print("\n" + "="*60)
print("ICON MATCHING DEMO")
print("="*60)
from modules.icon_matcher import IconMatcher, PerceptualHash
import cv2
import numpy as np
# Create matcher
matcher = IconMatcher()
print(f"\nIcon Database Stats:")
stats = matcher.get_database_stats()
print(f" Total Icons: {stats['total_icons']}")
print(f" Database Path: {stats['database_path']}")
# Demonstrate perceptual hashing
print(f"\nPerceptual Hashing:")
# Create a sample image
sample = np.random.randint(0, 255, (64, 64, 3), dtype=np.uint8)
avg_hash = PerceptualHash.average_hash(sample)
diff_hash = PerceptualHash.difference_hash(sample)
print(f" Average Hash: {avg_hash[:32]}...")
print(f" Difference Hash: {diff_hash[:32]}...")
# Show similarity calculation
similar = np.random.randint(0, 255, (64, 64, 3), dtype=np.uint8)
similar[20:40, 20:40] = sample[20:40, 20:40] # Make it somewhat similar
hash1 = PerceptualHash.average_hash(sample)
hash2 = PerceptualHash.average_hash(similar)
similarity = PerceptualHash.similarity(hash1, hash2)
print(f" Similarity between two images: {similarity:.2%}")
def demo_diagnostics():
"""Demonstrate system diagnostics."""
print("\n" + "="*60)
print("SYSTEM DIAGNOSTICS DEMO")
print("="*60)
from modules.game_vision_ai import GameVisionAI
print("\nRunning full system diagnostics...")
diag = GameVisionAI.diagnose()
print("\n--- Hardware ---")
hw = diag['hardware']
print(f" Platform: {hw['system']['platform']}")
print(f" Windows Store Python: {hw['system']['windows_store']}")
print(f" GPU Backend: {hw['gpu']['backend']}")
print(f" CUDA Available: {hw['gpu']['cuda_available']}")
print(f" OpenCV CUDA: {hw['gpu']['opencv_cuda']}")
print("\n--- ML Frameworks ---")
ml = hw['ml_frameworks']
print(f" PyTorch: {'Available' if ml['pytorch']['available'] else 'Not Available'}")
if ml['pytorch']['available']:
print(f" Version: {ml['pytorch']['version']}")
if ml['pytorch']['dll_error']:
print(f" ⚠️ DLL Error detected!")
print("\n--- OCR Backends ---")
for backend in diag['ocr_backends']:
status = "" if backend['available'] else ""
print(f" {status} {backend['name']}")
print("\n--- Recommendations ---")
print(f" OCR Backend: {diag['recommendations']['ocr_backend']}")
print(f" GPU: {diag['recommendations']['gpu']}")
def main():
"""Main entry point."""
import argparse
parser = argparse.ArgumentParser(
description="Game Vision AI Examples",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python vision_example.py --hardware # Hardware detection
python vision_example.py --backends # List OCR backends
python vision_example.py --ocr image.png # OCR demo
python vision_example.py --icons image.png # Icon detection demo
python vision_example.py --full image.png # Full vision demo
python vision_example.py --switch # Backend switching demo
python vision_example.py --matching # Icon matching demo
python vision_example.py --diagnostics # System diagnostics
python vision_example.py --all # Run all demos
"""
)
parser.add_argument('--hardware', action='store_true', help='Hardware detection demo')
parser.add_argument('--backends', action='store_true', help='List OCR backends')
parser.add_argument('--ocr', type=str, metavar='IMAGE', nargs='?', const='', help='OCR demo')
parser.add_argument('--icons', type=str, metavar='IMAGE', nargs='?', const='', help='Icon detection demo')
parser.add_argument('--full', type=str, metavar='IMAGE', nargs='?', const='', help='Full vision demo')
parser.add_argument('--switch', action='store_true', help='Backend switching demo')
parser.add_argument('--matching', action='store_true', help='Icon matching demo')
parser.add_argument('--diagnostics', action='store_true', help='System diagnostics')
parser.add_argument('--all', action='store_true', help='Run all demos')
args = parser.parse_args()
# If no args, show help
if not any([args.hardware, args.backends, args.ocr is not None,
args.icons is not None, args.full is not None,
args.switch, args.matching, args.diagnostics, args.all]):
parser.print_help()
return
try:
if args.all or args.hardware:
demo_hardware_detection()
if args.all or args.backends:
demo_ocr_backends()
if args.all or args.ocr is not None:
demo_ocr(args.ocr if args.ocr else None)
if args.all or args.icons is not None:
demo_icon_detection(args.icons if args.icons else None)
if args.all or args.full is not None:
demo_full_vision(args.full if args.full else None)
if args.all or args.switch:
demo_backend_switching()
if args.all or args.matching:
demo_icon_matching()
if args.all or args.diagnostics:
demo_diagnostics()
except ImportError as e:
print(f"\n❌ Import Error: {e}")
print("\nMake sure all dependencies are installed:")
print(" pip install opencv-python numpy pillow")
print("\nFor full OCR support:")
print(" pip install easyocr pytesseract paddleocr")
except Exception as e:
print(f"\n❌ Error: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()