File size: 12,530 Bytes
e13eb59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d5e1c5
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
from flask import Flask, request, render_template, send_file, url_for
import os
import cv2
from werkzeug.utils import secure_filename
from FULLSYSTEM import classifyDisease, lesionDetection
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import Paragraph, Spacer, Image, Table, TableStyle
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from datetime import datetime
from FULLSYSTEM import *
app = Flask(__name__)

# Configuration
UPLOAD_FOLDER = 'static/uploads/'
RESULT_FOLDER = 'static/results/'
PDF_FOLDER = 'static/pdfs/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['RESULT_FOLDER'] = RESULT_FOLDER
app.config['PDF_FOLDER'] = PDF_FOLDER

# Create folders if not exist
for folder in [UPLOAD_FOLDER, RESULT_FOLDER, PDF_FOLDER]:
    os.makedirs(folder, exist_ok=True)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Enhanced grade mappings with detailed descriptions
GRADE_INFO = {
    0: (
        "No Diabetic Retinopathy", 
        "No signs of diabetic retinopathy detected. Continue regular annual eye examinations.",
        "DR is not present at this stage. The retina appears healthy with no visible abnormalities."
    ),
    1: (
        "Mild Non-Proliferative Diabetic Retinopathy (NPDR)", 
        "Early stage detected. Monitor blood sugar levels closely and follow up with your ophthalmologist in 9-12 months.",
        "Characterized by the presence of at least one microaneurysm (small blood vessel bulges) in the retina. These tiny red dots are the earliest clinically visible sign of diabetic retinopathy."
    ),
    2: (
        "Moderate Non-Proliferative Diabetic Retinopathy", 
        "Progressive stage detected. Schedule a comprehensive eye examination within 6 months and maintain strict glycemic control.",
        "More microaneurysms are present along with other signs such as dot and blot hemorrhages, hard exudates (lipid deposits), and cotton wool spots (nerve fiber layer infarcts)."
    ),
    3: (
        "Severe Non-Proliferative Diabetic Retinopathy", 
        "Advanced stage detected. Immediate consultation with an ophthalmologist is necessary. Risk of progression to PDR is significant.",
        "Characterized by the 4-2-1 rule: extensive intraretinal hemorrhages in 4 quadrants, venous beading in 2+ quadrants, or intraretinal microvascular abnormalities (IRMA) in 1+ quadrant. The blood vessels are severely damaged and blocked."
    ),
    4: (
        "Proliferative Diabetic Retinopathy (PDR)", 
        "Critical stage detected. Urgent specialist treatment required! High risk of vision loss without immediate intervention.",
        "New abnormal blood vessels grow on the retina or optic disc (neovascularization) due to severe ischemia. These vessels are fragile and can leak blood, causing vitreous hemorrhage, and may lead to retinal detachment and blindness if untreated."
    )
}

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return "No file part", 400
        file = request.files['file']
        if file.filename == '':
            return "No selected file", 400
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            save_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(save_path)

            # Predict class
            grade = classifyDisease(clsmodel, save_path)

            # Predict segmentation (returns cv2 image)
            segimage = lesionDetection(save_path, segmodel)

            # Save segmented image
            seg_filename = os.path.splitext(filename)[0] + '_segmented.png'
            seg_save_path = os.path.join(app.config['RESULT_FOLDER'], seg_filename)
            cv2.imwrite(seg_save_path, segimage)

            # Get grade name, advice, and description
            grade_name, advice, description = GRADE_INFO.get(grade, ("Unknown", "Consult doctor.", "Unable to determine severity."))

            # Generate PDF report
            pdf_filename = os.path.splitext(filename)[0] + '_report.pdf'
            pdf_path = os.path.join(app.config['PDF_FOLDER'], pdf_filename)
            
            # Pass original and segmented image paths to PDF generator
            original_image_path = save_path
            segmented_image_path = seg_save_path
            
            generate_pdf_report(pdf_path, filename, grade, grade_name, advice, description, original_image_path, segmented_image_path)

            # Pass everything to template
            return render_template('result.html',
                                   original_image=url_for('static', filename='uploads/' + filename),
                                   segmented_image=url_for('static', filename='results/' + seg_filename),
                                   grade=grade,
                                   grade_name=grade_name,
                                   advice=advice,
                                   description=description,
                                   pdf_url=url_for('download_file', filename='pdfs/' + pdf_filename))
    return render_template('index.html')

@app.route('/download/<path:filename>')
def download_file(filename):
    return send_file(os.path.join('static', filename), as_attachment=True)

