Spaces:
Build error
Build error
import cv2 | |
import numpy as np | |
import gradio as gr | |
from pdf2image import convert_from_path | |
import os | |
import tempfile | |
# 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 from a PDF | |
def process_blueprint(pdf_path): | |
try: | |
# Convert PDF to images | |
images = convert_from_path(pdf_path, first_page=1, last_page=1) # Process only the first page | |
if not images: | |
raise ValueError("No images extracted from the PDF") | |
# Save the first page as a temporary image | |
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as temp_file: | |
images[0].save(temp_file.name, 'PNG') | |
temp_image_path = temp_file.name | |
# Open the image with OpenCV | |
image = cv2.imread(temp_image_path) | |
if image is None: | |
raise ValueError("Could not load the image from PDF") | |
# Clean up temporary file | |
os.unlink(temp_image_path) | |
# 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 assume 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 | |
except Exception as e: | |
return {"error": f"Failed to process PDF: {str(e)}"} | |
# Set up Gradio interface | |
interface = gr.Interface( | |
fn=process_blueprint, | |
inputs=gr.File(file_types=[".pdf"], label="Upload Blueprint PDF"), | |
outputs=gr.JSON(label="Material Estimates"), | |
title="Blueprint Material Estimator", | |
description="Upload a PDF containing a blueprint to estimate construction materials." | |
) | |
# Launch the interface | |
if __name__ == "__main__": | |
interface.launch(share=False) |