File size: 8,406 Bytes
2c5f171 72f857c dc2367e 2c5f171 2c1d06f 2c5f171 a6fedfd 2c5f171 2c1d06f a6fedfd 2c5f171 72f857c a16e911 2c5f171 e3a7c25 a16e911 e3a7c25 a16e911 2c5f171 a16e911 72f857c a16e911 2c1d06f a16e911 2c5f171 a16e911 e7d22a5 2c5f171 a16e911 2c5f171 a16e911 2c5f171 a16e911 e3a7c25 a16e911 2c5f171 72f857c a16e911 72f857c a16e911 72f857c a16e911 2c5f171 a16e911 2c5f171 39f18c1 2c5f171 e7d22a5 |
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 |
from PIL import Image, ImageDraw, ImageFont
import torch
from torchvision import models, transforms
from simple_salesforce import Salesforce
import base64
from io import BytesIO
import logging
from datetime import datetime
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import gradio as gr
# Setup logging
logging.basicConfig(level=logging.INFO)
# Salesforce Credentials (replace with your own or environment variables)
SALESFORCE_USERNAME = "drone@sathkrutha.com"
SALESFORCE_PASSWORD = "Komal1303@"
SALESFORCE_SECURITY_TOKEN = "53AWRskW9EjWUsSL5LU6nFTy3"
SALESFORCE_INSTANCE_URL = "https://sathikrutha-a-dev-ed.my.salesforce.com"
# Salesforce Site or parent record ID where content will be linked
SITE_RECORD_ID = "a003000000xxxxx" # TODO: Replace with actual Site__c record ID
# Connect to Salesforce
try:
sf = Salesforce(
username=SALESFORCE_USERNAME,
password=SALESFORCE_PASSWORD,
security_token=SALESFORCE_SECURITY_TOKEN,
instance_url=SALESFORCE_INSTANCE_URL
)
logging.info("Salesforce connection established.")
except Exception as e:
logging.error(f"Failed to connect to Salesforce: {str(e)}")
raise Exception(f"Failed to connect to Salesforce: {str(e)}")
# Load the Faster R-CNN pretrained model
model = models.detection.fasterrcnn_resnet50_fpn(weights="FasterRCNN_ResNet50_FPN_Weights.COCO_V1")
model.eval()
# Image transformation for the model input
transform = transforms.Compose([
transforms.ToTensor(),
])
VALID_FAULT_TYPES = ["Crack", "Rust", "Spalling", "Deformation", "Corrosion"]
VALID_SEVERITIES = ["Minor", "Moderate", "Critical"]
def get_severity(score):
if score >= 0.9:
return "Critical"
elif score >= 0.7:
return "Moderate"
else:
return "Minor"
def map_defect_type():
return VALID_FAULT_TYPES[0]
def upload_image_to_salesforce(image, filename="detected_image.jpg", record_id=None):
try:
buffered = BytesIO()
image.save(buffered, format="JPEG")
img_data = base64.b64encode(buffered.getvalue()).decode("utf-8")
content_version = sf.ContentVersion.create({
"Title": filename,
"PathOnClient": filename,
"VersionData": img_data,
"FirstPublishLocationId": record_id if record_id else SITE_RECORD_ID
})
logging.info(f"Image uploaded to Salesforce ContentVersion ID: {content_version['id']}")
return content_version["id"]
except Exception as e:
logging.error(f"Failed to upload image to Salesforce: {str(e)}")
raise Exception(f"Failed to upload image to Salesforce: {str(e)}")
def create_pdf_report(defect_list):
buffer = BytesIO()
c = canvas.Canvas(buffer, pagesize=letter)
width, height = letter
c.setFont("Helvetica-Bold", 14)
c.drawString(30, height - 50, "Structural Defect Detection Report")
c.setFont("Helvetica", 12)
y = height - 80
for i, defect in enumerate(defect_list, 1):
text = f"{i}. Type: {defect['type']}, Confidence: {defect['confidence']}, Severity: {defect['severity']}"
c.drawString(30, y, text)
y -= 20
if y < 50:
c.showPage()
c.setFont("Helvetica", 12)
y = height - 50
c.save()
pdf = buffer.getvalue()
buffer.close()
return pdf
def upload_pdf_to_salesforce(pdf_bytes, filename="report.pdf", record_id=None):
try:
pdf_data = base64.b64encode(pdf_bytes).decode("utf-8")
content_version = sf.ContentVersion.create({
"Title": filename,
"PathOnClient": filename,
"VersionData": pdf_data,
"FirstPublishLocationId": record_id if record_id else SITE_RECORD_ID
})
logging.info(f"PDF uploaded to Salesforce ContentVersion ID: {content_version['id']}")
return content_version["id"]
except Exception as e:
logging.error(f"Failed to upload PDF to Salesforce: {str(e)}")
raise Exception(f"Failed to upload PDF to Salesforce: {str(e)}")
def detect_defects(image):
if image is None:
return None, "No image provided"
try:
image_tensor = transform(image).unsqueeze(0)
with torch.no_grad():
predictions = model(image_tensor)
result_image = image.copy()
draw = ImageDraw.Draw(result_image)
try:
font = ImageFont.truetype("arial.ttf", 18)
except:
font = ImageFont.load_default()
output = []
for i in range(len(predictions[0]['boxes'])):
score = predictions[0]['scores'][i].item()
if score < 0.3:
continue
box = predictions[0]['boxes'][i].tolist()
defect_type = map_defect_type()
severity = get_severity(score)
output.append({
"type": defect_type,
"confidence": round(score, 2),
"severity": severity,
})
draw.rectangle(box, outline="red", width=3)
text = f"{defect_type}: {severity}"
draw.text((box[0], box[1] - 20 if box[1] > 20 else box[1],), text, fill="red", font=font)
if output:
# Fixed date formatting to ensure proper YYYY-MM-DD format
current_date = datetime.now().strftime("%Y-%m-%d")
inspection_name = f"Inspection-{current_date}-{len(output):03d}"
try:
inspection_record = sf.Drone_Structure_Inspection__c.create({
"Inspection_Date__c": current_date,
"Fault_Type__c": output[0]["type"],
"Severity__c": output[0]["severity"],
"Fault_Summary__c": str(output),
"Status__c": "New",
"Annotated_Image_URL__c": "",
"Report_PDF__c": ""
})
record_id = inspection_record.get("id")
content_version_id_img = upload_image_to_salesforce(
result_image,
filename=f"detected_defect_{record_id}.jpg",
record_id=record_id
)
pdf_bytes = create_pdf_report(output)
content_version_id_pdf = upload_pdf_to_salesforce(
pdf_bytes,
filename=f"defect_report_{record_id}.pdf",
record_id=record_id
)
update_data = {}
if content_version_id_img:
update_data["Annotated_Image_URL__c"] = f"/sfc/servlet.shepherd/version/download/{content_version_id_img}"
if content_version_id_pdf:
update_data["Report_PDF__c"] = f"/sfc/servlet.shepherd/version/download/{content_version_id_pdf}"
if update_data:
sf.Drone_Structure_Inspection__c.update(record_id, update_data)
output.append({"salesforce_record_id": record_id})
except Exception as e:
output.append({"error": f"Failed to create Salesforce record: {str(e)}"})
return result_image, str(output)
return result_image, "No defects detected above confidence threshold."
except Exception as e:
logging.error(f"Detection failed: {str(e)}")
return None, f"Detection failed: {str(e)}"
# Use gr.Blocks for more control over the UI
with gr.Blocks() as demo:
gr.Markdown(
"""
# Structural Defect Detection with Salesforce Integration
Upload drone-captured images to detect structural defects like cracks, rust, spalling, and deformations using Faster R-CNN. Detected faults are stored in Salesforce with annotated images.
"""
)
with gr.Row():
image_input = gr.Image(type="pil", label="Upload Drone Image")
image_output = gr.Image(label="Detection Result")
output_text = gr.Textbox(label="Detected Faults with Severity")
with gr.Row():
clear_btn = gr.Button("Clear")
submit_btn = gr.Button("Submit", variant="primary")
submit_btn.click(
fn=detect_defects,
inputs=image_input,
outputs=[image_output, output_text]
)
clear_btn.click(
fn=lambda: (None, ""),
inputs=None,
outputs=[image_input, output_text]
)
if __name__ == "__main__":
demo.launch(share=False) |