Spaces:
Running
Running
Update predict.py
Browse files- predict.py +22 -101
predict.py
CHANGED
@@ -1,110 +1,31 @@
|
|
1 |
-
from fastapi import FastAPI, File, UploadFile
|
2 |
-
from fastapi.responses import FileResponse
|
3 |
-
from tensorflow.keras.preprocessing.image import img_to_array
|
4 |
-
import tensorflow as tf
|
5 |
import cv2
|
6 |
import numpy as np
|
7 |
-
import os
|
8 |
-
from scipy import fftpack
|
9 |
-
from scipy import ndimage
|
10 |
from ultralytics import YOLO
|
11 |
-
from
|
12 |
-
import io
|
13 |
|
14 |
app = FastAPI()
|
15 |
-
uploads_dir = 'uploads'
|
16 |
-
|
17 |
-
if not os.path.exists(uploads_dir):
|
18 |
-
os.makedirs(uploads_dir)
|
19 |
-
|
20 |
-
# Load the saved models
|
21 |
-
segmentation_model_path = 'segmentation_model.h5'
|
22 |
-
segmentation_model = tf.keras.models.load_model(segmentation_model_path)
|
23 |
yolo_model_path = 'best.pt'
|
24 |
-
|
25 |
-
|
26 |
-
def calculate_moisture_and_texture(image):
|
27 |
-
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
28 |
-
fft_image = fftpack.fft2(gray_image)
|
29 |
-
fft_shifted = fftpack.fftshift(fft_image)
|
30 |
-
magnitude_spectrum = 20 * np.log(np.abs(fft_shifted))
|
31 |
-
height, width = magnitude_spectrum.shape
|
32 |
-
center_x, center_y = width // 2, height // 2
|
33 |
-
radius = min(center_x, center_y) // 2
|
34 |
-
moisture_region = magnitude_spectrum[center_y - radius:center_y + radius, center_x - radius:center_x + radius]
|
35 |
-
moisture_level = np.mean(moisture_region)
|
36 |
-
return moisture_level
|
37 |
|
38 |
-
def
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
wound_region = labeled_mask == wound_label
|
43 |
-
rows = np.any(wound_region, axis=1)
|
44 |
-
cols = np.any(wound_region, axis=0)
|
45 |
-
rmin, rmax = np.where(rows)[0][[0, -1]]
|
46 |
-
cmin, cmax = np.where(cols)[0][[0, -1]]
|
47 |
-
length_pixels = rmax - rmin
|
48 |
-
breadth_pixels = cmax - cmin
|
49 |
-
pixel_to_cm_ratio = 0.1
|
50 |
-
length_cm = length_pixels * pixel_to_cm_ratio
|
51 |
-
breadth_cm = breadth_pixels * pixel_to_cm_ratio
|
52 |
-
depth_cm = np.mean(mask[wound_region]) * pixel_to_cm_ratio
|
53 |
-
length_cm = round(length_cm, 3)
|
54 |
-
breadth_cm = round(breadth_cm, 3)
|
55 |
-
depth_cm = round(depth_cm, 3)
|
56 |
-
area_cm2 = length_cm * breadth_cm
|
57 |
-
return length_cm, breadth_cm, depth_cm, area_cm2
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
62 |
|
63 |
-
@app.post("/
|
64 |
-
async def
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
combined_ymax = float('-inf')
|
74 |
-
for detection in results[0].boxes.xyxy.tolist():
|
75 |
-
xmin, ymin, xmax, ymax = detection
|
76 |
-
combined_xmin = min(combined_xmin, xmin)
|
77 |
-
combined_ymin = min(combined_ymin, ymin)
|
78 |
-
combined_xmax = max(combined_xmax, xmax)
|
79 |
-
combined_ymax = max(combined_ymax, ymax)
|
80 |
-
combined_xmin = int(combined_xmin)
|
81 |
-
combined_ymin = int(combined_ymin)
|
82 |
-
combined_xmax = int(combined_xmax)
|
83 |
-
combined_ymax = int(combined_ymax)
|
84 |
-
combined_img = img[combined_ymin:combined_ymax, combined_xmin:combined_xmax]
|
85 |
-
combined_img_resized = cv2.resize(combined_img, (224, 224))
|
86 |
-
img_array = img_to_array(combined_img_resized) / 255.0
|
87 |
-
img_array = np.expand_dims(img_array, axis=0)
|
88 |
-
output = segmentation_model.predict(img_array)
|
89 |
-
predicted_mask = output[0]
|
90 |
-
mask_overlay = (predicted_mask.squeeze() * 255).astype(np.uint8)
|
91 |
-
mask_overlay_colored = np.zeros((mask_overlay.shape[0], mask_overlay.shape[1], 3), dtype=np.uint8)
|
92 |
-
mask_overlay_colored[mask_overlay > 200] = [255, 0, 0] # Red
|
93 |
-
mask_overlay_colored[(mask_overlay > 100) & (mask_overlay <= 200)] = [0, 255, 0] # Green
|
94 |
-
mask_overlay_colored[mask_overlay <= 100] = [0, 0, 255] # Blue
|
95 |
-
mask_overlay_colored = cv2.resize(mask_overlay_colored, (224, 224))
|
96 |
-
blended_image = cv2.addWeighted(combined_img_resized.astype(np.uint8), 0.6, mask_overlay_colored, 0.4, 0)
|
97 |
-
segmented_image = Image.fromarray(cv2.cvtColor(blended_image, cv2.COLOR_BGR2RGB))
|
98 |
-
img_byte_arr = io.BytesIO()
|
99 |
-
segmented_image.save(img_byte_arr, format='PNG')
|
100 |
-
img_byte_arr.seek(0)
|
101 |
-
length_cm, breadth_cm, depth_cm, area_cm2 = calculate_wound_dimensions(predicted_mask)
|
102 |
-
moisture = calculate_moisture_and_texture(combined_img)
|
103 |
-
response = Response(img_byte_arr.getvalue(), media_type='image/png')
|
104 |
-
response.headers['X-Length-Cm'] = str(length_cm)
|
105 |
-
response.headers['X-Breadth-Cm'] = str(breadth_cm)
|
106 |
-
response.headers['X-Depth-Cm'] = str(depth_cm)
|
107 |
-
response.headers['X-Area-Cm2'] = str(area_cm2)
|
108 |
-
response.headers['X-Moisture'] = str(moisture)
|
109 |
-
return response
|
110 |
-
return {'error': 'Invalid file format'}
|
|
|
1 |
+
from fastapi import FastAPI, File, UploadFile
|
|
|
|
|
|
|
2 |
import cv2
|
3 |
import numpy as np
|
|
|
|
|
|
|
4 |
from ultralytics import YOLO
|
5 |
+
from fastapi.responses import FileResponse
|
|
|
6 |
|
7 |
app = FastAPI()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
yolo_model_path = 'best.pt'
|
9 |
+
yolo = YOLO(yolo_model_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
+
def detect_wounds(image):
|
12 |
+
results = yolo(image)
|
13 |
+
boxes = results[0].boxes.xyxy.tolist()
|
14 |
+
return boxes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
def draw_boxes(image, boxes):
|
17 |
+
for box in boxes:
|
18 |
+
x1, y1, x2, y2 = map(int, box)
|
19 |
+
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
20 |
+
return image
|
21 |
|
22 |
+
@app.post("/detect")
|
23 |
+
async def detect(image: UploadFile = File(...)):
|
24 |
+
image_bytes = await image.read()
|
25 |
+
image = np.frombuffer(image_bytes, np.uint8)
|
26 |
+
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
|
27 |
+
wound_boxes = detect_wounds(image)
|
28 |
+
image_with_boxes = draw_boxes(image, wound_boxes)
|
29 |
+
result_path = 'esult.jpg'
|
30 |
+
cv2.imwrite(result_path, image_with_boxes)
|
31 |
+
return FileResponse(result_path, media_type='image/jpeg')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|