Kushalmanda's picture
Create app.py
8a50c3f verified
raw
history blame
4.62 kB
import cv2
import numpy as np
from PIL import Image
import gradio as gr
from pdf2image import convert_from_path # Import the PDF-to-image conversion library
# Function to calculate materials based on blueprint dimensions
def calculate_materials_from_dimensions(wall_area, foundation_area):
materials = {
"cement": 0,
"bricks": 0,
"steel": 0
}
# Wall calculations (in m²)
if wall_area > 0:
materials['cement'] += wall_area * 10 # 10 kg cement per m² for walls
materials['bricks'] += wall_area * 500 # 500 bricks per m² for walls
materials['steel'] += wall_area * 2 # 2 kg steel per m² for walls
# Foundation calculations (in m²)
if foundation_area > 0:
materials['cement'] += foundation_area * 20 # 20 kg cement per m² for foundation
materials['bricks'] += foundation_area * 750 # 750 bricks per m² for foundation
materials['steel'] += foundation_area * 5 # 5 kg steel per m² for foundation
return materials
# Function to process the blueprint and extract dimensions
def process_blueprint(image_path):
image = None
try:
# Check if the uploaded file is a PDF
if image_path.lower().endswith(".pdf"):
try:
# Convert the PDF to an image (first page)
images = convert_from_path(image_path, first_page=1, last_page=1)
image = np.array(images[0]) # Get the first page
print("Successfully converted PDF to image.")
except Exception as e:
print(f"Error processing the PDF file: {e}")
raise ValueError("Error processing the PDF file. Please ensure the file is a valid blueprint PDF.")
else:
# Open the image file
image = cv2.imread(image_path)
print("Successfully loaded image.")
except Exception as e:
print(f"Error loading file: {e}")
raise ValueError("Error loading the image. Please try again with a valid image or PDF file.")
# Check if image is successfully loaded
if image is None:
raise ValueError("Could not load the image or PDF file.")
# Convert to grayscale for easier processing
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply edge detection to find lines (walls)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
# Use Hough Transform to detect lines (walls)
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, threshold=100, minLineLength=50, maxLineGap=10)
# Calculate total wall length (in pixels)
total_wall_length_pixels = 0
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
length = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
total_wall_length_pixels += length
# From the blueprint, we know the dimensions (27 m × 9.78 m)
image_height, image_width = image.shape[:2]
blueprint_width_m = 27 # From the blueprint (27 m)
blueprint_height_m = 9.78 # From the blueprint (9.78 m)
# Calculate pixel-to-meter ratio
pixel_to_meter_width = blueprint_width_m / image_width
pixel_to_meter_height = blueprint_height_m / image_height
pixel_to_meter = (pixel_to_meter_width + pixel_to_meter_height) / 2 # Average for simplicity
# Convert wall length to meters
total_wall_length_m = total_wall_length_pixels * pixel_to_meter
# Estimate wall area (assume wall height of 3 m for simplicity)
wall_height_m = 3 # Standard room height
wall_area = total_wall_length_m * wall_height_m
# Estimate foundation area (based on the blueprint's total area)
total_area = blueprint_width_m * blueprint_height_m # 27 m × 9.78 m
foundation_area = total_area * 0.1 # Assume 10% of the total area is foundation
# Calculate materials
materials = calculate_materials_from_dimensions(wall_area, foundation_area)
# Format the output
formatted_materials = {
"cement": f"{materials['cement']:.2f} kg",
"bricks": f"{materials['bricks']:.0f} units",
"steel": f"{materials['steel']:.2f} kg"
}
return formatted_materials
# Set up Gradio interface
interface = gr.Interface(
fn=process_blueprint,
inputs=gr.File(label="Upload Blueprint (Image or PDF)", type="filepath"), # Support both image and PDF files
outputs=gr.JSON(label="Material Estimates"),
title="Blueprint Material Estimator",
description="Upload a blueprint image or PDF to estimate construction materials."
)
# Launch the interface
if __name__ == "__main__":
interface.launch(share=False)