DimasMP3 commited on
Commit ·
10d4547
1
Parent(s): c695e83
Normalise image inputs and force RGB channels
Browse files- app.py +14 -1
- inference.py +18 -12
app.py
CHANGED
|
@@ -17,6 +17,17 @@ logger = logging.getLogger(__name__)
|
|
| 17 |
IMG_SIZE = 244
|
| 18 |
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
class FaceShapeModel:
|
| 21 |
def __init__(self, model_path: str, labels: List[str]):
|
| 22 |
if not os.path.exists(model_path):
|
|
@@ -33,7 +44,9 @@ class FaceShapeModel:
|
|
| 33 |
image = image.convert("RGB")
|
| 34 |
|
| 35 |
resized = image.resize((IMG_SIZE, IMG_SIZE), Image.BILINEAR)
|
| 36 |
-
array =
|
|
|
|
|
|
|
| 37 |
array = np.expand_dims(array, axis=0)
|
| 38 |
return array
|
| 39 |
|
|
|
|
| 17 |
IMG_SIZE = 244
|
| 18 |
|
| 19 |
|
| 20 |
+
def _ensure_three_channels(array: np.ndarray) -> np.ndarray:
|
| 21 |
+
if array.ndim == 2:
|
| 22 |
+
array = np.stack([array] * 3, axis=-1)
|
| 23 |
+
elif array.ndim == 3:
|
| 24 |
+
if array.shape[-1] == 1:
|
| 25 |
+
array = np.repeat(array, 3, axis=-1)
|
| 26 |
+
elif array.shape[-1] > 3:
|
| 27 |
+
array = array[..., :3]
|
| 28 |
+
return array
|
| 29 |
+
|
| 30 |
+
|
| 31 |
class FaceShapeModel:
|
| 32 |
def __init__(self, model_path: str, labels: List[str]):
|
| 33 |
if not os.path.exists(model_path):
|
|
|
|
| 44 |
image = image.convert("RGB")
|
| 45 |
|
| 46 |
resized = image.resize((IMG_SIZE, IMG_SIZE), Image.BILINEAR)
|
| 47 |
+
array = np.asarray(resized, dtype="float32")
|
| 48 |
+
array = _ensure_three_channels(array)
|
| 49 |
+
array /= 255.0
|
| 50 |
array = np.expand_dims(array, axis=0)
|
| 51 |
return array
|
| 52 |
|
inference.py
CHANGED
|
@@ -17,6 +17,7 @@ LABELS: List[str] = [
|
|
| 17 |
|
| 18 |
TARGET_SIZE = 244
|
| 19 |
|
|
|
|
| 20 |
def _load_image(image_bytes: bytes) -> Image.Image:
|
| 21 |
image = Image.open(io.BytesIO(image_bytes))
|
| 22 |
if image.mode != "RGB":
|
|
@@ -24,10 +25,22 @@ def _load_image(image_bytes: bytes) -> Image.Image:
|
|
| 24 |
return image
|
| 25 |
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
def _preprocess(image_bytes: bytes) -> np.ndarray:
|
| 28 |
image = _load_image(image_bytes)
|
| 29 |
resized = image.resize((TARGET_SIZE, TARGET_SIZE), Image.BILINEAR)
|
| 30 |
array = np.asarray(resized, dtype="float32")
|
|
|
|
| 31 |
array /= 255.0
|
| 32 |
return np.expand_dims(array, axis=0)
|
| 33 |
|
|
@@ -37,23 +50,16 @@ class PreTrainedModel:
|
|
| 37 |
self.model = tf.keras.models.load_model(model_path)
|
| 38 |
|
| 39 |
def predict(self, inputs: bytes) -> List[Dict[str, Any]]:
|
| 40 |
-
|
| 41 |
-
preds = self.model.predict(
|
| 42 |
|
| 43 |
if isinstance(preds, (list, tuple)):
|
| 44 |
preds = preds[0]
|
| 45 |
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
scores = np.array([float(scores)])
|
| 49 |
-
|
| 50 |
-
scores_list = scores.tolist()
|
| 51 |
-
top_index = int(np.argmax(scores_list))
|
| 52 |
return [
|
| 53 |
-
{
|
| 54 |
-
"label": LABELS[top_index],
|
| 55 |
-
"score": float(scores_list[top_index]),
|
| 56 |
-
}
|
| 57 |
]
|
| 58 |
|
| 59 |
|
|
|
|
| 17 |
|
| 18 |
TARGET_SIZE = 244
|
| 19 |
|
| 20 |
+
|
| 21 |
def _load_image(image_bytes: bytes) -> Image.Image:
|
| 22 |
image = Image.open(io.BytesIO(image_bytes))
|
| 23 |
if image.mode != "RGB":
|
|
|
|
| 25 |
return image
|
| 26 |
|
| 27 |
|
| 28 |
+
def _ensure_three_channels(array: np.ndarray) -> np.ndarray:
|
| 29 |
+
if array.ndim == 2:
|
| 30 |
+
array = np.stack([array] * 3, axis=-1)
|
| 31 |
+
elif array.ndim == 3:
|
| 32 |
+
if array.shape[-1] == 1:
|
| 33 |
+
array = np.repeat(array, 3, axis=-1)
|
| 34 |
+
elif array.shape[-1] > 3:
|
| 35 |
+
array = array[..., :3]
|
| 36 |
+
return array
|
| 37 |
+
|
| 38 |
+
|
| 39 |
def _preprocess(image_bytes: bytes) -> np.ndarray:
|
| 40 |
image = _load_image(image_bytes)
|
| 41 |
resized = image.resize((TARGET_SIZE, TARGET_SIZE), Image.BILINEAR)
|
| 42 |
array = np.asarray(resized, dtype="float32")
|
| 43 |
+
array = _ensure_three_channels(array)
|
| 44 |
array /= 255.0
|
| 45 |
return np.expand_dims(array, axis=0)
|
| 46 |
|
|
|
|
| 50 |
self.model = tf.keras.models.load_model(model_path)
|
| 51 |
|
| 52 |
def predict(self, inputs: bytes) -> List[Dict[str, Any]]:
|
| 53 |
+
x = _preprocess(inputs)
|
| 54 |
+
preds = self.model.predict(x, verbose=0)
|
| 55 |
|
| 56 |
if isinstance(preds, (list, tuple)):
|
| 57 |
preds = preds[0]
|
| 58 |
|
| 59 |
+
probs = np.asarray(preds).squeeze().tolist()
|
| 60 |
+
idx = int(np.argmax(probs))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
return [
|
| 62 |
+
{"label": LABELS[idx], "score": float(probs[idx])},
|
|
|
|
|
|
|
|
|
|
| 63 |
]
|
| 64 |
|
| 65 |
|