15
15
16
16
"""Common corruptions to images.
17
17
18
- Define 12 +4 common image corruptions: Gaussian noise, shot noise, impulse_noise,
18
+ Define 15 +4 common image corruptions: Gaussian noise, shot noise, impulse_noise,
19
19
defocus blur, frosted glass blur, zoom blur, fog, brightness, contrast, elastic,
20
- pixelate, jpeg compression.
20
+ pixelate, jpeg compression, frost, snow, and motion blur .
21
21
22
- 4 extra corruptions include gaussian blur, saturate, spatter, and speckle
23
- noise.
22
+ 4 extra corruptions: gaussian blur, saturate, spatter, and speckle noise.
24
23
"""
25
24
26
25
from __future__ import absolute_import
27
26
from __future__ import division
28
27
from __future__ import print_function
29
28
30
29
import io
30
+ import subprocess
31
+ import tempfile
31
32
import numpy as np
33
+ import tensorflow .compat .v2 as tf
32
34
import tensorflow_datasets .public_api as tfds
33
35
36
+
37
+ # To be populated by download_manager
38
+ FROST_FILENAMES = []
39
+
40
+
41
+ def _imagemagick_bin ():
42
+ return 'imagemagick' # pylint: disable=unreachable
43
+
44
+
34
45
# /////////////// Corruption Helpers ///////////////
35
46
36
47
@@ -239,7 +250,7 @@ def defocus_blur(x, severity=1):
239
250
return around_and_astype (x_clip )
240
251
241
252
242
- def frosted_glass_blur (x , severity = 1 ):
253
+ def glass_blur (x , severity = 1 ):
243
254
"""Frosted glass blurring to images.
244
255
245
256
Apply frosted glass blurring to images by shuffling pixels locally.
@@ -367,7 +378,7 @@ def contrast(x, severity=1):
367
378
return around_and_astype (x_clip )
368
379
369
380
370
- def elastic (x , severity = 1 ):
381
+ def elastic_transform (x , severity = 1 ):
371
382
"""Conduct elastic transform to images.
372
383
373
384
Elastic transform is performed on small patches of the images.
@@ -469,6 +480,131 @@ def jpeg_compression(x, severity=1):
469
480
return np .asarray (x )
470
481
471
482
483
+ def frost (x , severity = 1 ):
484
+ """Apply frost to images.
485
+
486
+ Args:
487
+ x: numpy array, uncorrupted image, assumed to have uint8 pixel in [0,255].
488
+ severity: integer, severity of corruption.
489
+
490
+ Returns:
491
+ numpy array, image with uint8 pixels in [0,255]. Applied frost.
492
+ """
493
+ c = [(1 , 0.4 ), (0.8 , 0.6 ), (0.7 , 0.7 ), (0.65 , 0.7 ), (0.6 , 0.75 )][severity - 1 ]
494
+ filename = FROST_FILENAMES [np .random .randint (5 )]
495
+ with tempfile .NamedTemporaryFile () as im_frost :
496
+ tf .io .gfile .copy (filename , im_frost .name , overwrite = True )
497
+ frost_img = tfds .core .lazy_imports .cv2 .imread (im_frost .name )
498
+ # randomly crop and convert to rgb
499
+ x_start , y_start = np .random .randint (
500
+ 0 , frost_img .shape [0 ] - 224 ), np .random .randint (0 ,
501
+ frost_img .shape [1 ] - 224 )
502
+ frost_img = frost_img [x_start :x_start + 224 , y_start :y_start + 224 ][...,
503
+ [2 , 1 , 0 ]]
504
+
505
+ x = np .clip (c [0 ] * np .array (x ) + c [1 ] * frost_img , 0 , 255 )
506
+
507
+ return around_and_astype (x )
508
+
509
+
510
+ def snow (x , severity = 1 ):
511
+ """Apply snow to images.
512
+
513
+ Args:
514
+ x: numpy array, uncorrupted image, assumed to have uint8 pixel in [0,255].
515
+ severity: integer, severity of corruption.
516
+
517
+ Returns:
518
+ numpy array, image with uint8 pixels in [0,255]. Applied snow.
519
+ """
520
+ cv2 = tfds .core .lazy_imports .cv2
521
+ PIL_Image = tfds .core .lazy_imports .PIL_Image # pylint: disable=invalid-name
522
+ c = [(0.1 , 0.3 , 3 , 0.5 , 10 , 4 , 0.8 ), (0.2 , 0.3 , 2 , 0.5 , 12 , 4 , 0.7 ),
523
+ (0.55 , 0.3 , 4 , 0.9 , 12 , 8 , 0.7 ), (0.55 , 0.3 , 4.5 , 0.85 , 12 , 8 , 0.65 ),
524
+ (0.55 , 0.3 , 2.5 , 0.85 , 12 , 12 , 0.55 )][severity - 1 ]
525
+
526
+ x = np .array (x , dtype = np .float32 ) / 255.
527
+ snow_layer = np .random .normal (
528
+ size = x .shape [:2 ], loc = c [0 ], scale = c [1 ]) # [:2] for monochrome
529
+
530
+ snow_layer = clipped_zoom (snow_layer [..., np .newaxis ], c [2 ])
531
+ snow_layer [snow_layer < c [3 ]] = 0
532
+
533
+ snow_layer = PIL_Image .fromarray (
534
+ (np .clip (snow_layer .squeeze (), 0 , 1 ) * 255 ).astype (np .uint8 ), mode = 'L' )
535
+
536
+ with tempfile .NamedTemporaryFile () as im_input :
537
+ with tempfile .NamedTemporaryFile () as im_output :
538
+ snow_layer .save (im_input .name , format = 'PNG' )
539
+
540
+ convert_bin = _imagemagick_bin ()
541
+ radius = c [4 ]
542
+ sigma = c [5 ]
543
+ angle = np .random .uniform (- 135 , - 45 )
544
+
545
+ subprocess .check_output ([
546
+ convert_bin , '-motion-blur' , '{}x{}+{}' .format (radius , sigma , angle ),
547
+ im_input .name , im_output .name
548
+ ])
549
+
550
+ with open (im_output .name , 'rb' ) as f :
551
+ output = f .read ()
552
+
553
+ snow_layer = cv2 .imdecode (
554
+ np .fromstring (output , np .uint8 ), cv2 .IMREAD_UNCHANGED ) / 255.
555
+ snow_layer = snow_layer [..., np .newaxis ]
556
+
557
+ x = c [6 ] * x + (1 - c [6 ]) * np .maximum (
558
+ x ,
559
+ cv2 .cvtColor (x , cv2 .COLOR_RGB2GRAY ).reshape (224 , 224 , 1 ) * 1.5 + 0.5 )
560
+ x = np .clip (x + snow_layer + np .rot90 (snow_layer , k = 2 ), 0 , 1 ) * 255
561
+
562
+ return around_and_astype (x )
563
+
564
+
565
+ def motion_blur (x , severity = 1 ):
566
+ """Apply motion blur to images.
567
+
568
+ Args:
569
+ x: numpy array, uncorrupted image, assumed to have uint8 pixel in [0,255].
570
+ severity: integer, severity of corruption.
571
+
572
+ Returns:
573
+ numpy array, image with uint8 pixels in [0,255]. Applied motion blur.
574
+ """
575
+ c = [(10 , 3 ), (15 , 5 ), (15 , 8 ), (15 , 12 ), (20 , 15 )][severity - 1 ]
576
+
577
+ x = tfds .core .lazy_imports .PIL_Image .fromarray (x .astype (np .uint8 ))
578
+
579
+ with tempfile .NamedTemporaryFile () as im_input :
580
+ with tempfile .NamedTemporaryFile () as im_output :
581
+ x .save (im_input .name , format = 'PNG' )
582
+
583
+ convert_bin = _imagemagick_bin ()
584
+ radius = c [0 ]
585
+ sigma = c [1 ]
586
+ angle = np .random .uniform (- 45 , - 45 )
587
+
588
+ subprocess .check_output ([
589
+ convert_bin , '-motion-blur' , '{}x{}+{}' .format (radius , sigma , angle ),
590
+ im_input .name , im_output .name
591
+ ])
592
+
593
+ with open (im_output .name , 'rb' ) as f :
594
+ output = f .read ()
595
+
596
+ x = tfds .core .lazy_imports .cv2 .imdecode (
597
+ np .fromstring (output , np .uint8 ),
598
+ tfds .core .lazy_imports .cv2 .IMREAD_UNCHANGED )
599
+
600
+ if x .shape != (224 , 224 ):
601
+ x = np .clip (x [..., [2 , 1 , 0 ]], 0 , 255 ) # BGR to RGB
602
+ else : # greyscale to RGB
603
+ x = np .clip (np .array ([x , x , x ]).transpose ((1 , 2 , 0 )), 0 , 255 )
604
+
605
+ return around_and_astype (x )
606
+
607
+
472
608
# /////////////// Extra Corruptions ///////////////
473
609
474
610
@@ -484,7 +620,7 @@ def gaussian_blur(x, severity=1):
484
620
"""
485
621
c = [1 , 2 , 3 , 4 , 6 ][severity - 1 ]
486
622
487
- x = tfds .core .lazy_imports .gaussian (
623
+ x = tfds .core .lazy_imports .skimage . filters . gaussian (
488
624
np .array (x ) / 255. , sigma = c , multichannel = True )
489
625
x = np .clip (x , 0 , 1 ) * 255
490
626
@@ -543,7 +679,7 @@ def spatter(x, severity=1):
543
679
# ker = np.array([[-1,-2,-3],[-2,0,0],[-3,0,1]], dtype=np.float32)
544
680
# ker -= np.mean(ker)
545
681
ker = np .array ([[- 2 , - 1 , 0 ], [- 1 , 1 , 1 ], [0 , 1 , 2 ]])
546
- dist = cv2 .filter2D (dist , cv2 .CV_8U , ker )
682
+ dist = cv2 .filter2D (dist , cv2 .CVX_8U , ker )
547
683
dist = cv2 .blur (dist , (3 , 3 )).astype (np .float32 )
548
684
549
685
m = cv2 .cvtColor (liquid_layer * dist , cv2 .COLOR_GRAY2BGRA )
0 commit comments