Smartlab_tech / app.py
pavansuresh's picture
Update app.py
97a0169 verified
raw
history blame
7.62 kB
import gradio as gr
import cv2
import numpy as np
from fpdf import FPDF
import tempfile
import os
from paddleocr import PaddleOCR
import time
from simple_salesforce import Salesforce
from datetime import datetime
import boto3
# Initialize PaddleOCR once with updated parameters
ocr_model = PaddleOCR(use_textline_orientation=True, lang='en')
def upload_image_and_get_url(image_path):
"""
Upload the image to AWS S3 and return the public URL.
"""
s3_client = boto3.client(
's3',
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'], # Set environment variable
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'], # Set environment variable
region_name=os.environ['AWS_REGION'] # Set environment variable
)
# Define the S3 bucket name
bucket_name = 'your-bucket-name'
# Generate a unique key for the image (e.g., using the file name)
image_key = f"images/{os.path.basename(image_path)}"
# Upload the image to S3
s3_client.upload_file(image_path, bucket_name, image_key)
# Construct the public URL for the uploaded image
image_url = f"https://{bucket_name}.s3.{os.environ['AWS_REGION']}.amazonaws.com/{image_key}"
return image_url
def analyze_uv_coverage(img, brightness_threshold=150, kernel_size=5, apply_blur=True, adaptive_thresh=False):
"""
Analyze UV sterilization coverage by thresholding the grayscale image.
Optional adaptive thresholding and Gaussian blur for noise reduction.
Morphological operations clean the mask for better accuracy.
"""
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
if apply_blur:
gray = cv2.GaussianBlur(gray, (5, 5), 0)
if adaptive_thresh:
binary_mask = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
11, 2)
else:
_, binary_mask = cv2.threshold(gray, brightness_threshold, 255, cv2.THRESH_BINARY)
# Morphological opening (erosion followed by dilation) to remove noise
kernel = np.ones((kernel_size, kernel_size), np.uint8)
binary_mask = cv2.morphologyEx(binary_mask, cv2.MORPH_OPEN, kernel, iterations=1)
# Morphological closing (dilation followed by erosion) to close small holes inside foreground
binary_mask = cv2.morphologyEx(binary_mask, cv2.MORPH_CLOSE, kernel, iterations=1)
total_pixels = binary_mask.size
sterilized_pixels = cv2.countNonZero(binary_mask)
coverage_percent = (sterilized_pixels / total_pixels) * 100
# Create overlay for visualization: Green = sterilized, Red = unsterilized
overlay = img.copy()
overlay[binary_mask == 255] = [0, 255, 0] # Green
overlay[binary_mask == 0] = [0, 0, 255] # Red
annotated_img = cv2.addWeighted(img, 0.6, overlay, 0.4, 0)
return annotated_img, coverage_percent
def create_pdf_report(coverage_percent, extracted_texts, annotated_image_path, output_path):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", 'B', 16)
pdf.cell(200, 10, txt="UV Sterilization Report", ln=True, align='C')
pdf.ln(10)
pdf.set_font("Arial", size=12)
pdf.cell(0, 10, f"Sterilization Coverage: {coverage_percent:.2f}%", ln=True)
pdf.ln(5)
pdf.cell(0, 10, "Extracted Text from Image (OCR):", ln=True)
pdf.set_font("Arial", size=10)
if extracted_texts:
for text in extracted_texts:
# Filter out very short or empty OCR texts to improve clarity
if len(text.strip()) > 1:
pdf.multi_cell(0, 8, f"- {text}")
else:
pdf.cell(0, 8, "No text detected.", ln=True)
pdf.ln(10)
pdf.cell(0, 10, "Annotated Image:", ln=True)
pdf.image(annotated_image_path, x=10, y=pdf.get_y(), w=pdf.w - 20)
pdf.output(output_path)
def save_record_to_salesforce(annotated_image_url, coverage_percent, original_image_pil, compliance_threshold=80):
sf = Salesforce(
username=os.environ['SF_USERNAME'],
password=os.environ['SF_PASSWORD'],
security_token=os.environ['SF_SECURITY_TOKEN'],
domain=os.environ.get('SF_DOMAIN', 'login') # 'test' for sandbox
)
# Save original image temporarily, upload it, get URL
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_orig_img_file:
original_image_pil.save(temp_orig_img_file.name, format="JPEG")
temp_orig_img_path = temp_orig_img_file.name
original_image_url = upload_image_and_get_url(temp_orig_img_path)
os.unlink(temp_orig_img_path)
compliance_status = 'Pass' if coverage_percent >= compliance_threshold else 'Fail'
technician_id = os.environ.get('SF_TECHNICIAN_ID') # Salesforce UserId lookup
record_name = f"UV Verification - {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}"
sf.UV_Verification__c.create({
'Name': record_name,
'Annotated_Image__c': annotated_image_url,
'Coverage_Percentage__c': round(coverage_percent, 2),
'Original_Image__c': original_image_url, # Correct field API name here
'Compliance_Status__c': compliance_status,
'Technician_ID__c': technician_id,
'Verified_On__c': datetime.utcnow().isoformat()
})
def process_image(input_img, brightness_threshold=150):
img = cv2.cvtColor(np.array(input_img), cv2.COLOR_RGB2BGR)
# Resize large images for faster processing, preserving aspect ratio
max_dim = 640
h, w = img.shape[:2]
if max(h, w) > max_dim:
scale = max_dim / max(h, w)
img = cv2.resize(img, (int(w * scale), int(h * scale)))
start_time = time.time()
ocr_result = ocr_model.ocr(img)
ocr_time = time.time() - start_time
extracted_texts = []
for line in ocr_result:
if line:
for word_info in line:
text = word_info[1][0].strip()
if len(text) > 1:
extracted_texts.append(text)
annotated_img, coverage_percent = analyze_uv_coverage(img, brightness_threshold)
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_img_file:
cv2.imwrite(temp_img_file.name, annotated_img)
annotated_img_path = temp_img_file.name
temp_pdf_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
temp_pdf_file.close()
create_pdf_report(coverage_percent, extracted_texts, annotated_img_path, temp_pdf_file.name)
# Upload annotated image and get URL
annotated_image_url = upload_image_and_get_url(annotated_img_path)
# Save record in Salesforce
save_record_to_salesforce(annotated_image_url, coverage_percent, input_img)
annotated_img_rgb = cv2.cvtColor(annotated_img, cv2.COLOR_BGR2RGB)
report_text = f"UV Sterilization Coverage: {coverage_percent:.2f}%"
# Clean up temp image file after PDF generation
os.unlink(annotated_img_path)
return annotated_img_rgb, report_text, temp_pdf_file.name
iface = gr.Interface(
fn=process_image,
inputs=[
gr.Image(type="pil", label="Upload Post-UV Sterilization Image"),
gr.Slider(50, 255, value=150, step=1, label="Brightness Threshold")
],
outputs=[
gr.Image(type="numpy", label="Annotated Image"),
gr.Textbox(label="UV Sterilization Report", lines=5),
gr.File(label="Download PDF Report")
],
title="UV Sterilization Coverage Analyzer",
description="Upload a post-UV sterilization image to analyze surface coverage and generate a compliance report."
)
iface.queue() # Enable request queuing to improve UX on heavy processing
if __name__ == "__main__":
iface.launch()