|
| 1 | +# built-in dependencies |
1 | 2 | import math
|
2 | 3 | from typing import Union, Tuple
|
| 4 | + |
| 5 | +# 3rd party dependencies |
3 | 6 | import numpy as np
|
4 | 7 | from PIL import Image
|
| 8 | +import cv2 |
| 9 | +import tensorflow as tf |
| 10 | + |
| 11 | +tf_major_version = int(tf.__version__.split(".", maxsplit=1)[0]) |
| 12 | +if tf_major_version == 1: |
| 13 | + from keras.preprocessing import image |
| 14 | +else: |
| 15 | + from tensorflow.keras.preprocessing import image |
5 | 16 |
|
6 | 17 |
|
7 | 18 | # pylint: disable=unused-argument
|
@@ -143,6 +154,58 @@ def rotate_facial_area(
|
143 | 154 | return (x1, y1, x2, y2)
|
144 | 155 |
|
145 | 156 |
|
| 157 | +def resize_image( |
| 158 | + img: np.ndarray, target_size: Tuple[int, int], min_max_norm: bool = True |
| 159 | +) -> np.ndarray: |
| 160 | + """ |
| 161 | + Resize an image to expected size of a ml model with adding black pixels. |
| 162 | + Ref: github.com/serengil/deepface/blob/master/deepface/modules/preprocessing.py |
| 163 | + Args: |
| 164 | + img (np.ndarray): pre-loaded image as numpy array |
| 165 | + target_size (tuple): input shape of ml model |
| 166 | + min_max_norm (bool): set this to True if you want to normalize image in [0, 1]. |
| 167 | + this is only running when target_size is not none. |
| 168 | + for instance, matplotlib expects inputs in this scale. (default is True) |
| 169 | + Returns: |
| 170 | + img (np.ndarray): resized input image |
| 171 | + """ |
| 172 | + factor_0 = target_size[0] / img.shape[0] |
| 173 | + factor_1 = target_size[1] / img.shape[1] |
| 174 | + factor = min(factor_0, factor_1) |
| 175 | + |
| 176 | + dsize = ( |
| 177 | + int(img.shape[1] * factor), |
| 178 | + int(img.shape[0] * factor), |
| 179 | + ) |
| 180 | + img = cv2.resize(img, dsize) |
| 181 | + |
| 182 | + diff_0 = target_size[0] - img.shape[0] |
| 183 | + diff_1 = target_size[1] - img.shape[1] |
| 184 | + |
| 185 | + # Put the base image in the middle of the padded image |
| 186 | + img = np.pad( |
| 187 | + img, |
| 188 | + ( |
| 189 | + (diff_0 // 2, diff_0 - diff_0 // 2), |
| 190 | + (diff_1 // 2, diff_1 - diff_1 // 2), |
| 191 | + (0, 0), |
| 192 | + ), |
| 193 | + "constant", |
| 194 | + ) |
| 195 | + |
| 196 | + # double check: if target image is not still the same size with target. |
| 197 | + if img.shape[0:2] != target_size: |
| 198 | + img = cv2.resize(img, target_size) |
| 199 | + |
| 200 | + # make it 4-dimensional how ML models expect |
| 201 | + img = image.img_to_array(img) |
| 202 | + |
| 203 | + if min_max_norm is True and img.max() > 1: |
| 204 | + img = (img.astype(np.float32) / 255.0).astype(np.float32) |
| 205 | + |
| 206 | + return img |
| 207 | + |
| 208 | + |
146 | 209 | def bbox_pred(boxes, box_deltas):
|
147 | 210 | """
|
148 | 211 | This function is copied from the following code snippet:
|
|
0 commit comments