Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from PIL import Image | |
| import torch | |
| import torchvision.models as models | |
| import torchvision.transforms as transforms | |
| import cv2 | |
| import numpy as np | |
| import openpyxl | |
| import os | |
| from tkinter import filedialog | |
| # Load the pre-trained EfficientNet-B7 model | |
| model = models.efficientnet_b7(pretrained=True) | |
| model.eval() | |
| # Define the transformations to be applied to the input image | |
| transform = transforms.Compose([ | |
| transforms.Resize((224, 224)), | |
| transforms.ToTensor(), | |
| transforms.Normalize(mean=[0.485, 0.456, 0.406], | |
| std=[0.229, 0.224, 0.225]) | |
| ]) | |
| def predict_house_area(room_id, excel_file, image_files): | |
| total_area_sqm = 0 | |
| predicted_areas = [] | |
| # Check if the excel_file is provided | |
| if excel_file is not None: | |
| # Load the existing Excel workbook | |
| workbook = openpyxl.load_workbook(excel_file.name) | |
| worksheet = workbook.active | |
| else: | |
| # Create a new Excel workbook | |
| workbook = openpyxl.Workbook() | |
| worksheet = workbook.active | |
| # Write the headers to the worksheet | |
| worksheet.cell(row=1, column=1).value = "Room ID" | |
| worksheet.cell(row=1, column=2).value = "Image File" | |
| worksheet.cell(row=1, column=3).value = "Predicted Area (sqm)" | |
| # Get the last row index to append new data | |
| last_row_index = worksheet.max_row if worksheet.max_row else 1 | |
| # Loop over all the images | |
| for i, image_file in enumerate(image_files): | |
| # Load the input image | |
| img = Image.open(image_file.name) | |
| # Extract the image file name from the path | |
| image_file_name = os.path.basename(image_file.name) | |
| # Check if the image is PNG and convert to JPEG if it is | |
| if img.format == "PNG": | |
| # Convert the image to RGB format | |
| img = img.convert("RGB") | |
| # Apply the transformations to the input image | |
| img_transformed = transform(img) | |
| # Add a batch dimension to the transformed image tensor | |
| img_transformed_batch = torch.unsqueeze(img_transformed, 0) | |
| # Use the pre-trained model to make a prediction on the input image | |
| with torch.no_grad(): | |
| output = model(img_transformed_batch) | |
| # Convert the output tensor to a probability distribution using softmax | |
| softmax = torch.nn.Softmax(dim=1) | |
| output_probs = softmax(output) | |
| # Extract the predicted class (house square footage) from the output probabilities | |
| predicted_class = torch.argmax(output_probs) | |
| # Calculate the predicted area based on the predicted class | |
| predicted_area_sqm = 0 | |
| if predicted_class in [861, 648, 594, 894, 799, 896, 454]: | |
| # Convert to grayscale and apply adaptive thresholding | |
| gray = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2GRAY) | |
| gray = cv2.GaussianBlur(gray, (5, 5), 0) | |
| mask = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 2) | |
| # Apply Canny edge detection to the binary mask | |
| edges = cv2.Canny(mask, 30, 100) | |
| # Apply dilation to fill gaps in the contour | |
| kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) | |
| dilated = cv2.dilate(edges, kernel, iterations=2) | |
| eroded = cv2.erode(dilated, kernel, iterations=1) | |
| # Find contours in binary mask | |
| contours, _ = cv2.findContours(eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
| # Find largest contour and calculate area | |
| max_area = 0 | |
| for c in contours: | |
| area = cv2.contourArea(c) | |
| if area > max_area: | |
| max_area = area | |
| # Convert pixel area to square meters | |
| pixels_per_meter = 300 # adjust this value based on your image resolution and actual room dimensions | |
| predicted_area_sqm = (max_area + 10) / (2 * pixels_per_meter ** 2) | |
| else: | |
| predicted_area_sqft = predicted_class.item() | |
| predicted_area_sqm = predicted_area_sqft * 0.092903 / 4.2 | |
| # Add the predicted area to the sum | |
| total_area_sqm += predicted_area_sqm | |
| # Add the predicted area to the list of predicted areas | |
| predicted_areas.append(predicted_area_sqm) | |
| # Write the room ID, image file name, and predicted area to the worksheet | |
| worksheet.cell(row=last_row_index + i + 1, column=1).value = room_id | |
| worksheet.cell(row=last_row_index + i + 1, column=2).value = image_file_name | |
| worksheet.cell(row=last_row_index + i + 1, column=3).value = predicted_area_sqm | |
| # Save the workbook to a temporary file | |
| temp_file = "predicted_areas.xlsx" | |
| workbook.save(temp_file) | |
| return f"Sum of predicted house square footage: {total_area_sqm:.2f} square meters", temp_file | |
| inputs = [ | |
| gr.inputs.Textbox(label = "Mã Phòng" , type = "text"), | |
| gr.inputs.File(label="Excel File", type="file"), | |
| gr.inputs.File(label="Images", type="file", file_count="multiple") | |
| ] | |
| outputs = [ | |
| gr.outputs.Textbox(label="Sum of Predicted House Square Footage"), | |
| gr.outputs.File(label="Excel Result") | |
| ] | |
| interface = gr.Interface( | |
| fn=predict_house_area, | |
| inputs=inputs, | |
| outputs=outputs, | |
| title="House Predictor", | |
| allow_flagging="never" # Disable flag button | |
| ) | |
| if __name__ == "__main__": | |
| interface.launch() | |