diff --git a/README.md b/README.md index 3aff2e7..f338cea 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ +

English | 中文文档

## 🤗 Introduction @@ -194,7 +195,7 @@ LandmarksRandomTranslate() Execution Flag: False But, is ok if you pass a Tensor to a np.ndarray-like transform, **torchlm** will automatically be compatible with different data types and then wrap it back to the original type through a **autodtype** wrapper. -* Supported Transforms Sets, see [transforms.md](https://github.com/DefTruth/torchlm/blob/main/docs/api/transfroms.md). A detail example can be found at [test/transforms.py](https://github.com/DefTruth/torchlm/blob/main/test/transforms.py). +* Supported Transforms Sets, see [transforms.md](docs/api/transforms.md). A detail example can be found at [test/transforms.py](test/transforms.py). ### Training(TODO) * [ ] YOLOX @@ -210,7 +211,7 @@ LandmarksRandomTranslate() Execution Flag: False The ONNXRuntime(CPU/GPU), MNN, NCNN and TNN C++ inference of **torchlm** will be release at [lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit). ## 📖 Documentations -* [x] [Data Augmentation's API](docs/api/transfroms.md) +* [x] [Data Augmentation's API](docs/api/transforms.md) ## 🎓 License The code of **torchlm** is released under the MIT License. diff --git a/docs/README.pypi.md b/docs/README.pypi.md deleted file mode 100644 index 283f2bd..0000000 --- a/docs/README.pypi.md +++ /dev/null @@ -1,191 +0,0 @@ -![torchlm-logo](https://github.com/DefTruth/torchlm/blob/main/docs/res/logo.png) - -
- - - - - - -
- - -## 🤗 Introduction -**torchlm** is a PyTorch landmarks-only library with **100+ data augmentations**, **training** and **inference**. **torchlm** is only focus on any landmarks detection, such as face landmarks, hand keypoints and body keypoints, etc. It provides **30+** native data augmentations and can **bind** with **80+** transforms from torchvision and albumations, no matter the input is a np.ndarray or a torch Tensor, **torchlm** will automatically be compatible with different data types and then wrap it back to the original type through a **autodtype** wrapper. Further, **torchlm** will add modules for **training** and **inference** in the future. [❤️ Star 🌟👆🏻 this repo to support me if it does any helps to you, thanks ~ ] - -# 🆕 What's New - -* [2022/02/13]: Add **30+** native data augmentations and **bind** **80+** torchvision and albumations's transforms. - -## 🛠️ Usage - -### Requirements -* opencv-python-headless>=4.5.2 -* numpy>=1.14.4 -* torch>=1.6.0 -* torchvision>=0.9.0 -* albumentations>=1.1.0 - -### Installation -you can install **torchlm** directly from [pypi](https://pypi.org/project/torchlm/). -```shell -pip3 install torchlm -# install from specific pypi mirrors use '-i' -pip3 install torchlm -i https://pypi.org/simple/ -``` -or install from source. -```shell -# clone torchlm repository locally -git clone --depth=1 https://github.com/DefTruth/torchlm.git -cd torchlm -# install in editable mode -pip install -e . -``` - -### Data Augmentation -**torchlm** provides **30+** native data augmentations for landmarks and can **bind** with **80+** transforms from torchvision and albumations **torchlm.bind** method. Further, **torchlm.bind** provide a `prob` parameter at bind-level to force any transform or callable be a random-style. The data augmentations in **torchlm** are `safe` and `simplest`. Any transform operations at runtime cause landmarks outside will be auto drop to keep the number of landmarks unchanged. The layout format of landmarks is `xy` with shape `(N, 2)`, `N` denotes the number of the input landmarks. No matter the input is a np.ndarray or a torch Tensor, **torchlm** will automatically be compatible with different data types and then wrap it back to the original type through a **autodtype** wrapper. - -* use native torchlm transforms -```python -import torchlm -transform = torchlm.LandmarksCompose([ - # use native torchlm transforms - torchlm.LandmarksRandomScale(prob=0.5), - torchlm.LandmarksRandomTranslate(prob=0.5), - torchlm.LandmarksRandomShear(prob=0.5), - torchlm.LandmarksRandomMask(prob=0.5), - torchlm.LandmarksRandomBlur(kernel_range=(5, 25), prob=0.5), - torchlm.LandmarksRandomBrightness(prob=0.), - torchlm.LandmarksRandomRotate(40, prob=0.5, bins=8), - torchlm.LandmarksRandomCenterCrop((0.5, 1.0), (0.5, 1.0), prob=0.5), - # ... - ]) -``` -
- - - - - - - -
- -* **bind** torchvision and albumations's transform, using **torchlm.bind** -```python -import torchvision -import albumentations -import torchlm -transform = torchlm.LandmarksCompose([ - # use native torchlm transforms - torchlm.LandmarksRandomScale(prob=0.5), - # bind torchvision image only transforms - torchlm.bind(torchvision.transforms.GaussianBlur(kernel_size=(5, 25)), prob=0.5), # bind with a given prob - torchlm.bind(torchvision.transforms.RandomAutocontrast(p=0.5)), - # bind albumentations image only transforms - torchlm.bind(albumentations.ColorJitter(p=0.5)), - torchlm.bind(albumentations.GlassBlur(p=0.5)), - # bind albumentations dual transforms - torchlm.bind(albumentations.RandomCrop(height=200, width=200, p=0.5)), - torchlm.bind(albumentations.Rotate(p=0.5)), - # ... - ]) -``` -* **bind** custom callable array or Tensor functions, using **torchlm.bind** - -```python -# First, defined your custom functions -def callable_array_noop(img: np.ndarray, landmarks: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: - # do some transform here ... - return img.astype(np.uint32), landmarks.astype(np.float32) - -def callable_tensor_noop(img: Tensor, landmarks: Tensor) -> Tuple[Tensor, Tensor]: - # do some transform here ... - return img, landmarks -``` - -```python -# Then, bind your functions and put it into the transforms pipeline. -transform = torchlm.LandmarksCompose([ - # use native torchlm transforms - torchlm.LandmarksRandomScale(prob=0.5), - # bind custom callable array functions - torchlm.bind(callable_array_noop, bind_type=torchlm.BindEnum.Callable_Array), - # bind custom callable Tensor functions with a given prob - torchlm.bind(callable_tensor_noop, bind_type=torchlm.BindEnum.Callable_Tensor, prob=0.5), - # ... - ]) -``` -
- - - - - - - -
- - -* setup logging mode as `True` globally might help you figure out the runtime details -```python -import torchlm -# some global setting -torchlm.set_transforms_debug(True) -torchlm.set_transforms_logging(True) -torchlm.set_autodtype_logging(True) -``` -some detail information will show you at each runtime, the infos might look like -```shell -LandmarksRandomScale() AutoDtype Info: AutoDtypeEnum.Array_InOut -LandmarksRandomScale() Execution Flag: False -BindTorchVisionTransform(GaussianBlur())() AutoDtype Info: AutoDtypeEnum.Tensor_InOut -BindTorchVisionTransform(GaussianBlur())() Execution Flag: True -BindAlbumentationsTransform(ColorJitter())() AutoDtype Info: AutoDtypeEnum.Array_InOut -BindAlbumentationsTransform(ColorJitter())() Execution Flag: True -BindArrayCallable(callable_array_noop())() AutoDtype Info: AutoDtypeEnum.Array_InOut -BindArrayCallable(callable_array_noop())() Execution Flag: True -BindTensorCallable(callable_tensor_noop())() AutoDtype Info: AutoDtypeEnum.Tensor_InOut -BindTensorCallable(callable_tensor_noop())() Execution Flag: False -``` -* Execution Flag: True means current transform was executed successful, False means it was not executed because of the random probability or some Runtime Exceptions(torchlm will should the error infos if debug mode is True). -* AutoDtype Info: - * Array_InOut means current transform need a np.ndnarray as input and then output a np.ndarray. - * Tensor_InOut means current transform need a torch Tensor as input and then output a torch Tensor. - * Array_In means current transform needs a np.ndarray input and then output a torch Tensor. - * Tensor_In means current transform needs a torch Tensor input and then output a np.ndarray. - - But, is ok if you pass a Tensor to a np.ndarray-like transform, **torchlm** will automatically be compatible with different data types and then wrap it back to the original type through a **autodtype** wrapper. - - -* Supported Transforms Sets, see [transforms.md](https://github.com/DefTruth/torchlm/blob/main/docs/api/transfroms.md). A detail example can be found at [test/transforms.py](https://github.com/DefTruth/torchlm/blob/main/test/transforms.py). - -### Training(TODO) -* [ ] YOLOX -* [ ] YOLOv5 -* [ ] NanoDet -* [ ] PIPNet -* [ ] ResNet -* [ ] MobileNet -* [ ] ShuffleNet -* [ ] ... - -### Inference(TODO) -* [ ] ONNXRuntime -* [ ] MNN -* [ ] NCNN -* [ ] TNN -* [ ] ... - -## 📖 Documentations -* [ ] Data Augmentation's API (TODO) -* [ ] ... - -## 🎓 License -The code of **torchlm** is released under the MIT License. - -## ❤️ Contribution -Please consider ⭐ this repo if you like it, as it is the simplest way to support me. - -## 👋 Acknowledgement -The implementation of torchlm's transforms borrow the code from [Paperspace](https://github.com/Paperspace/DataAugmentationForObjectDetection/blob/master/data_aug/bbox_util.py) . diff --git a/docs/api/transfroms.md b/docs/api/transforms.md similarity index 98% rename from docs/api/transfroms.md rename to docs/api/transforms.md index 28fc67c..699e8b4 100644 --- a/docs/api/transfroms.md +++ b/docs/api/transforms.md @@ -1,144 +1,13 @@ -# Supported Transforms Set +# Data Augmentations API -## native torchlm's transforms - -```python -__all__ = [ - "LandmarksCompose", - "LandmarksNormalize", - "LandmarksUnNormalize", - "LandmarksToTensor", - "LandmarksToNumpy", - "LandmarksResize", - "LandmarksClip", - "LandmarksAlign", - "LandmarksRandomAlign", - "LandmarksRandomCenterCrop", - "LandmarksRandomHorizontalFlip", - "LandmarksHorizontalFlip", - "LandmarksRandomScale", - "LandmarksRandomTranslate", - "LandmarksRandomRotate", - "LandmarksRandomShear", - "LandmarksRandomHSV", - "LandmarksRandomMask", - "LandmarksRandomBlur", - "LandmarksRandomBrightness", - "LandmarksRandomPatches", - "LandmarksRandomBackground", - "LandmarksRandomPatchesWithAlpha", - "LandmarksRandomBackgroundWithAlpha", - "LandmarksRandomMaskWithAlpha", - "BindAlbumentationsTransform", - "BindTorchVisionTransform", - "BindArrayCallable", - "BindTensorCallable", - "BindEnum", - "bind", - "set_transforms_logging", - "set_transforms_debug" -] -``` - -## transforms from torchvision - -```python -# torchvision >= 0.9.0 -_Supported_Image_Only_Transform_Set: Tuple = ( - torchvision.transforms.Normalize, - torchvision.transforms.ColorJitter, - torchvision.transforms.Grayscale, - torchvision.transforms.RandomGrayscale, - torchvision.transforms.RandomErasing, - torchvision.transforms.GaussianBlur, - torchvision.transforms.RandomInvert, - torchvision.transforms.RandomPosterize, - torchvision.transforms.RandomSolarize, - torchvision.transforms.RandomAdjustSharpness, - torchvision.transforms.RandomAutocontrast, - torchvision.transforms.RandomEqualize -) -``` - -## transforms from albumentations - -```python -# albumentations >= v 1.1.0 -_Supported_Image_Only_Transform_Set: Tuple = ( - albumentations.Blur, - albumentations.CLAHE, - albumentations.ChannelDropout, - albumentations.ChannelShuffle, - albumentations.ColorJitter, - albumentations.Downscale, - albumentations.Emboss, - albumentations.Equalize, - albumentations.FDA, - albumentations.FancyPCA, - albumentations.FromFloat, - albumentations.GaussNoise, - albumentations.GaussianBlur, - albumentations.GlassBlur, - albumentations.HistogramMatching, - albumentations.HueSaturationValue, - albumentations.ISONoise, - albumentations.ImageCompression, - albumentations.InvertImg, - albumentations.MedianBlur, - albumentations.MotionBlur, - albumentations.Normalize, - albumentations.PixelDistributionAdaptation, - albumentations.Posterize, - albumentations.RGBShift, - albumentations.RandomBrightnessContrast, - albumentations.RandomFog, - albumentations.RandomGamma, - albumentations.RandomRain, - albumentations.RandomShadow, - albumentations.RandomSnow, - albumentations.RandomSunFlare, - albumentations.RandomToneCurve, - albumentations.Sharpen, - albumentations.Solarize, - albumentations.Superpixels, - albumentations.TemplateTransform, - albumentations.ToFloat, - albumentations.ToGray -) - -_Supported_Dual_Transform_Set: Tuple = ( - albumentations.Affine, - albumentations.CenterCrop, - albumentations.CoarseDropout, - albumentations.Crop, - albumentations.CropAndPad, - albumentations.CropNonEmptyMaskIfExists, - albumentations.Flip, - albumentations.HorizontalFlip, - albumentations.Lambda, - albumentations.LongestMaxSize, - albumentations.NoOp, - albumentations.PadIfNeeded, - albumentations.Perspective, - albumentations.PiecewiseAffine, - albumentations.RandomCrop, - albumentations.RandomCropNearBBox, - albumentations.RandomGridShuffle, - albumentations.RandomResizedCrop, - albumentations.RandomRotate90, - albumentations.RandomScale, - albumentations.RandomSizedCrop, - albumentations.Resize, - albumentations.Rotate, - albumentations.SafeRotate, - albumentations.ShiftScaleRotate, - albumentations.SmallestMaxSize, - albumentations.Transpose, - albumentations.VerticalFlip -) -``` +## Contents +* [torchlm原生数据增强方法API文档](#torchlm-transforms-api) +* [Native Torchlm's Transforms](#torchlm-native-transforms) +* [Transforms from TorchVision](#torchlm-torchvision-transforms) +* [Transforms from Albumentations](#torchlm-albumentations-transforms) ## torchlm原生数据增强方法API文档 +
* LandmarksNormalize: 对img进行归一化处理,x = (x - mean) / std,对于landmarks不做任何处理。初始化参数说明,mean: float, 均值,默认为127.5;std: float, 标准差,默认128.0; @@ -706,3 +575,144 @@ class LandmarksCompose(object): ): ``` +## Native torchlm's Transforms +
+ +```python +__all__ = [ + "LandmarksCompose", + "LandmarksNormalize", + "LandmarksUnNormalize", + "LandmarksToTensor", + "LandmarksToNumpy", + "LandmarksResize", + "LandmarksClip", + "LandmarksAlign", + "LandmarksRandomAlign", + "LandmarksRandomCenterCrop", + "LandmarksRandomHorizontalFlip", + "LandmarksHorizontalFlip", + "LandmarksRandomScale", + "LandmarksRandomTranslate", + "LandmarksRandomRotate", + "LandmarksRandomShear", + "LandmarksRandomHSV", + "LandmarksRandomMask", + "LandmarksRandomBlur", + "LandmarksRandomBrightness", + "LandmarksRandomPatches", + "LandmarksRandomBackground", + "LandmarksRandomPatchesWithAlpha", + "LandmarksRandomBackgroundWithAlpha", + "LandmarksRandomMaskWithAlpha", + "BindAlbumentationsTransform", + "BindTorchVisionTransform", + "BindArrayCallable", + "BindTensorCallable", + "BindEnum", + "bind", + "set_transforms_logging", + "set_transforms_debug" +] +``` + +## Transforms from TorchVision +
+ +```python +# torchvision >= 0.9.0 +_Supported_Image_Only_Transform_Set: Tuple = ( + torchvision.transforms.Normalize, + torchvision.transforms.ColorJitter, + torchvision.transforms.Grayscale, + torchvision.transforms.RandomGrayscale, + torchvision.transforms.RandomErasing, + torchvision.transforms.GaussianBlur, + torchvision.transforms.RandomInvert, + torchvision.transforms.RandomPosterize, + torchvision.transforms.RandomSolarize, + torchvision.transforms.RandomAdjustSharpness, + torchvision.transforms.RandomAutocontrast, + torchvision.transforms.RandomEqualize +) +``` + +## Transforms from Albumentations +
+ +```python +# albumentations >= v 1.1.0 +_Supported_Image_Only_Transform_Set: Tuple = ( + albumentations.Blur, + albumentations.CLAHE, + albumentations.ChannelDropout, + albumentations.ChannelShuffle, + albumentations.ColorJitter, + albumentations.Downscale, + albumentations.Emboss, + albumentations.Equalize, + albumentations.FDA, + albumentations.FancyPCA, + albumentations.FromFloat, + albumentations.GaussNoise, + albumentations.GaussianBlur, + albumentations.GlassBlur, + albumentations.HistogramMatching, + albumentations.HueSaturationValue, + albumentations.ISONoise, + albumentations.ImageCompression, + albumentations.InvertImg, + albumentations.MedianBlur, + albumentations.MotionBlur, + albumentations.Normalize, + albumentations.PixelDistributionAdaptation, + albumentations.Posterize, + albumentations.RGBShift, + albumentations.RandomBrightnessContrast, + albumentations.RandomFog, + albumentations.RandomGamma, + albumentations.RandomRain, + albumentations.RandomShadow, + albumentations.RandomSnow, + albumentations.RandomSunFlare, + albumentations.RandomToneCurve, + albumentations.Sharpen, + albumentations.Solarize, + albumentations.Superpixels, + albumentations.TemplateTransform, + albumentations.ToFloat, + albumentations.ToGray +) + +_Supported_Dual_Transform_Set: Tuple = ( + albumentations.Affine, + albumentations.CenterCrop, + albumentations.CoarseDropout, + albumentations.Crop, + albumentations.CropAndPad, + albumentations.CropNonEmptyMaskIfExists, + albumentations.Flip, + albumentations.HorizontalFlip, + albumentations.Lambda, + albumentations.LongestMaxSize, + albumentations.NoOp, + albumentations.PadIfNeeded, + albumentations.Perspective, + albumentations.PiecewiseAffine, + albumentations.RandomCrop, + albumentations.RandomCropNearBBox, + albumentations.RandomGridShuffle, + albumentations.RandomResizedCrop, + albumentations.RandomRotate90, + albumentations.RandomScale, + albumentations.RandomSizedCrop, + albumentations.Resize, + albumentations.Rotate, + albumentations.SafeRotate, + albumentations.ShiftScaleRotate, + albumentations.SmallestMaxSize, + albumentations.Transpose, + albumentations.VerticalFlip +) +``` + diff --git a/setup.py b/setup.py index b48c720..93da0f0 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ def get_long_description(): setuptools.setup( name="torchlm", - version="0.1.4", + version="0.1.5", author="DefTruth", author_email="qyjdef@163.com", description="A PyTorch landmarks-only library with 100+ data augmentations, " diff --git a/torchlm/__init__.py b/torchlm/__init__.py index 704798f..d26825b 100644 --- a/torchlm/__init__.py +++ b/torchlm/__init__.py @@ -1,5 +1,5 @@ # Versions -__version__ = '0.1.4' +__version__ = '0.1.5' # Transforms Module: 100+ transforms available, can bind torchvision and # albumentations into torchlm pipeline with autodtype wrapper. from .transforms import *