def generate_pdf_report(filepath, image_name, grade, grade_name, advice, description, original_image_path, segmented_image_path):
    doc = SimpleDocTemplate(filepath, pagesize=letter)
    styles = getSampleStyleSheet()
    story = []
    
    # Create custom styles
    title_style = ParagraphStyle(
        'Title',
        parent=styles['Heading1'],
        fontSize=20,
        alignment=1,  # Center alignment
        spaceAfter=20
    )
    
    section_heading = ParagraphStyle(
        'SectionHeading',
        parent=styles['Heading2'],
        fontSize=16,
        textColor=colors.darkblue,
        spaceAfter=10
    )
    
    normal_text = ParagraphStyle(
        'BodyText',
        parent=styles['Normal'],
        fontSize=11,
        spaceAfter=8
    )
    
    disclaimer_style = ParagraphStyle(
        'Disclaimer',
        parent=styles['Italic'],
        fontSize=9,
        textColor=colors.darkgrey,
        alignment=1  # Center alignment
    )
    
    # Add title
    title = Paragraph("<b>DIABETIC RETINOPATHY ASSESSMENT REPORT</b>", title_style)
    story.append(title)
    
    # Add current date
    current_date = datetime.now().strftime("%B %d, %Y")
    date_text = Paragraph(f"<b>Report Date:</b> {current_date}", normal_text)
    story.append(date_text)
    story.append(Spacer(1, 0.2*inch))
    
    # Patient information section
    story.append(Paragraph("<b>PATIENT INFORMATION</b>", section_heading))
    story.append(Paragraph(f"<b>Image Filename:</b> {image_name}", normal_text))
    story.append(Paragraph("<b>Patient ID:</b> For clinical use, please enter patient information", normal_text))
    story.append(Spacer(1, 0.2*inch))
    
    # Results section
    story.append(Paragraph("<b>ANALYSIS RESULTS</b>", section_heading))
    
    # Create severity indicator
    severity_table_data = [[f"Grade {grade}: {grade_name}"]]
    severity_table = Table(severity_table_data, colWidths=[6*inch])
    
    # Color code based on severity
    if grade == 0:
        bg_color = colors.lightgreen
    elif grade == 1:
        bg_color = colors.lightblue
    elif grade == 2:
        bg_color = colors.yellow
    elif grade == 3:
        bg_color = colors.orange
    else:  # grade 4
        bg_color = colors.red
    
    severity_table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), bg_color),
        ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('FONTNAME', (0, 0), (-1, -1), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 14),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
        ('TOPPADDING', (0, 0), (-1, -1), 8),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ]))
    story.append(severity_table)
    story.append(Spacer(1, 0.2*inch))
    
    # Detailed description
    story.append(Paragraph("<b>Clinical Description:</b>", normal_text))
    story.append(Paragraph(description, normal_text))
    story.append(Spacer(1, 0.1*inch))
    
    # Medical advice
    story.append(Paragraph("<b>Medical Advice:</b>", normal_text))
    story.append(Paragraph(advice, normal_text))
    story.append(Spacer(1, 0.3*inch))
    
    # Add images
    story.append(Paragraph("<b>RETINAL IMAGES</b>", section_heading))
    
    # Create a table for side-by-side images
    image_width = 2.0*inch
    image_height = 2.0*inch
    
    # Resize images to fit properly
    try:
        orig_img = Image(original_image_path, width=image_width, height=image_height)
        seg_img = Image(segmented_image_path, width=image_width, height=image_height)
        
        image_table_data = [
            [Paragraph("<b>Original Image</b>", normal_text), Paragraph("<b>AI-Processed Image with Lesions</b>", normal_text)],
            [orig_img, seg_img]
        ]
        
        image_table = Table(image_table_data, colWidths=[3*inch, 3*inch])
        image_table.setStyle(TableStyle([
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.lightgrey),
            ('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey),
            ('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 5),
            ('TOPPADDING', (0, 0), (-1, -1), 5),
        ]))
        story.append(image_table)
    except Exception as e:
        story.append(Paragraph(f"Error loading images: {str(e)}", normal_text))
    
    story.append(Spacer(1, 0.3*inch))
    
    # Information about diabetic retinopathy
    story.append(Paragraph("<b>ABOUT DIABETIC RETINOPATHY</b>", section_heading))
    
    dr_info = """
    <b>What is Diabetic Retinopathy?</b><br/>
    Diabetic retinopathy is a diabetes complication that affects the eyes. It's caused by damage to the blood vessels in the retina (the light-sensitive tissue at the back of the eye). Over time, too much sugar in the blood can lead to blockage of the tiny blood vessels that nourish the retina, cutting off its blood supply. As a result, the eye attempts to grow new blood vessels, but these don't develop properly.
    <br/><br/>
    <b>Stages of Diabetic Retinopathy:</b><br/>
    <b>1. No Diabetic Retinopathy (Grade 0):</b> No abnormalities detected.<br/>
    <b>2. Mild NPDR (Grade 1):</b> Microaneurysms (small swellings in blood vessels) appear.<br/>
    <b>3. Moderate NPDR (Grade 2):</b> Some blood vessels that nourish the retina become blocked.<br/>
    <b>4. Severe NPDR (Grade 3):</b> Many blood vessels are blocked, depriving several areas of the retina of blood supply.<br/>
    <b>5. Proliferative DR (Grade 4):</b> New, abnormal blood vessels grow (proliferate) in the retina, which can leak and cause severe vision problems.
    """
    story.append(Paragraph(dr_info, normal_text))
    story.append(Spacer(1, 0.2*inch))
    
    # Disclaimer
    story.append(Paragraph("<b>DISCLAIMER</b>", section_heading))
    disclaimer_text = """
    This report is generated by an automated Diabetic Retinopathy Detection System using artificial intelligence 
    algorithms to analyze retinal images. The results provided are meant to assist healthcare professionals 
    and should NOT be used as the sole basis for medical decisions. This report MUST be reviewed and verified by a 
    qualified ophthalmologist or healthcare professional before any treatment decisions are made. Early detection 
    and treatment of diabetic retinopathy can significantly reduce the risk of vision loss.
    """
    story.append(Paragraph(disclaimer_text, normal_text))
    
    # Footer
    story.append(Spacer(1, 0.5*inch))
    footer_text = "© Diabetic Retinopathy Detection System | Generated automatically | Page 1"
    story.append(Paragraph(footer_text, disclaimer_style))
    
    # Build the PDF
    doc.build(story)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=7860, debug=True)