CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
image_processing_convnext.py326 linesDownload Raw Back to convnext
1# coding=utf-82# Copyright 2022 The HuggingFace Inc. team. All rights reserved.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8#     http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15"""Image processor class for ConvNeXT."""16 17from typing import Optional, Union18 19import numpy as np20 21from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict22from ...image_transforms import (23    center_crop,24    get_resize_output_image_size,25    resize,26    to_channel_dimension_format,27)28from ...image_utils import (29    IMAGENET_STANDARD_MEAN,30    IMAGENET_STANDARD_STD,31    ChannelDimension,32    ImageInput,33    PILImageResampling,34    infer_channel_dimension_format,35    is_scaled_image,36    make_flat_list_of_images,37    to_numpy_array,38    valid_images,39    validate_preprocess_arguments,40)41from ...utils import TensorType, filter_out_non_signature_kwargs, is_vision_available, logging42from ...utils.import_utils import requires43 44 45if is_vision_available():46    import PIL47 48 49logger = logging.get_logger(__name__)50 51 52@requires(backends=("vision",))53class ConvNextImageProcessor(BaseImageProcessor):54    r"""55    Constructs a ConvNeXT image processor.56 57    Args:58        do_resize (`bool`, *optional*, defaults to `True`):59            Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be overridden60            by `do_resize` in the `preprocess` method.61        size (`dict[str, int]` *optional*, defaults to `{"shortest_edge": 384}`):62            Resolution of the output image after `resize` is applied. If `size["shortest_edge"]` >= 384, the image is63            resized to `(size["shortest_edge"], size["shortest_edge"])`. Otherwise, the smaller edge of the image will64            be matched to `int(size["shortest_edge"]/crop_pct)`, after which the image is cropped to65            `(size["shortest_edge"], size["shortest_edge"])`. Only has an effect if `do_resize` is set to `True`. Can66            be overridden by `size` in the `preprocess` method.67        crop_pct (`float` *optional*, defaults to 224 / 256):68            Percentage of the image to crop. Only has an effect if `do_resize` is `True` and size < 384. Can be69            overridden by `crop_pct` in the `preprocess` method.70        resample (`PILImageResampling`, *optional*, defaults to `Resampling.BILINEAR`):71            Resampling filter to use if resizing the image. Can be overridden by `resample` in the `preprocess` method.72        do_rescale (`bool`, *optional*, defaults to `True`):73            Whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by `do_rescale` in74            the `preprocess` method.75        rescale_factor (`int` or `float`, *optional*, defaults to `1/255`):76            Scale factor to use if rescaling the image. Can be overridden by `rescale_factor` in the `preprocess`77            method.78        do_normalize (`bool`, *optional*, defaults to `True`):79            Whether to normalize the image. Can be overridden by the `do_normalize` parameter in the `preprocess`80            method.81        image_mean (`float` or `list[float]`, *optional*, defaults to `IMAGENET_STANDARD_MEAN`):82            Mean to use if normalizing the image. This is a float or list of floats the length of the number of83            channels in the image. Can be overridden by the `image_mean` parameter in the `preprocess` method.84        image_std (`float` or `list[float]`, *optional*, defaults to `IMAGENET_STANDARD_STD`):85            Standard deviation to use if normalizing the image. This is a float or list of floats the length of the86            number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method.87    """88 89    model_input_names = ["pixel_values"]90 91    def __init__(92        self,93        do_resize: bool = True,94        size: Optional[dict[str, int]] = None,95        crop_pct: Optional[float] = None,96        resample: PILImageResampling = PILImageResampling.BILINEAR,97        do_rescale: bool = True,98        rescale_factor: Union[int, float] = 1 / 255,99        do_normalize: bool = True,100        image_mean: Optional[Union[float, list[float]]] = None,101        image_std: Optional[Union[float, list[float]]] = None,102        **kwargs,103    ) -> None:104        super().__init__(**kwargs)105        size = size if size is not None else {"shortest_edge": 384}106        size = get_size_dict(size, default_to_square=False)107 108        self.do_resize = do_resize109        self.size = size110        # Default value set here for backwards compatibility where the value in config is None111        self.crop_pct = crop_pct if crop_pct is not None else 224 / 256112        self.resample = resample113        self.do_rescale = do_rescale114        self.rescale_factor = rescale_factor115        self.do_normalize = do_normalize116        self.image_mean = image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN117        self.image_std = image_std if image_std is not None else IMAGENET_STANDARD_STD118 119    def resize(120        self,121        image: np.ndarray,122        size: dict[str, int],123        crop_pct: float,124        resample: PILImageResampling = PILImageResampling.BICUBIC,125        data_format: Optional[Union[str, ChannelDimension]] = None,126        input_data_format: Optional[Union[str, ChannelDimension]] = None,127        **kwargs,128    ) -> np.ndarray:129        """130        Resize an image.131 132        Args:133            image (`np.ndarray`):134                Image to resize.135            size (`dict[str, int]`):136                Dictionary of the form `{"shortest_edge": int}`, specifying the size of the output image. If137                `size["shortest_edge"]` >= 384 image is resized to `(size["shortest_edge"], size["shortest_edge"])`.138                Otherwise, the smaller edge of the image will be matched to `int(size["shortest_edge"] / crop_pct)`,139                after which the image is cropped to `(size["shortest_edge"], size["shortest_edge"])`.140            crop_pct (`float`):141                Percentage of the image to crop. Only has an effect if size < 384.142            resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`):143                Resampling filter to use when resizing the image.144            data_format (`str` or `ChannelDimension`, *optional*):145                The channel dimension format of the image. If not provided, it will be the same as the input image.146            input_data_format (`ChannelDimension` or `str`, *optional*):147                The channel dimension format of the input image. If not provided, it will be inferred from the input148                image.149        """150        size = get_size_dict(size, default_to_square=False)151        if "shortest_edge" not in size:152            raise ValueError(f"Size dictionary must contain 'shortest_edge' key. Got {size.keys()}")153        shortest_edge = size["shortest_edge"]154 155        if shortest_edge < 384:156            # maintain same ratio, resizing shortest edge to shortest_edge/crop_pct157            resize_shortest_edge = int(shortest_edge / crop_pct)158            resize_size = get_resize_output_image_size(159                image, size=resize_shortest_edge, default_to_square=False, input_data_format=input_data_format160            )161            image = resize(162                image=image,163                size=resize_size,164                resample=resample,165                data_format=data_format,166                input_data_format=input_data_format,167                **kwargs,168            )169            # then crop to (shortest_edge, shortest_edge)170            return center_crop(171                image=image,172                size=(shortest_edge, shortest_edge),173                data_format=data_format,174                input_data_format=input_data_format,175                **kwargs,176            )177        else:178            # warping (no cropping) when evaluated at 384 or larger179            return resize(180                image,181                size=(shortest_edge, shortest_edge),182                resample=resample,183                data_format=data_format,184                input_data_format=input_data_format,185                **kwargs,186            )187 188    @filter_out_non_signature_kwargs()189    def preprocess(190        self,191        images: ImageInput,192        do_resize: Optional[bool] = None,193        size: Optional[dict[str, int]] = None,194        crop_pct: Optional[float] = None,195        resample: Optional[PILImageResampling] = None,196        do_rescale: Optional[bool] = None,197        rescale_factor: Optional[float] = None,198        do_normalize: Optional[bool] = None,199        image_mean: Optional[Union[float, list[float]]] = None,200        image_std: Optional[Union[float, list[float]]] = None,201        return_tensors: Optional[Union[str, TensorType]] = None,202        data_format: ChannelDimension = ChannelDimension.FIRST,203        input_data_format: Optional[Union[str, ChannelDimension]] = None,204    ) -> PIL.Image.Image:205        """206        Preprocess an image or batch of images.207 208        Args:209            images (`ImageInput`):210                Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If211                passing in images with pixel values between 0 and 1, set `do_rescale=False`.212            do_resize (`bool`, *optional*, defaults to `self.do_resize`):213                Whether to resize the image.214            size (`dict[str, int]`, *optional*, defaults to `self.size`):215                Size of the output image after `resize` has been applied. If `size["shortest_edge"]` >= 384, the image216                is resized to `(size["shortest_edge"], size["shortest_edge"])`. Otherwise, the smaller edge of the217                image will be matched to `int(size["shortest_edge"]/ crop_pct)`, after which the image is cropped to218                `(size["shortest_edge"], size["shortest_edge"])`. Only has an effect if `do_resize` is set to `True`.219            crop_pct (`float`, *optional*, defaults to `self.crop_pct`):220                Percentage of the image to crop if size < 384.221            resample (`int`, *optional*, defaults to `self.resample`):222                Resampling filter to use if resizing the image. This can be one of `PILImageResampling`, filters. Only223                has an effect if `do_resize` is set to `True`.224            do_rescale (`bool`, *optional*, defaults to `self.do_rescale`):225                Whether to rescale the image values between [0 - 1].226            rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`):227                Rescale factor to rescale the image by if `do_rescale` is set to `True`.228            do_normalize (`bool`, *optional*, defaults to `self.do_normalize`):229                Whether to normalize the image.230            image_mean (`float` or `list[float]`, *optional*, defaults to `self.image_mean`):231                Image mean.232            image_std (`float` or `list[float]`, *optional*, defaults to `self.image_std`):233                Image standard deviation.234            return_tensors (`str` or `TensorType`, *optional*):235                The type of tensors to return. Can be one of:236                    - Unset: Return a list of `np.ndarray`.237                    - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`.238                    - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`.239                    - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`.240                    - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`.241            data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`):242                The channel dimension format for the output image. Can be one of:243                - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.244                - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.245                - Unset: Use the channel dimension format of the input image.246            input_data_format (`ChannelDimension` or `str`, *optional*):247                The channel dimension format for the input image. If unset, the channel dimension format is inferred248                from the input image. Can be one of:249                - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.250                - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.251                - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.252        """253        do_resize = do_resize if do_resize is not None else self.do_resize254        crop_pct = crop_pct if crop_pct is not None else self.crop_pct255        resample = resample if resample is not None else self.resample256        do_rescale = do_rescale if do_rescale is not None else self.do_rescale257        rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor258        do_normalize = do_normalize if do_normalize is not None else self.do_normalize259        image_mean = image_mean if image_mean is not None else self.image_mean260        image_std = image_std if image_std is not None else self.image_std261 262        size = size if size is not None else self.size263        size = get_size_dict(size, default_to_square=False)264 265        images = make_flat_list_of_images(images)266 267        if not valid_images(images):268            raise ValueError(269                "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, "270                "torch.Tensor, tf.Tensor or jax.ndarray."271            )272 273        validate_preprocess_arguments(274            do_rescale=do_rescale,275            rescale_factor=rescale_factor,276            do_normalize=do_normalize,277            image_mean=image_mean,278            image_std=image_std,279            do_resize=do_resize,280            size=size,281            resample=resample,282        )283 284        # All transformations expect numpy arrays.285        images = [to_numpy_array(image) for image in images]286 287        if do_rescale and is_scaled_image(images[0]):288            logger.warning_once(289                "It looks like you are trying to rescale already rescaled images. If the input"290                " images have pixel values between 0 and 1, set `do_rescale=False` to avoid rescaling them again."291            )292 293        if input_data_format is None:294            # We assume that all images have the same channel dimension format.295            input_data_format = infer_channel_dimension_format(images[0])296 297        if do_resize:298            images = [299                self.resize(300                    image=image, size=size, crop_pct=crop_pct, resample=resample, input_data_format=input_data_format301                )302                for image in images303            ]304 305        if do_rescale:306            images = [307                self.rescale(image=image, scale=rescale_factor, input_data_format=input_data_format)308                for image in images309            ]310 311        if do_normalize:312            images = [313                self.normalize(image=image, mean=image_mean, std=image_std, input_data_format=input_data_format)314                for image in images315            ]316 317        images = [318            to_channel_dimension_format(image, data_format, input_channel_dim=input_data_format) for image in images319        ]320 321        data = {"pixel_values": images}322        return BatchFeature(data=data, tensor_type=return_tensors)323 324 325__all__ = ["ConvNextImageProcessor"]326 
Aluode/PerceptionLabPortable · CoolFace