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))