import cv2 import numpy as np import gradio as gr from pdf2image import convert_from_path import os import tempfile import logging from PIL import Image # Set up logging logging.basicConfig(filename='debug.log', level=logging.DEBUG) logger = logging.getLogger(__name__) def validate_poppler_path(poppler_path): if not poppler_path: return None poppler_path = poppler_path.replace('\\', '/') if not os.path.isdir(poppler_path): return None pdftoppm_path = os.path.join(poppler_path, "pdftoppm" + (".exe" if os.name == "nt" else "")) if not os.path.isfile(pdftoppm_path): return None return poppler_path def calculate_materials_from_dimensions(wall_area, foundation_area): return { "cement": round(wall_area * 10 + foundation_area * 20, 2), "bricks": int(wall_area * 500 + foundation_area * 750), "steel": round(wall_area * 2 + foundation_area * 5, 2) } def process_blueprint(uploaded_file, blueprint_width_m=27, blueprint_height_m=9.78, poppler_path=None): try: filename = uploaded_file.name poppler_path = validate_poppler_path(poppler_path) # Convert input to image if filename.endswith(".pdf"): images = convert_from_path(uploaded_file.name, poppler_path=poppler_path) if not images: return {"error": "No pages found in PDF"} image = np.array(images[0]) else: image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), cv2.IMREAD_COLOR) if image is None: return {"error": "Failed to load image"} gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 50, 150) lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50, maxLineGap=10) total_wall_length_pixels = sum( np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) for line in lines for x1, y1, x2, y2 in [line[0]] ) if lines is not None else 0 img_h, img_w = image.shape[:2] pixel_to_meter_w = blueprint_width_m / img_w pixel_to_meter_h = blueprint_height_m / img_h avg_pixel_to_meter = (pixel_to_meter_w + pixel_to_meter_h) / 2 total_wall_length_m = total_wall_length_pixels * avg_pixel_to_meter wall_height_m = 3 wall_area = total_wall_length_m * wall_height_m total_area = blueprint_width_m * blueprint_height_m foundation_area = total_area * 0.1 materials = calculate_materials_from_dimensions(wall_area, foundation_area) return { "cement": f"{materials['cement']} kg", "bricks": f"{materials['bricks']} units", "steel": f"{materials['steel']} kg" } except Exception as e: return {"error": f"Processing failed: {str(e)}"} # Gradio UI interface = gr.Interface( fn=process_blueprint, inputs=[ gr.File(label="Upload Blueprint (PDF or Image)", file_types=[".pdf", ".png", ".jpg", ".jpeg"]), gr.Number(label="Blueprint Width (meters)", value=27), gr.Number(label="Blueprint Height (meters)", value=9.78), gr.Textbox(label="Poppler Path (Optional)", placeholder="e.g., C:/poppler/bin") ], outputs=gr.JSON(label="Estimated Materials"), title="Blueprint Estimator", description="Upload a blueprint as PDF or image to estimate materials (cement, bricks, steel)." ) if __name__ == "__main__": interface.launch()