@ -16,17 +16,20 @@ import numpy as np
from PIL import Image
from cStringIO import StringIO
def resize_image ( img , target_size ) :
"""
Resize an image so that the shorter edge has length target_size .
img : the input image to be resized .
target_size : the target resized image size .
"""
percent = ( target_size / float ( min ( img . size [ 0 ] , img . size [ 1 ] ) ) )
resized_size = int ( round ( img . size [ 0 ] * percent ) ) , int ( round ( img . size [ 1 ] * percent ) )
percent = ( target_size / float ( min ( img . size [ 0 ] , img . size [ 1 ] ) ) )
resized_size = int ( round ( img . size [ 0 ] * percent ) ) , int (
round ( img . size [ 1 ] * percent ) )
img = img . resize ( resized_size , Image . ANTIALIAS )
return img
def flip ( im ) :
"""
Return the flipped image .
@ -38,6 +41,7 @@ def flip(im):
else :
return im [ : , : : - 1 ]
def crop_img ( im , inner_size , color = True , test = True ) :
"""
Return cropped image .
@ -50,20 +54,22 @@ def crop_img(im, inner_size, color=True, test=True):
If True , crop the center of images .
"""
if color :
height , width = max ( inner_size , im . shape [ 1 ] ) , max ( inner_size , im . shape [ 2 ] )
height , width = max ( inner_size , im . shape [ 1 ] ) , max ( inner_size ,
im . shape [ 2 ] )
padded_im = np . zeros ( ( 3 , height , width ) )
startY = ( height - im . shape [ 1 ] ) / 2
startX = ( width - im . shape [ 2 ] ) / 2
endY , endX = startY + im . shape [ 1 ] , startX + im . shape [ 2 ]
padded_im [ : , startY : endY , startX : endX ] = im
padded_im [ : , startY : endY , startX : endX ] = im
else :
im = im . astype ( ' float32 ' )
height , width = max ( inner_size , im . shape [ 0 ] ) , max ( inner_size , im . shape [ 1 ] )
height , width = max ( inner_size , im . shape [ 0 ] ) , max ( inner_size ,
im . shape [ 1 ] )
padded_im = np . zeros ( ( height , width ) )
startY = ( height - im . shape [ 0 ] ) / 2
startX = ( width - im . shape [ 1 ] ) / 2
endY , endX = startY + im . shape [ 0 ] , startX + im . shape [ 1 ]
padded_im [ startY : endY , startX : endX ] = im
padded_im [ startY : endY , startX : endX ] = im
if test :
startY = ( height - inner_size ) / 2
startX = ( width - inner_size ) / 2
@ -72,19 +78,21 @@ def crop_img(im, inner_size, color=True, test=True):
startX = np . random . randint ( 0 , width - inner_size + 1 )
endY , endX = startY + inner_size , startX + inner_size
if color :
pic = padded_im [ : , startY : endY , startX : endX ]
pic = padded_im [ : , startY : endY , startX : endX ]
else :
pic = padded_im [ startY : endY , startX : endX ]
pic = padded_im [ startY : endY , startX : endX ]
if ( not test ) and ( np . random . randint ( 2 ) == 0 ) :
pic = flip ( pic )
return pic
def decode_jpeg ( jpeg_string ) :
np_array = np . array ( Image . open ( StringIO ( jpeg_string ) ) )
if len ( np_array . shape ) == 3 :
np_array = np . transpose ( np_array , ( 2 , 0 , 1 ) )
return np_array
def preprocess_img ( im , img_mean , crop_size , is_train , color = True ) :
"""
Does data augmentation for images .
@ -99,6 +107,7 @@ def preprocess_img(im, img_mean, crop_size, is_train, color=True):
pic - = img_mean
return pic . flatten ( )
def load_meta ( meta_path , mean_img_size , crop_size , color = True ) :
"""
Return the loaded meta file .
@ -109,17 +118,18 @@ def load_meta(meta_path, mean_img_size, crop_size, color=True):
mean = np . load ( meta_path ) [ ' data_mean ' ]
border = ( mean_img_size - crop_size ) / 2
if color :
assert ( mean_img_size * mean_img_size * 3 == mean . shape [ 0 ] )
assert ( mean_img_size * mean_img_size * 3 == mean . shape [ 0 ] )
mean = mean . reshape ( 3 , mean_img_size , mean_img_size )
mean = mean [ : , border : border + crop_size ,
border : border + crop_size ] . astype ( ' float32 ' )
mean = mean [ : , border : border + crop_size , border : border +
crop_size ] . astype ( ' float32 ' )
else :
assert ( mean_img_size * mean_img_size == mean . shape [ 0 ] )
assert ( mean_img_size * mean_img_size == mean . shape [ 0 ] )
mean = mean . reshape ( mean_img_size , mean_img_size )
mean = mean [ border : border + crop_size ,
border: border + crop_size] . astype ( ' float32 ' )
mean = mean [ border : border + crop_size , border : border +
crop_size] . astype ( ' float32 ' )
return mean
def load_image ( img_path , is_color = True ) :
"""
Load image and return .
@ -130,6 +140,7 @@ def load_image(img_path, is_color=True):
img . load ( )
return img
def oversample ( img , crop_dims ) :
"""
image : iterable of ( H x W x K ) ndarrays
@ -152,50 +163,53 @@ def oversample(img, crop_dims):
for j in w_indices :
crops_ix [ curr ] = ( i , j , i + crop_dims [ 0 ] , j + crop_dims [ 1 ] )
curr + = 1
crops_ix [ 4 ] = np . tile ( im_center , ( 1 , 2 ) ) + np . concatenate ( [
- crop_dims / 2.0 ,
crop_dims / 2.0
] )
crops_ix [ 4 ] = np . tile ( im_center , ( 1 , 2 ) ) + np . concatenate (
[ - crop_dims / 2.0 , crop_dims / 2.0 ] )
crops_ix = np . tile ( crops_ix , ( 2 , 1 ) )
# Extract crops
crops = np . empty ( ( 10 * len ( img ) , crop_dims [ 0 ] , crop_dims [ 1 ] ,
im_shape [ - 1 ] ) , dtype = np . float32 )
crops = np . empty (
( 10 * len ( img ) , crop_dims [ 0 ] , crop_dims [ 1 ] , im_shape [ - 1 ] ) ,
dtype = np . float32 )
ix = 0
for im in img :
for crop in crops_ix :
crops [ ix ] = im [ crop [ 0 ] : crop [ 2 ] , crop [ 1 ] : crop [ 3 ] , : ]
ix + = 1
crops [ ix - 5 : ix ] = crops [ ix - 5 : ix , : , : : - 1 , : ] # flip for mirrors
crops [ ix - 5 : ix ] = crops [ ix - 5 : ix , : , : : - 1 , : ] # flip for mirrors
return crops
class ImageTransformer :
def __init__ ( self , transpose = None ,
channel_swap = None , mean = None , is_color = True ) :
def __init__ ( self ,
transpose = None ,
channel_swap = None ,
mean = None ,
is_color = True ) :
self . transpose = transpose
self . channel_swap = None
self . mean = None
self . is_color = is_color
self . is_color = is_color
def set_transpose ( self , order ) :
def set_transpose ( self , order ) :
if self . is_color :
assert 3 == len ( order )
assert 3 == len ( order )
self . transpose = order
def set_channel_swap ( self , order ) :
def set_channel_swap ( self , order ) :
if self . is_color :
assert 3 == len ( order )
assert 3 == len ( order )
self . channel_swap = order
def set_mean ( self , mean ) :
# mean value, may be one value per channel
if mean . ndim == 1 :
mean = mean [ : , np . newaxis , np . newaxis ]
else :
mean = mean [ : , np . newaxis , np . newaxis ]
else :
# elementwise mean
if self . is_color :
assert len ( mean . shape ) == 3
self . mean = mean
self . mean = mean
def transformer ( self , data ) :
if self . transpose is not None :