Hussein El-Hadidy commited on
Commit ·
e4c62bf
1
Parent(s): bfaa87e
Segment Burns API
Browse files- SkinBurns_Segmentation.py +68 -0
- app.py +32 -0
- requirements.txt +8 -1
SkinBurns_Segmentation.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
from skimage import io, img_as_float, color, transform
|
| 3 |
+
from scipy.ndimage import gaussian_filter
|
| 4 |
+
import tensorly as tl
|
| 5 |
+
from tensorly.decomposition import tucker
|
| 6 |
+
from sklearn.cluster import KMeans
|
| 7 |
+
import cv2
|
| 8 |
+
import matplotlib.pyplot as plt
|
| 9 |
+
|
| 10 |
+
def segment_skin_burns(image_path, output_path='segmented_image.png'):
|
| 11 |
+
# Load and preprocess the image
|
| 12 |
+
image = io.imread(image_path)
|
| 13 |
+
image = img_as_float(image)
|
| 14 |
+
image_lab = color.rgb2lab(image) # LAB color space
|
| 15 |
+
|
| 16 |
+
# Adaptive Illumination Correction (CLAHE)
|
| 17 |
+
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
|
| 18 |
+
image_lab[:, :, 0] = clahe.apply((image_lab[:, :, 0] * 255).astype(np.uint8)) / 255.0
|
| 19 |
+
|
| 20 |
+
# Gaussian filtering
|
| 21 |
+
sigma_value = 1.5
|
| 22 |
+
image_lab_filtered = np.zeros_like(image_lab)
|
| 23 |
+
for i in range(3):
|
| 24 |
+
image_lab_filtered[:, :, i] = gaussian_filter(image_lab[:, :, i], sigma=sigma_value)
|
| 25 |
+
|
| 26 |
+
# Third-order tensor
|
| 27 |
+
tensor_image = tl.tensor(image_lab_filtered)
|
| 28 |
+
|
| 29 |
+
# Tucker3 tensor decomposition
|
| 30 |
+
tucker_rank = [30, 30, 3]
|
| 31 |
+
core, factors = tucker(tensor_image, rank=tucker_rank)
|
| 32 |
+
|
| 33 |
+
# Resize core tensor
|
| 34 |
+
core_resized = transform.resize(core, (image.shape[0], image.shape[1], 3), anti_aliasing=True)
|
| 35 |
+
|
| 36 |
+
# Convert to RGB
|
| 37 |
+
core_resized_rgb = np.clip(color.lab2rgb(core_resized), 0, 1)
|
| 38 |
+
|
| 39 |
+
# Reconstruct image
|
| 40 |
+
reconstructed_image = tl.tucker_to_tensor((core, factors))
|
| 41 |
+
|
| 42 |
+
# Features for clustering
|
| 43 |
+
height, width, _ = image.shape
|
| 44 |
+
feature_vectors = reconstructed_image.reshape(height * width, -1)
|
| 45 |
+
|
| 46 |
+
# K-means clustering
|
| 47 |
+
n_clusters = 3 # Burn wound, healthy skin, background
|
| 48 |
+
kmeans = KMeans(n_clusters=n_clusters, n_init=10, random_state=42)
|
| 49 |
+
kmeans.fit(feature_vectors)
|
| 50 |
+
labels = kmeans.labels_.reshape(height, width)
|
| 51 |
+
|
| 52 |
+
# Identify burn cluster
|
| 53 |
+
cluster_means = [np.mean(feature_vectors[labels.flatten() == i], axis=0) for i in range(n_clusters)]
|
| 54 |
+
burn_cluster = np.argmax([mean[1] for mean in cluster_means]) # LAB 'a' channel: higher values → red tones
|
| 55 |
+
|
| 56 |
+
# Color-mapped segmentation image
|
| 57 |
+
segmentation_map = np.zeros((height, width, 3))
|
| 58 |
+
colors = {burn_cluster: [1, 0, 0], # Red for burn
|
| 59 |
+
(burn_cluster + 1) % 3: [0, 1, 0], # Green for healthy skin
|
| 60 |
+
(burn_cluster + 2) % 3: [0, 0, 1]} # Blue for background
|
| 61 |
+
|
| 62 |
+
for cluster, color in colors.items():
|
| 63 |
+
segmentation_map[labels == cluster] = color
|
| 64 |
+
|
| 65 |
+
# Save the segmented image
|
| 66 |
+
plt.imsave(output_path, segmentation_map)
|
| 67 |
+
|
| 68 |
+
return output_path
|
app.py
CHANGED
|
@@ -4,6 +4,7 @@ from pymongo.server_api import ServerApi
|
|
| 4 |
import cloudinary
|
| 5 |
import cloudinary.uploader
|
| 6 |
from cloudinary.utils import cloudinary_url
|
|
|
|
| 7 |
|
| 8 |
app = FastAPI()
|
| 9 |
|
|
@@ -57,6 +58,37 @@ async def upload_sample(file: UploadFile = File(...)):
|
|
| 57 |
except Exception as e:
|
| 58 |
return {"error": str(e)}
|
| 59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
# ✅ Optimize and transform image URL
|
| 61 |
@app.get("/cloudinary/transform")
|
| 62 |
def transform_image():
|
|
|
|
| 4 |
import cloudinary
|
| 5 |
import cloudinary.uploader
|
| 6 |
from cloudinary.utils import cloudinary_url
|
| 7 |
+
from SkinBurns_Segmentation import segment_skin_burns
|
| 8 |
|
| 9 |
app = FastAPI()
|
| 10 |
|
|
|
|
| 58 |
except Exception as e:
|
| 59 |
return {"error": str(e)}
|
| 60 |
|
| 61 |
+
@app.post("/skin_burns/segment")
|
| 62 |
+
async def Segment_Burns(file: UploadFile = File(...), output_path='segmented_image.png'):
|
| 63 |
+
try:
|
| 64 |
+
# Save the uploaded file temporarily
|
| 65 |
+
with open(file.filename, "wb") as temp_file:
|
| 66 |
+
temp_file.write(await file.read())
|
| 67 |
+
|
| 68 |
+
# Call the segmentation function
|
| 69 |
+
segmented_image_path = segment_skin_burns(file.filename, output_path)
|
| 70 |
+
|
| 71 |
+
# Upload the segmented image to Cloudinary
|
| 72 |
+
result = cloudinary.uploader.upload(segmented_image_path, public_id=f"segmented_{file.filename}")
|
| 73 |
+
uploaded_url = result["secure_url"]
|
| 74 |
+
|
| 75 |
+
# Save segmented image URL to MongoDB
|
| 76 |
+
collection = db["Images"]
|
| 77 |
+
doc = {"filename": f"segmented_{file.filename}", "url": uploaded_url}
|
| 78 |
+
collection.insert_one(doc)
|
| 79 |
+
|
| 80 |
+
return {"segmented_image_url": uploaded_url}
|
| 81 |
+
except Exception as e:
|
| 82 |
+
return {"error": str(e)}
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
|
| 92 |
# ✅ Optimize and transform image URL
|
| 93 |
@app.get("/cloudinary/transform")
|
| 94 |
def transform_image():
|
requirements.txt
CHANGED
|
@@ -2,4 +2,11 @@ fastapi
|
|
| 2 |
uvicorn[standard]
|
| 3 |
pymongo[srv]
|
| 4 |
python-multipart
|
| 5 |
-
cloudinary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
uvicorn[standard]
|
| 3 |
pymongo[srv]
|
| 4 |
python-multipart
|
| 5 |
+
cloudinary
|
| 6 |
+
numpy
|
| 7 |
+
scikit-image
|
| 8 |
+
scipy
|
| 9 |
+
tensorly
|
| 10 |
+
scikit-learn
|
| 11 |
+
opencv-python
|
| 12 |
+
matplotlib
|