Spaces:
Sleeping
Sleeping
trttung1610
commited on
Commit
•
d54f3c3
1
Parent(s):
97be2e7
Upload 2 files
Browse files- requirements.txt +7 -0
- web.py +145 -0
requirements.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
pillow
|
3 |
+
torch
|
4 |
+
torchvision
|
5 |
+
opencv-python
|
6 |
+
numpy
|
7 |
+
openpyxl
|
web.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from PIL import Image
|
3 |
+
import torch
|
4 |
+
import torchvision.models as models
|
5 |
+
import torchvision.transforms as transforms
|
6 |
+
import cv2
|
7 |
+
import numpy as np
|
8 |
+
import openpyxl
|
9 |
+
import os
|
10 |
+
from tkinter import filedialog
|
11 |
+
|
12 |
+
# Load the pre-trained EfficientNet-B7 model
|
13 |
+
model = models.efficientnet_b7(pretrained=True)
|
14 |
+
model.eval()
|
15 |
+
|
16 |
+
# Define the transformations to be applied to the input image
|
17 |
+
transform = transforms.Compose([
|
18 |
+
transforms.Resize((224, 224)),
|
19 |
+
transforms.ToTensor(),
|
20 |
+
transforms.Normalize(mean=[0.485, 0.456, 0.406],
|
21 |
+
std=[0.229, 0.224, 0.225])
|
22 |
+
])
|
23 |
+
def predict_house_area(room_id, excel_file, image_files):
|
24 |
+
total_area_sqm = 0
|
25 |
+
predicted_areas = []
|
26 |
+
|
27 |
+
# Check if the excel_file is provided
|
28 |
+
if excel_file is not None:
|
29 |
+
# Load the existing Excel workbook
|
30 |
+
workbook = openpyxl.load_workbook(excel_file.name)
|
31 |
+
worksheet = workbook.active
|
32 |
+
else:
|
33 |
+
# Create a new Excel workbook
|
34 |
+
workbook = openpyxl.Workbook()
|
35 |
+
worksheet = workbook.active
|
36 |
+
|
37 |
+
# Write the headers to the worksheet
|
38 |
+
worksheet.cell(row=1, column=1).value = "Room ID"
|
39 |
+
worksheet.cell(row=1, column=2).value = "Image File"
|
40 |
+
worksheet.cell(row=1, column=3).value = "Predicted Area (sqm)"
|
41 |
+
|
42 |
+
# Get the last row index to append new data
|
43 |
+
last_row_index = worksheet.max_row if worksheet.max_row else 1
|
44 |
+
|
45 |
+
# Loop over all the images
|
46 |
+
for i, image_file in enumerate(image_files):
|
47 |
+
# Load the input image
|
48 |
+
img = Image.open(image_file.name)
|
49 |
+
# Extract the image file name from the path
|
50 |
+
image_file_name = os.path.basename(image_file.name)
|
51 |
+
# Check if the image is PNG and convert to JPEG if it is
|
52 |
+
if img.format == "PNG":
|
53 |
+
# Convert the image to RGB format
|
54 |
+
img = img.convert("RGB")
|
55 |
+
|
56 |
+
# Apply the transformations to the input image
|
57 |
+
img_transformed = transform(img)
|
58 |
+
|
59 |
+
# Add a batch dimension to the transformed image tensor
|
60 |
+
img_transformed_batch = torch.unsqueeze(img_transformed, 0)
|
61 |
+
|
62 |
+
# Use the pre-trained model to make a prediction on the input image
|
63 |
+
with torch.no_grad():
|
64 |
+
output = model(img_transformed_batch)
|
65 |
+
|
66 |
+
# Convert the output tensor to a probability distribution using softmax
|
67 |
+
softmax = torch.nn.Softmax(dim=1)
|
68 |
+
output_probs = softmax(output)
|
69 |
+
|
70 |
+
# Extract the predicted class (house square footage) from the output probabilities
|
71 |
+
predicted_class = torch.argmax(output_probs)
|
72 |
+
|
73 |
+
# Calculate the predicted area based on the predicted class
|
74 |
+
predicted_area_sqm = 0
|
75 |
+
if predicted_class in [861, 648, 594, 894, 799, 896, 454]:
|
76 |
+
# Convert to grayscale and apply adaptive thresholding
|
77 |
+
gray = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2GRAY)
|
78 |
+
gray = cv2.GaussianBlur(gray, (5, 5), 0)
|
79 |
+
mask = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 2)
|
80 |
+
|
81 |
+
# Apply Canny edge detection to the binary mask
|
82 |
+
edges = cv2.Canny(mask, 30, 100)
|
83 |
+
|
84 |
+
# Apply dilation to fill gaps in the contour
|
85 |
+
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
|
86 |
+
dilated = cv2.dilate(edges, kernel, iterations=2)
|
87 |
+
eroded = cv2.erode(dilated, kernel, iterations=1)
|
88 |
+
|
89 |
+
# Find contours in binary mask
|
90 |
+
contours, _ = cv2.findContours(eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
91 |
+
|
92 |
+
# Find largest contour and calculate area
|
93 |
+
max_area = 0
|
94 |
+
for c in contours:
|
95 |
+
area = cv2.contourArea(c)
|
96 |
+
if area > max_area:
|
97 |
+
max_area = area
|
98 |
+
|
99 |
+
# Convert pixel area to square meters
|
100 |
+
pixels_per_meter = 300 # adjust this value based on your image resolution and actual room dimensions
|
101 |
+
predicted_area_sqm = (max_area + 10) / (2 * pixels_per_meter ** 2)
|
102 |
+
else:
|
103 |
+
predicted_area_sqft = predicted_class.item()
|
104 |
+
predicted_area_sqm = predicted_area_sqft * 0.092903 / 4.2
|
105 |
+
|
106 |
+
# Add the predicted area to the sum
|
107 |
+
total_area_sqm += predicted_area_sqm
|
108 |
+
|
109 |
+
# Add the predicted area to the list of predicted areas
|
110 |
+
predicted_areas.append(predicted_area_sqm)
|
111 |
+
|
112 |
+
# Write the room ID, image file name, and predicted area to the worksheet
|
113 |
+
worksheet.cell(row=last_row_index + i + 1, column=1).value = room_id
|
114 |
+
worksheet.cell(row=last_row_index + i + 1, column=2).value = image_file_name
|
115 |
+
worksheet.cell(row=last_row_index + i + 1, column=3).value = predicted_area_sqm
|
116 |
+
|
117 |
+
# Save the workbook to a temporary file
|
118 |
+
temp_file = "predicted_areas.xlsx"
|
119 |
+
workbook.save(temp_file)
|
120 |
+
|
121 |
+
return f"Sum of predicted house square footage: {total_area_sqm:.2f} square meters", temp_file
|
122 |
+
|
123 |
+
|
124 |
+
inputs = [
|
125 |
+
gr.inputs.Textbox(label = "Mã Phòng" , type = "text"),
|
126 |
+
gr.inputs.File(label="Excel File", type="file"),
|
127 |
+
gr.inputs.File(label="Images", type="file", file_count="multiple")
|
128 |
+
]
|
129 |
+
|
130 |
+
outputs = [
|
131 |
+
gr.outputs.Textbox(label="Sum of Predicted House Square Footage"),
|
132 |
+
gr.outputs.File(label="Excel Result")
|
133 |
+
]
|
134 |
+
|
135 |
+
interface = gr.Interface(
|
136 |
+
fn=predict_house_area,
|
137 |
+
inputs=inputs,
|
138 |
+
outputs=outputs,
|
139 |
+
title="House Predictor",
|
140 |
+
allow_flagging="never" # Disable flag button
|
141 |
+
)
|
142 |
+
|
143 |
+
if __name__ == "__main__":
|
144 |
+
interface.launch(share=True)
|
145 |
+
|