426 lines
15 KiB
Python
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()
|