""" Gradio interface for Book Cover Analyzer - optimized for Hugging Face Spaces """ import gradio as gr from analyzer.book_analyzer import BookCoverAnalyzer from PIL import Image import tempfile import os # Initialize analyzer once (loads models) print("Loading models... This may take 30-60 seconds on first run.") analyzer = BookCoverAnalyzer(verbose=True) print("Models loaded successfully!") def analyze_book_cover(image): """Analyze uploaded book cover image""" if image is None: return "Please upload an image.", "", "", "", "" tmp_path = None try: # Save PIL Image to temporary file (analyzer expects file path) with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as tmp: image.save(tmp.name, format='JPEG') tmp_path = tmp.name # Analyze result = analyzer.analyze(tmp_path) # Check if analysis succeeded if not result.get('success', False): error = result.get('error', 'Unknown error') return f"Analysis failed: {error}", "", "", "", "" # Extract interpretation interp = result.get('interpretation', {}) # Format outputs title = interp.get('inferred_title') or "Unable to determine" authors = ", ".join(interp.get('inferred_authors', [])) or "Unable to determine" publisher = interp.get('inferred_publisher') or "Unable to determine" # Format detected elements image_regions = result.get('image_regions', []) if image_regions: elements_text = f"**Detected {len(image_regions)} visual elements:**\n" for elem in image_regions[:5]: # Top 5 elements_text += f"- {elem['location']}: {elem['pytorch_class']} ({elem['confidence']:.1%})\n" else: elements_text = "No visual elements detected (possibly plain text cover)" # Format detected text text_regions = result.get('text_regions', []) if text_regions: text_output = f"**Detected {len(text_regions)} text regions:**\n" for region in text_regions[:10]: # Top 10 text_output += f"- {region['text']}\n" # Format other text (reviews/quotes) other = interp.get('other_text', []) if other: text_output += f"\n**Reviews/Quotes:**\n" for text in other[:3]: text_output += f"- {text}\n" else: text_output = "No text detected on cover" return title, authors, publisher, elements_text, text_output except Exception as e: error_msg = f"Error analyzing image: {str(e)}" return error_msg, "", "", "", "" finally: # Always clean up temp file, even if there's an error if tmp_path and os.path.exists(tmp_path): try: os.unlink(tmp_path) except: pass # Ignore cleanup errors # Create Gradio interface demo = gr.Interface( fn=analyze_book_cover, inputs=gr.Image(type="pil", label="Upload Book Cover"), outputs=[ gr.Textbox(label="📚 Book Title", lines=2), gr.Textbox(label="✍️ Author(s)", lines=2), gr.Textbox(label="🏢 Publisher", lines=1), gr.Textbox(label="🖼️ Visual Elements (ImageNet Classification)", lines=8), gr.Textbox(label="📝 Detected Text (EasyOCR)", lines=15) ], title="📖 Book Cover Analyzer", description=""" Upload a book cover image to automatically detect: - **Book title, author, publisher** (inferred from text) - **Visual elements** (classified using ResNet18) - **All text regions** (extracted using EasyOCR) Powered by OpenCV, PyTorch, and EasyOCR. """, examples=[ # You can add example images here if you want ], theme="soft" ) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)