File size: 4,424 Bytes
e23fe35 |
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 |
import cv2
import numpy as np
import pytesseract
from PIL import Image
import re
class PrescriptionOCR:
def __init__(self):
self.medication_keywords = [
'tablet', 'capsule', 'mg', 'ml', 'injection', 'dose',
'twice', 'thrice', 'daily', 'weekly', 'monthly'
]
def preprocess_image(self, image):
"""Enhanced image preprocessing for medical prescriptions"""
try:
# Convert to numpy array
img_array = np.array(image)
# Convert to grayscale
if len(img_array.shape) == 3:
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
else:
gray = img_array
# Noise removal
denoised = cv2.medianBlur(gray, 3)
# Thresholding
_, thresh = cv2.threshold(denoised, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Morphological operations
kernel = np.ones((2, 2), np.uint8)
processed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
return processed
except Exception as e:
print(f"Image preprocessing error: {e}")
return np.array(image)
def extract_medication_info(self, text):
"""Extract medication information from OCR text"""
medications = []
lines = text.split('\n')
for line in lines:
line_clean = line.strip()
if any(keyword in line_clean.lower() for keyword in self.medication_keywords):
# Extract dosage information
dosage_pattern = r'(\d+\s*(?:mg|ml|tablet|cap)s?)'
dosages = re.findall(dosage_pattern, line_clean, re.IGNORECASE)
# Extract frequency
freq_pattern = r'(?:once|twice|thrice|\d+\s*times)\s*(?:daily|a day|per day)'
frequency = re.findall(freq_pattern, line_clean, re.IGNORECASE)
medication_info = {
'text': line_clean,
'dosages': dosages,
'frequency': frequency[0] if frequency else 'Unknown',
'confidence': 'High' if dosages else 'Medium'
}
medications.append(medication_info)
return medications
def process_prescription(self, image):
"""Main method to process prescription and extract information"""
try:
# Preprocess image
processed_img = self.preprocess_image(image)
# OCR with medical-specific configuration
custom_config = r'--oem 3 --psm 6 -l eng'
extracted_text = pytesseract.image_to_string(processed_img, config=custom_config)
# Extract medication information
medications = self.extract_medication_info(extracted_text)
# Calculate confidence score
confidence = self.calculate_confidence(extracted_text, medications)
return {
'raw_text': extracted_text,
'medications': medications,
'confidence_score': confidence,
'medication_count': len(medications)
}
except Exception as e:
return {
'raw_text': '',
'medications': [],
'confidence_score': 0,
'error': str(e)
}
def calculate_confidence(self, text, medications):
"""Calculate confidence score for OCR extraction"""
if not text.strip():
return 0
# Base score based on text length and medication detection
base_score = min(100, len(text) / 10)
# Bonus for medication detection
medication_bonus = len(medications) * 15
# Penalty for likely errors
error_penalty = 0
if len(text) < 20:
error_penalty += 20
if len(re.findall(r'[^\w\s.,]', text)) > len(text) * 0.3:
error_penalty += 15
final_score = base_score + medication_bonus - error_penalty
return max(0, min(100, final_score)) |