Spaces:
Runtime error
Runtime error
File size: 3,576 Bytes
430a6c7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
import cv2
import numpy as np
import pytesseract
import requests
import pandas as pd
import gradio as gr
from io import BytesIO
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 1. Utility: Detect rectangular contours (approximate book covers)
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def detect_book_regions(image: np.ndarray, min_area=10000, eps_coef=0.02):
"""
Detect rectangular regions in an image that likely correspond to book covers.
Returns a list of bounding boxes: (x, y, w, h).
"""
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 50, 150)
# Dilate + erode to close gaps
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
boxes = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area < min_area:
continue
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, eps_coef * peri, True)
# Keep only quadrilaterals
if len(approx) == 4:
x, y, w, h = cv2.boundingRect(approx)
ar = w / float(h)
# Filter by typical book-cover aspect ratios
if 0.4 < ar < 0.9 or 1.0 < ar < 1.6:
boxes.append((x, y, w, h))
# Sort leftβright, topβbottom
boxes = sorted(boxes, key=lambda b: (b[1], b[0]))
return boxes
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 2. OCR on a cropped region
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def ocr_on_region(image: np.ndarray, box: tuple):
"""
Crop the image to the given box and run Tesseract OCR.
Return the raw OCR text.
"""
x, y, w, h = box
cropped = image[y:y+h, x:x+w]
gray_crop = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY)
_, thresh_crop = cv2.threshold(gray_crop, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
custom_config = r'--oem 3 --psm 6'
text = pytesseract.image_to_string(thresh_crop, config=custom_config)
return text.strip()
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 3. Query OpenLibrary API
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def query_openlibrary(title_text: str, author_text: str = None):
"""
Search OpenLibrary by title (and optional author).
Return a dict with title, author_name, publisher, first_publish_year, or None.
"""
base_url = "https://openlibrary.org/search.json"
params = {"title": title_text}
if author_text:
params["author"] = author_text
try:
resp = requests.get(base_url, params=params, timeout=5) |