Skip to content

Commit

Permalink
Add standardization_parameters metaparameter handle
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoszptak committed Feb 8, 2024
1 parent 8c02bfd commit 089cd88
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import numpy as np


class StandardizationParameters:
mean: float
std: float

def __init__(self):
self.mean = np.array([0.0, 0.0, 0.0], dtype=np.float32)
self.std = np.array([1.0, 1.0, 1.0], dtype=np.float32)

def set_mean_std(self, mean: np.array, std: np.array):
self.mean = np.array(mean, dtype=np.float32)
self.std = np.array(std, dtype=np.float32)
10 changes: 5 additions & 5 deletions src/deepness/processing/map_processor/map_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def __init__(self,
def set_results_img(self, img):
if self._result_img is not None:
raise Exception("Result image already created!")

self._result_img = img

def get_result_img(self):
Expand Down Expand Up @@ -215,17 +215,17 @@ def tiles_generator_batched(self) -> Tuple[np.ndarray, List[TileParams]]:
"""
Iterate over all tiles, as a Python generator function, but return them in batches
"""

tile_img_batch, tile_params_batch = [], []

for tile_img, tile_params in self.tiles_generator():
tile_img_batch.append(tile_img)
tile_params_batch.append(tile_params)

if len(tile_img_batch) >= self.params.batch_size:
yield np.array(tile_img_batch), tile_params_batch
tile_img_batch, tile_params_batch = [], []

if len(tile_img_batch) > 0:
yield np.array(tile_img_batch), tile_params_batch
tile_img_batch, tile_params_batch = [], []
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ def _run(self) -> MapProcessingResult:
except Exception as e:
return MapProcessingResultFailed(f"Error occurred while reading query image: {e}")

query_img_emb = self.model.process(np.array([query_img]))[0]
# some hardcoded code for recognition model
query_img_resized = cv2.resize(query_img, self.model.get_input_shape()[2:4][::-1])
query_img_batched = np.array([query_img_resized])

query_img_emb = self.model.process(query_img_batched)[0]

final_shape_px = (
self.img_size_y_pixels,
Expand Down
35 changes: 26 additions & 9 deletions src/deepness/processing/models/model_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import cv2
import numpy as np

import deepness.processing.models.preprocessing_utils as preprocessing_utils
from deepness.common.lazy_package_loader import LazyPackageLoader
from deepness.common.processing_parameters.standardization_parameters import StandardizationParameters

ort = LazyPackageLoader('onnxruntime')

Expand Down Expand Up @@ -44,6 +46,7 @@ def __init__(self, model_file_path: str):
self.input_name = input_0.name

self.outputs_layers = self.sess.get_outputs()
self.standardization_parameters: StandardizationParameters = self.get_metadata_standarization_parameters()

@classmethod
def get_model_type_from_metadata(cls, model_file_path: str) -> Optional[str]:
Expand Down Expand Up @@ -169,6 +172,25 @@ def get_metadata_model_type(self) -> Optional[str]:
return str(value).capitalize()
return None

def get_metadata_standarization_parameters(self) -> Optional[StandardizationParameters]:
""" Get standardization parameters from metadata if exists
Returns
-------
Optional[StandardizationParameters]
Standardization parameters or None if not found
"""
meta = self.sess.get_modelmeta()
name_mean = 'standardization_parameters_mean'
name_std = 'standardization_parameters_std'

if name_mean in meta.custom_metadata_map and name_std in meta.custom_metadata_map:
mean = json.loads(meta.custom_metadata_map[name_mean])
std = json.loads(meta.custom_metadata_map[name_std])
return StandardizationParameters().set_mean_std(mean=mean, std=std)

return StandardizationParameters() # default, no standardization

def get_metadata_resolution(self) -> Optional[float]:
""" Get resolution from metadata if exists
Expand Down Expand Up @@ -357,15 +379,10 @@ def preprocessing(self, tiles_batched: np.ndarray) -> np.ndarray:
np.ndarray
Preprocessed batch of image (N,C,H,W), RGB, 0-1
"""
tiles_batched = tiles_batched[:, :, :, :self.input_shape[-3]]

if tiles_batched.shape[0] == 1 and tiles_batched.shape[1:3] != self.input_shape[2:4]:
# if the model has a fixed batch size, we can resize the input
tiles_batched = np.array([cv2.resize(tiles_batched[0], (self.input_shape[3], self.input_shape[2]))])

tiles_batched = tiles_batched.astype('float32')
tiles_batched /= 255
tiles_batched = tiles_batched.transpose(0, 3, 1, 2)
tiles_batched = preprocessing_utils.limit_channels_number(tiles_batched, limit=self.input_shape[-3])
tiles_batched = preprocessing_utils.normalize_values_to_01(tiles_batched)
tiles_batched = preprocessing_utils.standardize_values(tiles_batched, params=self.standardization_parameters)
tiles_batched = preprocessing_utils.transpose_nhwc_to_nchw(tiles_batched)

return tiles_batched

Expand Down
42 changes: 42 additions & 0 deletions src/deepness/processing/models/preprocessing_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import cv2
import numpy as np

from deepness.common.processing_parameters.standardization_parameters import StandardizationParameters


def limit_channels_number(tiles_batched: np.array, limit: int) -> np.array:
""" Limit the number of channels in the input image to the model
:param tiles_batched: Batch of tiles
:param limit: Number of channels to keep
:return: Batch of tiles with limited number of channels
"""
return tiles_batched[:, :, :, :limit]


def normalize_values_to_01(tiles_batched: np.array) -> np.array:
""" Normalize the values of the input image to the model to the range [0, 1]
:param tiles_batched: Batch of tiles
:return: Batch of tiles with values in the range [0, 1], in float32
"""
return np.float32(tiles_batched * 1./255.)


def standardize_values(tiles_batched: np.array, params: StandardizationParameters) -> np.array:
""" Standardize the input image to the model
:param tiles_batched: Batch of tiles
:param params: Parameters for standardization of type STANDARIZE_PARAMS
:return: Batch of tiles with standardized values
"""
return (tiles_batched - params.mean) / params.std


def transpose_nhwc_to_nchw(tiles_batched: np.array) -> np.array:
""" Transpose the input image from NHWC to NCHW
:param tiles_batched: Batch of tiles in NHWC format
:return: Batch of tiles in NCHW format
"""
return np.transpose(tiles_batched, (0, 3, 1, 2))

0 comments on commit 089cd88

Please sign in to comment.