-
Notifications
You must be signed in to change notification settings - Fork 3
/
segmentation.py
154 lines (130 loc) · 3.78 KB
/
segmentation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
# disable tensorflow warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
# segmentation model
from .model import deepskin_model
from .model import MODEL_CHECKPOINT
# download model weights
from .checkpoints import download_model_weights
import cv2
import numpy as np
from time import time as now
# constant values
from .constants import CRLF
from .constants import IMG_SIZE
from .constants import RESET_COLOR_CODE
from .constants import GREEN_COLOR_CODE
__author__ = ['Nico Curti']
__email__ = ['nico.curti2@unibo.it']
__all__ = [
'wound_segmentation'
]
def wound_segmentation (img : np.ndarray,
tol : float = 0.5,
verbose : bool = False
) -> np.ndarray :
'''
Perform the semantic image segmentation using the
Deepskin semantic model.
Parameters
----------
img : np.ndarray
Input image to analyze in RGB format
tol : float (default := 0.5)
Threshold to apply on the resulting mask for the
output binarization
verbose : bool (default := False)
Enable/Disable the logging of the steps
Returns
-------
pred : np.ndarray
Output image mask obtained by the model, in which
the semantic meaning is organized as: background
(channel 0), body (channel 1), wound (channel 2)
'''
tic = now()
step = 'Perform the semantic image segmentation... '
if verbose:
print(f'{step}',
end='\r',
flush=True,
)
# build the model for the semantic segmentation
model = deepskin_model(
verbose=False
)
# load the appropriated weights
local = os.path.dirname(os.path.abspath(__file__))
# build the weights filepath
weightspath = os.path.join(
local,
'..',
'checkpoints',
'efficientnetb3_deepskin_semantic.h5'
)
# if the weights file does not exists
if not os.path.exists(weightspath):
download_model_weights(
Id=MODEL_CHECKPOINT,
model_name = 'efficientnetb3_deepskin_semantic'
)
# load the weights
model.load_weights(weightspath)
# get the model input shape
_, h, w, c = model.input.shape
# pre-process the input
# resize the image into the shape required by the model
if verbose:
print(f'{CRLF}{step} {GREEN_COLOR_CODE}[1/3] pre-process the input image{RESET_COLOR_CODE}',
end='',
flush=True,
)
resized = cv2.resize(
img,
dsize=(h, w),
interpolation=cv2.INTER_CUBIC
)
# convert the image into floating-point values
resized = np.float32(resized)
# normalize the image into [0, 1] range
resized *= 1. / 255
# extend the dimensionality of the input array
# to the [batch, h, w, c] format
resized = resized.reshape(1, *resized.shape)
# apply the segmentation model
if verbose:
print(f'{CRLF}{step} {GREEN_COLOR_CODE}[2/3] apply the segmentation model{RESET_COLOR_CODE}',
end='',
flush=True,
)
# apply the model to get the prediction
pred = model.predict(resized, verbose=0)
# remove useless dimensions from the image
pred = np.squeeze(pred)
# filter the mask output to binary format
pred = np.where(pred > tol, 255, 0)
# convert the mask into uint8 fmt
pred = np.uint8(pred)
# post-process the mask
if verbose:
print(f'{CRLF}{step} {GREEN_COLOR_CODE}[3/3] post-process the segmentation mask{RESET_COLOR_CODE}',
end='',
flush=True,
)
# resize the output mask to the same
# shape of the original image, with an
# appropriated interpolation algorithm
pred = cv2.resize(
pred,
dsize=(img.shape[1], img.shape[0]),
interpolation=cv2.INTER_NEAREST_EXACT
)
toc = now()
if verbose:
print(f'{CRLF}{step} {GREEN_COLOR_CODE}[DONE]{RESET_COLOR_CODE} ({toc - tic:.3f} sec) ',
end='\n',
flush=True,
)
return pred