The image preprocessor loads an image from disk and prepares it as needed for batching. This includes padding, resizing, normalization, data type casting, and transposing. This Image Batcher implements one algorithm for now: * EfficientDet: Resizes and pads the image
(self, image_path)
| 107 | self.preprocessor = preprocessor |
| 108 | |
| 109 | def preprocess_image(self, image_path): |
| 110 | """ |
| 111 | The image preprocessor loads an image from disk and prepares it as needed for batching. This includes padding, |
| 112 | resizing, normalization, data type casting, and transposing. |
| 113 | This Image Batcher implements one algorithm for now: |
| 114 | * EfficientDet: Resizes and pads the image to fit the input size. |
| 115 | :param image_path: The path to the image on disk to load. |
| 116 | :return: Two values: A numpy array holding the image sample, ready to be contacatenated into the rest of the |
| 117 | batch, and the resize scale used, if any. |
| 118 | """ |
| 119 | |
| 120 | def resize_pad(image, pad_color=(0, 0, 0)): |
| 121 | """ |
| 122 | A subroutine to implement padding and resizing. This will resize the image to fit fully within the input |
| 123 | size, and pads the remaining bottom-right portions with the value provided. |
| 124 | :param image: The PIL image object |
| 125 | :pad_color: The RGB values to use for the padded area. Default: Black/Zeros. |
| 126 | :return: Two values: The PIL image object already padded and cropped, and the resize scale used. |
| 127 | """ |
| 128 | width, height = image.size |
| 129 | width_scale = width / self.width |
| 130 | height_scale = height / self.height |
| 131 | scale = 1.0 / max(width_scale, height_scale) |
| 132 | image = image.resize((round(width * scale), round(height * scale)), resample=Image.BILINEAR) |
| 133 | pad = Image.new("RGB", (self.width, self.height)) |
| 134 | pad.paste(pad_color, [0, 0, self.width, self.height]) |
| 135 | pad.paste(image) |
| 136 | return pad, scale |
| 137 | |
| 138 | scale = None |
| 139 | image = Image.open(image_path) |
| 140 | image = image.convert(mode="RGB") |
| 141 | if self.preprocessor == "EfficientDet": |
| 142 | # For EfficientNet V2: Resize & Pad with ImageNet mean values and keep as [0,255] Normalization |
| 143 | image, scale = resize_pad(image, (124, 116, 104)) |
| 144 | image = np.asarray(image, dtype=self.dtype) |
| 145 | # [0-1] Normalization, Mean subtraction and Std Dev scaling are part of the EfficientDet graph, so |
| 146 | # no need to do it during preprocessing here |
| 147 | else: |
| 148 | print("Preprocessing method {} not supported".format(self.preprocessor)) |
| 149 | sys.exit(1) |
| 150 | if self.format == "NCHW": |
| 151 | image = np.transpose(image, (2, 0, 1)) |
| 152 | return image, scale |
| 153 | |
| 154 | def get_batch(self): |
| 155 | """ |