Spaces:
Sleeping
Sleeping
File size: 7,617 Bytes
6727dc4 252549e a0b1614 252549e 3f4d43c 168adbc 9464db5 7a6994e 3f4d43c 12893c6 1623ecc 06c0907 7a6994e 97a0169 7a6994e 7dcbb03 3a13b8b 252549e 3a13b8b 7dcbb03 3a13b8b 7dcbb03 3a13b8b 7dcbb03 3a13b8b 7dcbb03 3a13b8b 252549e 3a13b8b 252549e 3a13b8b 252549e 3a13b8b 252549e a0b1614 252549e 3a13b8b 12893c6 252549e 3a13b8b 252549e 3a13b8b 168adbc 252549e 6727dc4 3a13b8b 7dcbb03 6727dc4 3a13b8b 252549e a0b1614 3a13b8b a0b1614 9464db5 3a13b8b 9464db5 3a13b8b 388621a 3a13b8b 9464db5 3a13b8b 9464db5 3a13b8b 9464db5 3a13b8b 9464db5 f4759e7 9464db5 6727dc4 3a13b8b 12893c6 3a13b8b 168adbc 3a13b8b 9c6cf28 3a13b8b 3f4d43c 12893c6 9c6cf28 7dcbb03 3a13b8b 6727dc4 3a13b8b 6727dc4 7dcbb03 3a13b8b 7dcbb03 3a13b8b 9464db5 3a13b8b 9464db5 3a13b8b 6727dc4 3a13b8b 098c355 3a13b8b 7a6994e 3a13b8b 7dcbb03 3a13b8b 32d99a2 a0b1614 6727dc4 7a6994e 6727dc4 098c355 6727dc4 a0b1614 3a13b8b 12893c6 a0b1614 3a8eb59 | 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 | 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() |