File size: 4,622 Bytes
8a50c3f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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)