-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmetadata_extractor.py
More file actions
127 lines (102 loc) · 4.2 KB
/
Copy pathmetadata_extractor.py
File metadata and controls
127 lines (102 loc) · 4.2 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#import cv2
#import pytesseract
#import re
#from datetime import datetime
#from dateutil import parser
import cv2
import pytesseract
import numpy as np
import logging
from io import BytesIO
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def preprocess_image(image_path):
"""Preprocess the image for better OCR results."""
# Read the image
img = cv2.imread(image_path)
if img is None:
raise ValueError(f"Could not read image at {image_path}")
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply thresholding to preprocess the image
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Apply dilation to connect text components
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
gray = cv2.dilate(gray, kernel, iterations=1)
return gray
def extract_text(image_path):
"""Extract text from image using Tesseract OCR."""
try:
# Preprocess the image
processed_img = preprocess_image(image_path)
# Use Tesseract to extract text
custom_config = r'--oem 3 --psm 6'
text = pytesseract.image_to_string(processed_img, config=custom_config)
return text.strip()
except Exception as e:
print(f"Error extracting text: {str(e)}")
return ""
def extract_isbn(text):
"""Extract ISBN from text using regex patterns."""
# Common ISBN patterns (10 or 13 digits, with optional hyphens/spaces)
isbn_patterns = [
r'\b(?:ISBN(?:-1[03])?:?\s*)?(97[89][-\s]?\d{1,5}[-\s]?\d{1,7}[-\s]?\d{1,6}[-\s]?\d)\b', # ISBN-13
r'\b(?:ISBN(?:-10)?:?\s*)?(\d{1,5}[-\s]?\d{1,7}[-\s]?\d{1,6}[-\s]?[\dX])\b' # ISBN-10
]
for pattern in isbn_patterns:
match = re.search(pattern, text, re.IGNORECASE)
if match:
# Clean up the matched ISBN
isbn = re.sub(r'[^\dX]', '', match.group(1)).upper()
# Validate ISBN length (10 or 13 digits)
if len(isbn) in (10, 13):
return isbn
return None
def extract_publication_date(text):
"""Extract publication date from text."""
# Look for years in the text (1900-2099)
year_matches = re.findall(r'\b(19\d{2}|20[0-9]{2})\b', text)
if year_matches:
try:
# Get the most recent year (likely the publication year)
years = [int(y) for y in year_matches]
most_recent_year = max(years)
# Only return if it's a reasonable year
if 1900 <= most_recent_year <= datetime.now().year + 1:
return str(most_recent_year)
except (ValueError, IndexError):
pass
return None
def extract_metadata(file_obj):
try:
# Ensure we're at the start of the file
file_obj.seek(0)
# Convert file object to bytes
file_bytes = file_obj.read()
# Convert to numpy array for OpenCV
nparr = np.frombuffer(file_bytes, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
return {"error": "Could not process the image"}
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply thresholding
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Try different page segmentation modes
custom_config = r'--oem 3 --psm 6'
text = pytesseract.image_to_string(gray, config=custom_config)
if not text.strip():
# Try with a different page segmentation mode
custom_config = r'--oem 3 --psm 3'
text = pytesseract.image_to_string(gray, config=custom_config)
if not text.strip():
return {"error": "No text could be extracted from the image"}
# For now, return the first 200 characters of extracted text
# You can add your metadata extraction logic here
return {
"text_sample": text[:200],
"filename": getattr(file_obj, 'filename', 'unknown')
}
except Exception as e:
return {"error": f"Error processing image: {str(e)}"}