mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
better error handling and correct image call for top 25
This commit is contained in:
103
test/README_broadcast_logo_analyzer.md
Normal file
103
test/README_broadcast_logo_analyzer.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Broadcast Logo Analyzer
|
||||
|
||||
This script analyzes broadcast channel logos to ensure we have proper logos for every game and identifies missing or problematic logos that might show as white boxes.
|
||||
|
||||
## Important Notes
|
||||
|
||||
**This script must be run on the Raspberry Pi** where the LEDMatrix project is located, as it needs to access the actual logo files in the `assets/broadcast_logos/` directory.
|
||||
|
||||
## Usage
|
||||
|
||||
### On Raspberry Pi (Recommended)
|
||||
|
||||
```bash
|
||||
# SSH into your Raspberry Pi
|
||||
ssh pi@your-pi-ip
|
||||
|
||||
# Navigate to the LEDMatrix project directory
|
||||
cd /path/to/LEDMatrix
|
||||
|
||||
# Run the analyzer
|
||||
python test/analyze_broadcast_logos.py
|
||||
```
|
||||
|
||||
### Local Testing (Optional)
|
||||
|
||||
If you want to test the script logic locally, you can:
|
||||
|
||||
1. Copy some logo files from your Pi to your local machine
|
||||
2. Place them in `assets/broadcast_logos/` directory
|
||||
3. Run the script locally
|
||||
|
||||
## What the Script Does
|
||||
|
||||
1. **Checks Logo Mappings**: Verifies all broadcast channel names in `BROADCAST_LOGO_MAP` have corresponding logo files
|
||||
2. **Validates File Existence**: Ensures all referenced logo files actually exist
|
||||
3. **Analyzes Logo Quality**:
|
||||
- Checks dimensions (too small/large)
|
||||
- Analyzes transparency handling
|
||||
- Detects potential white box issues
|
||||
- Measures content density
|
||||
4. **Identifies Issues**:
|
||||
- Missing logos
|
||||
- Problematic logos (corrupted, too transparent, etc.)
|
||||
- Orphaned logo files (exist but not mapped)
|
||||
5. **Generates Report**: Creates both console output and JSON report
|
||||
|
||||
## Output
|
||||
|
||||
The script generates:
|
||||
- **Console Report**: Detailed analysis with recommendations
|
||||
- **JSON Report**: `test/broadcast_logo_analysis.json` with structured data
|
||||
|
||||
## Common Issues Found
|
||||
|
||||
- **White Boxes**: Usually caused by:
|
||||
- Missing logo files
|
||||
- Corrupted image files
|
||||
- Images that are mostly transparent
|
||||
- Images with very low content density
|
||||
- **Missing Logos**: Broadcast channels that don't have corresponding logo files
|
||||
- **Orphaned Logos**: Logo files that exist but aren't mapped to any broadcast channel
|
||||
|
||||
## Recommendations
|
||||
|
||||
The script provides specific recommendations for each issue found, such as:
|
||||
- Adding missing logo files
|
||||
- Fixing problematic logos
|
||||
- Optimizing logo dimensions
|
||||
- Ensuring proper transparency handling
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
BROADCAST LOGO ANALYSIS REPORT
|
||||
================================================================================
|
||||
|
||||
SUMMARY:
|
||||
Total broadcast mappings: 44
|
||||
Existing logos: 40
|
||||
Missing logos: 2
|
||||
Problematic logos: 2
|
||||
Orphaned logos: 1
|
||||
|
||||
MISSING LOGOS (2):
|
||||
--------------------------------------------------
|
||||
New Channel -> newchannel.png
|
||||
Expected: /path/to/LEDMatrix/assets/broadcast_logos/newchannel.png
|
||||
|
||||
PROBLEMATIC LOGOS (2):
|
||||
--------------------------------------------------
|
||||
ESPN -> espn
|
||||
Issue: Very low content density: 2.1%
|
||||
Recommendation: Logo may appear as a white box - check content
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you see errors about missing dependencies:
|
||||
```bash
|
||||
pip install Pillow
|
||||
```
|
||||
|
||||
If the script can't find the broadcast logos directory, ensure you're running it from the LEDMatrix project root directory.
|
||||
418
test/analyze_broadcast_logos.py
Normal file
418
test/analyze_broadcast_logos.py
Normal file
@@ -0,0 +1,418 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Broadcast Logo Analyzer
|
||||
|
||||
This script analyzes broadcast channel logos to ensure we have proper logos
|
||||
for every game and identifies missing or problematic logos that might show
|
||||
as white boxes.
|
||||
|
||||
IMPORTANT: This script must be run on the Raspberry Pi where the LEDMatrix
|
||||
project is located, as it needs to access the actual logo files in the
|
||||
assets/broadcast_logos/ directory.
|
||||
|
||||
Usage (on Raspberry Pi):
|
||||
python test/analyze_broadcast_logos.py
|
||||
|
||||
Features:
|
||||
- Checks all broadcast logos referenced in BROADCAST_LOGO_MAP
|
||||
- Validates logo file existence and integrity
|
||||
- Analyzes logo dimensions and transparency
|
||||
- Identifies potential white box issues
|
||||
- Provides recommendations for missing logos
|
||||
- Generates a detailed report
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Set, Tuple, Optional
|
||||
from PIL import Image, ImageStat
|
||||
import logging
|
||||
|
||||
# Add the project root to the path so we can import from src
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
# Define the broadcast logo map directly (copied from odds_ticker_manager.py)
|
||||
BROADCAST_LOGO_MAP = {
|
||||
"ACC Network": "accn",
|
||||
"ACCN": "accn",
|
||||
"ABC": "abc",
|
||||
"BTN": "btn",
|
||||
"CBS": "cbs",
|
||||
"CBSSN": "cbssn",
|
||||
"CBS Sports Network": "cbssn",
|
||||
"ESPN": "espn",
|
||||
"ESPN2": "espn2",
|
||||
"ESPN3": "espn3",
|
||||
"ESPNU": "espnu",
|
||||
"ESPNEWS": "espn",
|
||||
"ESPN+": "espn",
|
||||
"ESPN Plus": "espn",
|
||||
"FOX": "fox",
|
||||
"FS1": "fs1",
|
||||
"FS2": "fs2",
|
||||
"MLBN": "mlbn",
|
||||
"MLB Network": "mlbn",
|
||||
"MLB.TV": "mlbn",
|
||||
"NBC": "nbc",
|
||||
"NFLN": "nfln",
|
||||
"NFL Network": "nfln",
|
||||
"PAC12": "pac12n",
|
||||
"Pac-12 Network": "pac12n",
|
||||
"SECN": "espn-sec-us",
|
||||
"TBS": "tbs",
|
||||
"TNT": "tnt",
|
||||
"truTV": "tru",
|
||||
"Peacock": "nbc",
|
||||
"Paramount+": "cbs",
|
||||
"Hulu": "espn",
|
||||
"Disney+": "espn",
|
||||
"Apple TV+": "nbc",
|
||||
# Regional sports networks
|
||||
"MASN": "cbs",
|
||||
"MASN2": "cbs",
|
||||
"MAS+": "cbs",
|
||||
"SportsNet": "nbc",
|
||||
"FanDuel SN": "fox",
|
||||
"FanDuel SN DET": "fox",
|
||||
"FanDuel SN FL": "fox",
|
||||
"SportsNet PIT": "nbc",
|
||||
"Padres.TV": "espn",
|
||||
"CLEGuardians.TV": "espn"
|
||||
}
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BroadcastLogoAnalyzer:
|
||||
"""Analyzes broadcast channel logos for completeness and quality."""
|
||||
|
||||
def __init__(self, project_root: Path):
|
||||
self.project_root = project_root
|
||||
self.broadcast_logos_dir = project_root / "assets" / "broadcast_logos"
|
||||
self.results = {
|
||||
'total_mappings': len(BROADCAST_LOGO_MAP),
|
||||
'existing_logos': [],
|
||||
'missing_logos': [],
|
||||
'problematic_logos': [],
|
||||
'recommendations': []
|
||||
}
|
||||
|
||||
def analyze_all_logos(self) -> Dict:
|
||||
"""Perform comprehensive analysis of all broadcast logos."""
|
||||
logger.info("Starting broadcast logo analysis...")
|
||||
|
||||
# Get all logo files that exist
|
||||
existing_files = self._get_existing_logo_files()
|
||||
logger.info(f"Found {len(existing_files)} existing logo files")
|
||||
|
||||
# Check each mapping in BROADCAST_LOGO_MAP
|
||||
for broadcast_name, logo_filename in BROADCAST_LOGO_MAP.items():
|
||||
self._analyze_logo_mapping(broadcast_name, logo_filename, existing_files)
|
||||
|
||||
# Check for orphaned logo files (files that exist but aren't mapped)
|
||||
self._check_orphaned_logos(existing_files)
|
||||
|
||||
# Generate recommendations
|
||||
self._generate_recommendations()
|
||||
|
||||
return self.results
|
||||
|
||||
def _get_existing_logo_files(self) -> Set[str]:
|
||||
"""Get all existing logo files in the broadcast_logos directory."""
|
||||
existing_files = set()
|
||||
|
||||
if not self.broadcast_logos_dir.exists():
|
||||
logger.warning(f"Broadcast logos directory does not exist: {self.broadcast_logos_dir}")
|
||||
return existing_files
|
||||
|
||||
for file_path in self.broadcast_logos_dir.iterdir():
|
||||
if file_path.is_file() and file_path.suffix.lower() in ['.png', '.jpg', '.jpeg']:
|
||||
existing_files.add(file_path.stem) # filename without extension
|
||||
|
||||
return existing_files
|
||||
|
||||
def _analyze_logo_mapping(self, broadcast_name: str, logo_filename: str, existing_files: Set[str]):
|
||||
"""Analyze a single logo mapping."""
|
||||
logo_path = self.broadcast_logos_dir / f"{logo_filename}.png"
|
||||
|
||||
if logo_filename not in existing_files:
|
||||
self.results['missing_logos'].append({
|
||||
'broadcast_name': broadcast_name,
|
||||
'logo_filename': logo_filename,
|
||||
'expected_path': str(logo_path)
|
||||
})
|
||||
logger.warning(f"Missing logo: {broadcast_name} -> {logo_filename}.png")
|
||||
return
|
||||
|
||||
# Logo exists, analyze its quality
|
||||
try:
|
||||
analysis = self._analyze_logo_quality(logo_path, broadcast_name, logo_filename)
|
||||
if analysis['is_problematic']:
|
||||
self.results['problematic_logos'].append(analysis)
|
||||
else:
|
||||
self.results['existing_logos'].append(analysis)
|
||||
except Exception as e:
|
||||
logger.error(f"Error analyzing logo {logo_path}: {e}")
|
||||
self.results['problematic_logos'].append({
|
||||
'broadcast_name': broadcast_name,
|
||||
'logo_filename': logo_filename,
|
||||
'path': str(logo_path),
|
||||
'error': str(e),
|
||||
'is_problematic': True
|
||||
})
|
||||
|
||||
def _analyze_logo_quality(self, logo_path: Path, broadcast_name: str, logo_filename: str) -> Dict:
|
||||
"""Analyze the quality of a logo file."""
|
||||
try:
|
||||
with Image.open(logo_path) as img:
|
||||
# Basic image info
|
||||
width, height = img.size
|
||||
mode = img.mode
|
||||
|
||||
# Convert to RGBA for analysis if needed
|
||||
if mode != 'RGBA':
|
||||
img_rgba = img.convert('RGBA')
|
||||
else:
|
||||
img_rgba = img
|
||||
|
||||
# Analyze for potential white box issues
|
||||
analysis = {
|
||||
'broadcast_name': broadcast_name,
|
||||
'logo_filename': logo_filename,
|
||||
'path': str(logo_path),
|
||||
'dimensions': (width, height),
|
||||
'mode': mode,
|
||||
'file_size': logo_path.stat().st_size,
|
||||
'is_problematic': False,
|
||||
'issues': [],
|
||||
'recommendations': []
|
||||
}
|
||||
|
||||
# Check for white box issues
|
||||
self._check_white_box_issues(img_rgba, analysis)
|
||||
|
||||
# Check dimensions
|
||||
self._check_dimensions(width, height, analysis)
|
||||
|
||||
# Check transparency
|
||||
self._check_transparency(img_rgba, analysis)
|
||||
|
||||
# Check if image is mostly empty/white
|
||||
self._check_content_density(img_rgba, analysis)
|
||||
|
||||
return analysis
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"Failed to analyze image: {e}")
|
||||
|
||||
def _check_white_box_issues(self, img: Image.Image, analysis: Dict):
|
||||
"""Check for potential white box issues."""
|
||||
# Get image statistics
|
||||
stat = ImageStat.Stat(img)
|
||||
|
||||
# Check if image is mostly white
|
||||
if img.mode == 'RGBA':
|
||||
# For RGBA, check RGB channels
|
||||
r_mean, g_mean, b_mean = stat.mean[:3]
|
||||
if r_mean > 240 and g_mean > 240 and b_mean > 240:
|
||||
analysis['issues'].append("Image appears to be mostly white")
|
||||
analysis['is_problematic'] = True
|
||||
|
||||
# Check for completely transparent images
|
||||
if img.mode == 'RGBA':
|
||||
alpha_channel = img.split()[3]
|
||||
alpha_stat = ImageStat.Stat(alpha_channel)
|
||||
if alpha_stat.mean[0] < 10: # Very low alpha
|
||||
analysis['issues'].append("Image is mostly transparent")
|
||||
analysis['is_problematic'] = True
|
||||
|
||||
def _check_dimensions(self, width: int, height: int, analysis: Dict):
|
||||
"""Check if dimensions are reasonable."""
|
||||
if width < 16 or height < 16:
|
||||
analysis['issues'].append(f"Very small dimensions: {width}x{height}")
|
||||
analysis['is_problematic'] = True
|
||||
analysis['recommendations'].append("Consider using a higher resolution logo")
|
||||
|
||||
if width > 512 or height > 512:
|
||||
analysis['issues'].append(f"Very large dimensions: {width}x{height}")
|
||||
analysis['recommendations'].append("Consider optimizing logo size for better performance")
|
||||
|
||||
# Check aspect ratio
|
||||
aspect_ratio = width / height
|
||||
if aspect_ratio > 4 or aspect_ratio < 0.25:
|
||||
analysis['issues'].append(f"Extreme aspect ratio: {aspect_ratio:.2f}")
|
||||
analysis['recommendations'].append("Consider using a more square logo")
|
||||
|
||||
def _check_transparency(self, img: Image.Image, analysis: Dict):
|
||||
"""Check transparency handling."""
|
||||
if img.mode == 'RGBA':
|
||||
# Check if there's any transparency
|
||||
alpha_channel = img.split()[3]
|
||||
alpha_data = list(alpha_channel.getdata())
|
||||
min_alpha = min(alpha_data)
|
||||
max_alpha = max(alpha_data)
|
||||
|
||||
if min_alpha < 255:
|
||||
analysis['recommendations'].append("Logo has transparency - ensure proper background handling")
|
||||
|
||||
if max_alpha < 128:
|
||||
analysis['issues'].append("Logo is very transparent")
|
||||
analysis['is_problematic'] = True
|
||||
|
||||
def _check_content_density(self, img: Image.Image, analysis: Dict):
|
||||
"""Check if the image has sufficient content."""
|
||||
# Convert to grayscale for analysis
|
||||
gray = img.convert('L')
|
||||
|
||||
# Count non-white pixels (assuming white background)
|
||||
pixels = list(gray.getdata())
|
||||
non_white_pixels = sum(1 for p in pixels if p < 240)
|
||||
total_pixels = len(pixels)
|
||||
content_ratio = non_white_pixels / total_pixels
|
||||
|
||||
if content_ratio < 0.05: # Less than 5% content
|
||||
analysis['issues'].append(f"Very low content density: {content_ratio:.1%}")
|
||||
analysis['is_problematic'] = True
|
||||
analysis['recommendations'].append("Logo may appear as a white box - check content")
|
||||
|
||||
def _check_orphaned_logos(self, existing_files: Set[str]):
|
||||
"""Check for logo files that exist but aren't mapped."""
|
||||
mapped_filenames = set(BROADCAST_LOGO_MAP.values())
|
||||
orphaned_files = existing_files - mapped_filenames
|
||||
|
||||
if orphaned_files:
|
||||
self.results['orphaned_logos'] = list(orphaned_files)
|
||||
logger.info(f"Found {len(orphaned_files)} orphaned logo files: {orphaned_files}")
|
||||
|
||||
def _generate_recommendations(self):
|
||||
"""Generate overall recommendations."""
|
||||
recommendations = []
|
||||
|
||||
if self.results['missing_logos']:
|
||||
recommendations.append(f"Add {len(self.results['missing_logos'])} missing logo files")
|
||||
|
||||
if self.results['problematic_logos']:
|
||||
recommendations.append(f"Fix {len(self.results['problematic_logos'])} problematic logos")
|
||||
|
||||
if 'orphaned_logos' in self.results:
|
||||
recommendations.append(f"Consider mapping {len(self.results['orphaned_logos'])} orphaned logo files")
|
||||
|
||||
# General recommendations
|
||||
recommendations.extend([
|
||||
"Ensure all logos are PNG format with transparency support",
|
||||
"Use consistent dimensions (preferably 64x64 or 128x128 pixels)",
|
||||
"Test logos on the actual LED matrix display",
|
||||
"Consider creating fallback logos for missing channels"
|
||||
])
|
||||
|
||||
self.results['recommendations'] = recommendations
|
||||
|
||||
def print_report(self):
|
||||
"""Print a detailed analysis report."""
|
||||
print("\n" + "="*80)
|
||||
print("BROADCAST LOGO ANALYSIS REPORT")
|
||||
print("="*80)
|
||||
|
||||
print(f"\nSUMMARY:")
|
||||
print(f" Total broadcast mappings: {self.results['total_mappings']}")
|
||||
print(f" Existing logos: {len(self.results['existing_logos'])}")
|
||||
print(f" Missing logos: {len(self.results['missing_logos'])}")
|
||||
print(f" Problematic logos: {len(self.results['problematic_logos'])}")
|
||||
|
||||
if 'orphaned_logos' in self.results:
|
||||
print(f" Orphaned logos: {len(self.results['orphaned_logos'])}")
|
||||
|
||||
# Missing logos
|
||||
if self.results['missing_logos']:
|
||||
print(f"\nMISSING LOGOS ({len(self.results['missing_logos'])}):")
|
||||
print("-" * 50)
|
||||
for missing in self.results['missing_logos']:
|
||||
print(f" {missing['broadcast_name']} -> {missing['logo_filename']}.png")
|
||||
print(f" Expected: {missing['expected_path']}")
|
||||
|
||||
# Problematic logos
|
||||
if self.results['problematic_logos']:
|
||||
print(f"\nPROBLEMATIC LOGOS ({len(self.results['problematic_logos'])}):")
|
||||
print("-" * 50)
|
||||
for problematic in self.results['problematic_logos']:
|
||||
print(f" {problematic['broadcast_name']} -> {problematic['logo_filename']}")
|
||||
if 'error' in problematic:
|
||||
print(f" Error: {problematic['error']}")
|
||||
if 'issues' in problematic:
|
||||
for issue in problematic['issues']:
|
||||
print(f" Issue: {issue}")
|
||||
if 'recommendations' in problematic:
|
||||
for rec in problematic['recommendations']:
|
||||
print(f" Recommendation: {rec}")
|
||||
|
||||
# Orphaned logos
|
||||
if 'orphaned_logos' in self.results and self.results['orphaned_logos']:
|
||||
print(f"\nORPHANED LOGOS ({len(self.results['orphaned_logos'])}):")
|
||||
print("-" * 50)
|
||||
for orphaned in self.results['orphaned_logos']:
|
||||
print(f" {orphaned}.png (not mapped in BROADCAST_LOGO_MAP)")
|
||||
|
||||
# Recommendations
|
||||
if self.results['recommendations']:
|
||||
print(f"\nRECOMMENDATIONS:")
|
||||
print("-" * 50)
|
||||
for i, rec in enumerate(self.results['recommendations'], 1):
|
||||
print(f" {i}. {rec}")
|
||||
|
||||
print("\n" + "="*80)
|
||||
|
||||
def save_report(self, output_file: str = "broadcast_logo_analysis.json"):
|
||||
"""Save the analysis results to a JSON file."""
|
||||
output_path = self.project_root / "test" / output_file
|
||||
with open(output_path, 'w') as f:
|
||||
json.dump(self.results, f, indent=2)
|
||||
logger.info(f"Analysis report saved to: {output_path}")
|
||||
|
||||
def main():
|
||||
"""Main function to run the broadcast logo analysis."""
|
||||
print("Broadcast Logo Analyzer")
|
||||
print("=" * 50)
|
||||
|
||||
# Check if we're in the right directory structure
|
||||
if not (project_root / "assets" / "broadcast_logos").exists():
|
||||
print("ERROR: This script must be run from the LEDMatrix project root directory")
|
||||
print(f"Expected directory structure: {project_root}/assets/broadcast_logos/")
|
||||
print("Please run this script on the Raspberry Pi where the LEDMatrix project is located.")
|
||||
print("\nTo test the script logic locally, you can copy some logo files to the expected location.")
|
||||
return 1
|
||||
|
||||
# Initialize analyzer
|
||||
analyzer = BroadcastLogoAnalyzer(project_root)
|
||||
|
||||
# Run analysis
|
||||
try:
|
||||
results = analyzer.analyze_all_logos()
|
||||
|
||||
# Print report
|
||||
analyzer.print_report()
|
||||
|
||||
# Save report
|
||||
analyzer.save_report()
|
||||
|
||||
# Return exit code based on issues found
|
||||
total_issues = len(results['missing_logos']) + len(results['problematic_logos'])
|
||||
if total_issues > 0:
|
||||
print(f"\n⚠️ Found {total_issues} issues that need attention!")
|
||||
return 1
|
||||
else:
|
||||
print(f"\n✅ All broadcast logos are in good condition!")
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Analysis failed: {e}")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
326
test/broadcast_logo_analysis.json
Normal file
326
test/broadcast_logo_analysis.json
Normal file
@@ -0,0 +1,326 @@
|
||||
{
|
||||
"total_mappings": 44,
|
||||
"existing_logos": [],
|
||||
"missing_logos": [],
|
||||
"problematic_logos": [
|
||||
{
|
||||
"broadcast_name": "ACC Network",
|
||||
"logo_filename": "accn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\accn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ACCN",
|
||||
"logo_filename": "accn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\accn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ABC",
|
||||
"logo_filename": "abc",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\abc.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "BTN",
|
||||
"logo_filename": "btn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\btn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "CBS",
|
||||
"logo_filename": "cbs",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "CBSSN",
|
||||
"logo_filename": "cbssn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbssn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "CBS Sports Network",
|
||||
"logo_filename": "cbssn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbssn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPN",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPN2",
|
||||
"logo_filename": "espn2",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn2.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPN3",
|
||||
"logo_filename": "espn3",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn3.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPNU",
|
||||
"logo_filename": "espnu",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espnu.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPNEWS",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPN+",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "ESPN Plus",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "FOX",
|
||||
"logo_filename": "fox",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "FS1",
|
||||
"logo_filename": "fs1",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fs1.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "FS2",
|
||||
"logo_filename": "fs2",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fs2.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "MLBN",
|
||||
"logo_filename": "mlbn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\mlbn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "MLB Network",
|
||||
"logo_filename": "mlbn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\mlbn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "MLB.TV",
|
||||
"logo_filename": "mlbn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\mlbn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "NBC",
|
||||
"logo_filename": "nbc",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "NFLN",
|
||||
"logo_filename": "nfln",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nfln.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "NFL Network",
|
||||
"logo_filename": "nfln",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nfln.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "PAC12",
|
||||
"logo_filename": "pac12n",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\pac12n.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Pac-12 Network",
|
||||
"logo_filename": "pac12n",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\pac12n.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "SECN",
|
||||
"logo_filename": "espn-sec-us",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn-sec-us.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "TBS",
|
||||
"logo_filename": "tbs",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\tbs.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "TNT",
|
||||
"logo_filename": "tnt",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\tnt.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "truTV",
|
||||
"logo_filename": "tru",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\tru.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Peacock",
|
||||
"logo_filename": "nbc",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Paramount+",
|
||||
"logo_filename": "cbs",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Hulu",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Disney+",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Apple TV+",
|
||||
"logo_filename": "nbc",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "MASN",
|
||||
"logo_filename": "cbs",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "MASN2",
|
||||
"logo_filename": "cbs",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "MAS+",
|
||||
"logo_filename": "cbs",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "SportsNet",
|
||||
"logo_filename": "nbc",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "FanDuel SN",
|
||||
"logo_filename": "fox",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "FanDuel SN DET",
|
||||
"logo_filename": "fox",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "FanDuel SN FL",
|
||||
"logo_filename": "fox",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "SportsNet PIT",
|
||||
"logo_filename": "nbc",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "Padres.TV",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
},
|
||||
{
|
||||
"broadcast_name": "CLEGuardians.TV",
|
||||
"logo_filename": "espn",
|
||||
"path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png",
|
||||
"error": "Failed to analyze image: 'Stat' object has no attribute 'min'",
|
||||
"is_problematic": true
|
||||
}
|
||||
],
|
||||
"recommendations": [
|
||||
"Fix 44 problematic logos",
|
||||
"Consider mapping 1 orphaned logo files",
|
||||
"Ensure all logos are PNG format with transparency support",
|
||||
"Use consistent dimensions (preferably 64x64 or 128x128 pixels)",
|
||||
"Test logos on the actual LED matrix display",
|
||||
"Consider creating fallback logos for missing channels"
|
||||
],
|
||||
"orphaned_logos": [
|
||||
"prime"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user