Skip to content

Commit

Permalink
Pr 1789 (#1790)
Browse files Browse the repository at this point in the history
* PlanckianJitter implementation

* Fix pre-commit errors

* Fixes on top of pr_1789

* Docstring

* Fix in const dict

* Fix

* Merge

* refactoring

* Added PlankianJitter

* Added PlankianJitter to Readme

* pre-commit fixes

* Fix in readme

* Fix in readme

* Fix in readme

* Fix in readme

---------

Co-authored-by: Jamil Zakirov <[email protected]>
  • Loading branch information
ternaus and zakajd committed Jun 17, 2024
1 parent 30ac95e commit 834268b
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ repos:
types: [python]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.8
rev: v0.4.9
hooks:
# Run the linter.
- id: ruff
Expand Down
75 changes: 38 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ Pixel-level transforms will change just an input image and will leave any additi
- [MultiplicativeNoise](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.MultiplicativeNoise)
- [Normalize](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.Normalize)
- [PixelDistributionAdaptation](https://albumentations.ai/docs/api_reference/augmentations/domain_adaptation/#albumentations.augmentations.domain_adaptation.PixelDistributionAdaptation)
- [PlanckianJitter](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.PlanckianJitter)
- [Posterize](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.Posterize)
- [RGBShift](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.RGBShift)
- [RandomBrightnessContrast](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.RandomBrightnessContrast)
Expand Down Expand Up @@ -288,43 +289,43 @@ To run the benchmark yourself, follow the instructions in [benchmark/README.md](
Results for running the benchmark on the first 2000 images from the ImageNet validation set using an AMD Ryzen Threadripper 3970X CPU.
The table shows how many images per second can be processed on a single core; higher is better.

| Library | Version |
|---------|---------|
| Python | 3.10.13 (main, Sep 11 2023, 13:44:35) [GCC 11.2.0] |
| albumentations | 1.4.8 |
| imgaug | 0.4.0 |
| torchvision | 0.18.1+rocm6.0 |
| numpy | 1.26.4 |
| opencv-python-headless | 4.10.0.82 |
| scikit-image | 0.23.2 |
| scipy | 1.13.1 |
| pillow | 10.3.0 |
| kornia | 0.7.2 |
| augly | 1.0.0 |

| |albumentations<br><small>1.4.8</small>|torchvision<br><small>0.18.1+rocm6.0</small>|kornia<br><small>0.7.2</small>|augly<br><small>1.0.0</small>|imgaug<br><small>0.4.0</small>|
|-----------------|--------------------------------------|--------------------------------------------|------------------------------|-----------------------------|------------------------------|
|HorizontalFlip |**8084 ± 30** |2422 ± 16 |940 ± 10 |3633 ± 7 |4869 ± 10 |
|VerticalFlip |7330 ± 11 |2541 ± 2 |945 ± 4 |4807 ± 4 |**8400 ± 11** |
|Rotate |535 ± 5 |144 ± 2 |202 ± 1 |**572 ± 2** |494 ± 1 |
|Affine |**1504 ± 46** |153 ± 1 |197 ± 1 |- |671 ± 2 |
|Equalize |1005 ± 1 |328 ± 2 |76 ± 1 |- |**1165 ± 1** |
|RandomCrop64 |20880 ± 170 |15792 ± 23 |833 ± 1 |**21313 ± 603** |5547 ± 2 |
|RandomResizedCrop|**2272 ± 6** |1113 ± 5 |189 ± 1 |- |- |
|ShiftRGB |**1708 ± 2** |- |425 ± 1 |- |1480 ± 11 |
|Resize |**2209 ± 1** |1285 ± 3 |200 ± 1 |430 ± 1 |1690 ± 1 |
|RandomGamma |**3638 ± 7** |229 ± 1 |213 ± 1 |- |2307 ± 3 |
|Grayscale |**7234 ± 4** |1628 ± 6 |447 ± 1 |2535 ± 1 |1052 ± 6 |
|ColorJitter |**438 ± 1** |50 ± 1 |47 ± 1 |214 ± 1 |- |
|RandomPerspective|457 ± 2 |122 ± 1 |115 ± 1 |- |**460 ± 2** |
|GaussianBlur |**2073 ± 1** |110 ± 2 |74 ± 2 |162 ± 1 |1271 ± 1 |
|MedianBlur |536 ± 1 |- |3 ± 0 |- |**564 ± 1** |
|MotionBlur |**2156 ± 8** |- |98 ± 1 |- |503 ± 1 |
|Posterize |**3435 ± 2** |2574 ± 2 |312 ± 9 |- |1894 ± 1 |
|JpegCompression |**805 ± 1** |- |- |679 ± 16 |427 ± 1 |
|GaussianNoise |**239 ± 1** |- |- |67 ± 1 |124 ± 1 |
|Elastic |126 ± 1 |4 ± 0 |1 ± 0 |- |**128 ± 1** |
|Normalize |**1056 ± 1** |429 ± 1 |398 ± 1 |- |- |
| Library | Version |
| ---------------------- | -------------------------------------------------- |
| Python | 3.10.13 (main, Sep 11 2023, 13:44:35) [GCC 11.2.0] |
| albumentations | 1.4.8 |
| imgaug | 0.4.0 |
| torchvision | 0.18.1+rocm6.0 |
| numpy | 1.26.4 |
| opencv-python-headless | 4.10.0.82 |
| scikit-image | 0.23.2 |
| scipy | 1.13.1 |
| pillow | 10.3.0 |
| kornia | 0.7.2 |
| augly | 1.0.0 |

| | albumentations<br><small>1.4.8</small> | torchvision<br><small>0.18.1+rocm6.0</small> | kornia<br><small>0.7.2</small> | augly<br><small>1.0.0</small> | imgaug<br><small>0.4.0</small> |
| ----------------- | -------------------------------------- | -------------------------------------------- | ------------------------------ | ----------------------------- | ------------------------------ |
| HorizontalFlip | **8084 ± 30** | 2422 ± 16 | 940 ± 10 | 3633 ± 7 | 4869 ± 10 |
| VerticalFlip | 7330 ± 11 | 2541 ± 2 | 945 ± 4 | 4807 ± 4 | **8400 ± 11** |
| Rotate | 535 ± 5 | 144 ± 2 | 202 ± 1 | **572 ± 2** | 494 ± 1 |
| Affine | **1504 ± 46** | 153 ± 1 | 197 ± 1 | - | 671 ± 2 |
| Equalize | 1005 ± 1 | 328 ± 2 | 76 ± 1 | - | **1165 ± 1** |
| RandomCrop64 | 20880 ± 170 | 15792 ± 23 | 833 ± 1 | **21313 ± 603** | 5547 ± 2 |
| RandomResizedCrop | **2272 ± 6** | 1113 ± 5 | 189 ± 1 | - | - |
| ShiftRGB | **1708 ± 2** | - | 425 ± 1 | - | 1480 ± 11 |
| Resize | **2209 ± 1** | 1285 ± 3 | 200 ± 1 | 430 ± 1 | 1690 ± 1 |
| RandomGamma | **3638 ± 7** | 229 ± 1 | 213 ± 1 | - | 2307 ± 3 |
| Grayscale | **7234 ± 4** | 1628 ± 6 | 447 ± 1 | 2535 ± 1 | 1052 ± 6 |
| ColorJitter | **438 ± 1** | 50 ± 1 | 47 ± 1 | 214 ± 1 | - |
| RandomPerspective | 457 ± 2 | 122 ± 1 | 115 ± 1 | - | **460 ± 2** |
| GaussianBlur | **2073 ± 1** | 110 ± 2 | 74 ± 2 | 162 ± 1 | 1271 ± 1 |
| MedianBlur | 536 ± 1 | - | 3 ± 0 | - | **564 ± 1** |
| MotionBlur | **2156 ± 8** | - | 98 ± 1 | - | 503 ± 1 |
| Posterize | **3435 ± 2** | 2574 ± 2 | 312 ± 9 | - | 1894 ± 1 |
| JpegCompression | **805 ± 1** | - | - | 679 ± 16 | 427 ± 1 |
| GaussianNoise | **239 ± 1** | - | - | 67 ± 1 | 124 ± 1 |
| Elastic | 126 ± 1 | 4 ± 0 | 1 ± 0 | - | **128 ± 1** |
| Normalize | **1056 ± 1** | 429 ± 1 | 398 ± 1 | - | - |

## Contributing

Expand Down
82 changes: 82 additions & 0 deletions albumentations/augmentations/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
ColorType,
ImageMode,
NumericType,
PlanckianJitterMode,
SizeType,
SpatterMode,
)
Expand Down Expand Up @@ -1436,6 +1437,87 @@ def center(width: NumericType, height: NumericType) -> Tuple[float, float]:
return width / 2 - 0.5, height / 2 - 0.5


PLANCKIAN_COEFFS = {
"blackbody": {
3_000: [0.6743, 0.4029, 0.0013],
3_500: [0.6281, 0.4241, 0.1665],
4_000: [0.5919, 0.4372, 0.2513],
4_500: [0.5623, 0.4457, 0.3154],
5_000: [0.5376, 0.4515, 0.3672],
5_500: [0.5163, 0.4555, 0.4103],
6_000: [0.4979, 0.4584, 0.4468],
6_500: [0.4816, 0.4604, 0.4782],
7_000: [0.4672, 0.4619, 0.5053],
7_500: [0.4542, 0.4630, 0.5289],
8_000: [0.4426, 0.4638, 0.5497],
8_500: [0.4320, 0.4644, 0.5681],
9_000: [0.4223, 0.4648, 0.5844],
9_500: [0.4135, 0.4651, 0.5990],
10_000: [0.4054, 0.4653, 0.6121],
10_500: [0.3980, 0.4654, 0.6239],
11_000: [0.3911, 0.4655, 0.6346],
11_500: [0.3847, 0.4656, 0.6444],
12_000: [0.3787, 0.4656, 0.6532],
12_500: [0.3732, 0.4656, 0.6613],
13_000: [0.3680, 0.4655, 0.6688],
13_500: [0.3632, 0.4655, 0.6756],
14_000: [0.3586, 0.4655, 0.6820],
14_500: [0.3544, 0.4654, 0.6878],
15_000: [0.3503, 0.4653, 0.6933],
},
"cied": {
4_000: [0.5829, 0.4421, 0.2288],
4_500: [0.5510, 0.4514, 0.2948],
5_000: [0.5246, 0.4576, 0.3488],
5_500: [0.5021, 0.4618, 0.3941],
6_000: [0.4826, 0.4646, 0.4325],
6_500: [0.4654, 0.4667, 0.4654],
7_000: [0.4502, 0.4681, 0.4938],
7_500: [0.4364, 0.4692, 0.5186],
8_000: [0.4240, 0.4700, 0.5403],
8_500: [0.4127, 0.4705, 0.5594],
9_000: [0.4023, 0.4709, 0.5763],
9_500: [0.3928, 0.4713, 0.5914],
10_000: [0.3839, 0.4715, 0.6049],
10_500: [0.3757, 0.4716, 0.6171],
11_000: [0.3681, 0.4717, 0.6281],
11_500: [0.3609, 0.4718, 0.6380],
12_000: [0.3543, 0.4719, 0.6472],
12_500: [0.3480, 0.4719, 0.6555],
13_000: [0.3421, 0.4719, 0.6631],
13_500: [0.3365, 0.4719, 0.6702],
14_000: [0.3313, 0.4719, 0.6766],
14_500: [0.3263, 0.4719, 0.6826],
15_000: [0.3217, 0.4719, 0.6882],
},
}


@clipped
def planckian_jitter(img: np.ndarray, temperature: int, mode: PlanckianJitterMode = "blackbody") -> np.ndarray:
img = img.copy()
# Linearly interpolate between 2 closest temperatures
step = 500
t_left = (temperature // step) * step
t_right = (temperature // step + 1) * step

w_left = (t_right - temperature) / step
w_right = (temperature - t_left) / step

coeffs = w_left * np.array(PLANCKIAN_COEFFS[mode][t_left]) + w_right * np.array(PLANCKIAN_COEFFS[mode][t_right])

image = img / 255.0 if img.dtype == np.uint8 else img

image[:, :, 0] = image[:, :, 0] * (coeffs[0] / coeffs[1])
image[:, :, 2] = image[:, :, 2] * (coeffs[2] / coeffs[1])
image[image > 1] = 1

if img.dtype == np.uint8:
return image * 255.0

return image


def generate_approx_gaussian_noise(
shape: SizeType,
mean: float = 0,
Expand Down
Loading

0 comments on commit 834268b

Please sign in to comment.