singa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wang...@apache.org
Subject [5/6] incubator-singa git commit: SINGA-246 Imgtool for image augmentation
Date Thu, 15 Sep 2016 14:10:14 GMT
SINGA-246 Imgtool for image augmentation

Rename some variables and functions.


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/87320214
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/87320214
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/87320214

Branch: refs/heads/master
Commit: 873202146c67d494cc3f3c3f19038c4b79f59801
Parents: f4fae37
Author: Wei Wang <wangwei@comp.nus.edu.sg>
Authored: Thu Sep 15 21:48:35 2016 +0800
Committer: Wei Wang <wangwei@comp.nus.edu.sg>
Committed: Thu Sep 15 21:48:35 2016 +0800

----------------------------------------------------------------------
 python/singa/image_tool.py | 490 ++++++++++++++++++++++++++++++++++++++++
 python/singa/imgtool.py    | 462 -------------------------------------
 2 files changed, 490 insertions(+), 462 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/87320214/python/singa/image_tool.py
----------------------------------------------------------------------
diff --git a/python/singa/image_tool.py b/python/singa/image_tool.py
new file mode 100644
index 0000000..b03174d
--- /dev/null
+++ b/python/singa/image_tool.py
@@ -0,0 +1,490 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# =============================================================================
+
+import random
+import numpy as np
+from PIL import Image, ImageEnhance
+
+
+def load_img(path, grayscale=False):
+    '''Read the image from a give path'''
+    img = Image.open(path)
+    if grayscale:
+        img = img.convert('L')
+    else:  # Ensure 3 channel even when loaded image is grayscale
+        img = img.convert('RGB')
+    return img
+
+
+def crop(img, patch, position):
+    '''Crop the input image into given size at given position.
+
+    Args:
+        patch(tuple): width and height of the patch
+        position(list(str)): left_top, left_bottom, right_top, right_bottom
+        and center.
+    '''
+    if img.size[0] < patch[0]:
+        raise Exception(
+            'img size[0] %d is smaller than patch[0]: %d' % (img[0], patch[0]))
+    if img.size[1] < patch[1]:
+        raise Exception(
+            'img size[1] %d is smaller than patch[1]: %d' % (img[1], patch[1]))
+
+    if position == 'left_top':
+        left, upper = 0, 0
+    elif position == 'left_bottom':
+        left, upper = 0, img.size[1]-patch[1]
+    elif position == 'right_top':
+        left, upper = img.size[0]-patch[0], 0
+    elif position == 'right_bottom':
+        left, upper = img.size[0]-patch[0], img.size[1]-patch[1]
+    elif position == 'center':
+        left, upper = (img.size[0]-patch[0])/2, (img.size[1]-patch[1])/2
+    else:
+        raise Exception('position is wrong')
+
+    box = (left, upper, left+patch[0], upper+patch[1])
+    new_img = img.crop(box)
+    # print "crop to box %d,%d,%d,%d" % box
+    return new_img
+
+
+def crop_and_resize(img, patch, position):
+    '''Crop a max square patch of the input image at given position and resize
+    it into given size.
+
+    Args:
+        patch(tuple): width, height
+        position(list(str)): left, center, right, top, middle, bottom.
+    '''
+    size = img.size
+    if position == 'left':
+        left, upper = 0, 0
+        right, bottom = size[1], size[1]
+    elif position == 'center':
+        left, upper = (size[0]-size[1])/2, 0
+        right, bottom = (size[0]+size[1])/2, size[1]
+    elif position == 'right':
+        left, upper = size[0]-size[1], 0
+        right, bottom = size[0], size[1]
+    elif position == 'top':
+        left, upper = 0, 0
+        right, bottom = size[0], size[0]
+    elif position == 'middle':
+        left, upper = 0, (size[1]-size[0])/2
+        right, bottom = size[0], (size[1]+size[0])/2
+    elif position == 'bottom':
+        left, upper = 0, size[1]-size[0]
+        right, bottom = size[0], size[1]
+    else:
+        raise Exception('position is wrong')
+    box = (left, upper, right, bottom)
+    new_img = img.crop(box)
+
+    new_img = img.resize(patch)
+    # print box+crop
+    # print "crop to box %d,%d,%d,%d and scale to %d,%d" % (box+crop)
+    return new_img
+
+
+def resize(img, small_size):
+    '''Resize the image to make the smaller side be at the given size'''
+    size = img.size
+    if size[0] < size[1]:
+        new_size = (small_size, int(small_size*size[1]/size[0]))
+    else:
+        new_size = (int(small_size*size[0]/size[1]), small_size)
+    new_img = img.resize(new_size)
+    # print 'resize to (%d,%d)' % new_size
+    return new_img
+
+
+def color_cast(img, offset):
+    '''Add a random value from [-offset, offset] to each channel'''
+    x = np.asarray(img, dtype='uint8')
+    x.flags.writeable = True
+    cast_value = [0, 0, 0]
+    for i in range(3):
+        r = random.randint(0, 1)
+        if r:
+            cast_value[i] = random.randint(-offset, offset)
+    for w in range(x.shape[0]):
+        for h in range(x.shape[1]):
+            for c in range(3):
+                if cast_value[c] == 0:
+                    continue
+                v = x[w][h][c]+cast_value[c]
+                if v < 0:
+                    v = 0
+                if v > 255:
+                    v = 255
+                x[w][h][c] = v
+    new_img = Image.fromarray(x.astype('uint8'), 'RGB')
+    return new_img
+
+
+def enhance(img, scale):
+    '''Apply random enhancement for Color,Contrast,Brightness,Sharpness.
+
+    Args:
+        scale(float): enhancement degree is from [1-scale, 1+scale]
+    '''
+    enhance_value = [1.0, 1.0, 1.0, 1.0]
+    for i in range(4):
+        r = random.randint(0, 1)
+        if r:
+            enhance_value[i] = random.uniform(1-scale, 1+scale)
+    if not enhance_value[0] == 1.0:
+        enhancer = ImageEnhance.Color(img)
+        img = enhancer.enhance(enhance_value[0])
+    if not enhance_value[1] == 1.0:
+        enhancer = ImageEnhance.Contrast(img)
+        img = enhancer.enhance(enhance_value[1])
+    if not enhance_value[2] == 1.0:
+        enhancer = ImageEnhance.Brightness(img)
+        img = enhancer.enhance(enhance_value[2])
+    if not enhance_value[3] == 1.0:
+        enhancer = ImageEnhance.Sharpness(img)
+        img = enhancer.enhance(enhance_value[3])
+    return img
+
+
+def flip(img):
+    # print 'flip'
+    new_img = img.transpose(Image.FLIP_LEFT_RIGHT)
+    return new_img
+
+
+def get_list_sample(l, sample_size):
+    return [l[i] for i in sorted(random.sample(xrange(len(l)), sample_size))]
+
+
+class ImageTool():
+    '''A tool for image augmentation.
+
+    For operations with inplace=True, the returned value is the ImageTool
+    instance self, which is for chaining multiple operations; Otherwise, the
+    preprocessed images would be returned.
+
+    For operations that has countable pre-processing cases, argument num_case
+    could be set to decide the number of pre-processing cases to apply.
+    Typically, it is set to 1 for training phases and to the max for test
+    phases.
+    '''
+
+    def __init__(self):
+        self.imgs = []
+        return
+
+    def load(self, path):
+        img = load_img(path)
+        self.imgs = [img]
+        return self
+
+    def set(self, imgs):
+        self.imgs = imgs
+        return self
+
+    def append(self, img):
+        self.imgs.append(img)
+        return self
+
+    def get(self):
+        return self.imgs
+
+    def resize_by_range(self, rng, inplace=True):
+        '''
+        Args:
+            rng: a tuple (begin,end), include begin, exclude end
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        size_list = range(rng[0], rng[1])
+        return self.resize_by_list(size_list, 1, inplace)
+
+    def resize_by_list(self, size_list, num_case=1, inplace=True):
+        '''
+        Args:
+            num_case: num of resize cases, must be <= the length of size_list
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        new_imgs = []
+        if num_case < 1 or num_case > len(size_list):
+            raise Exception(
+                'num_case must be smaller in [0,%d(length of size_list)]' %
+                len(size_list))
+        for img in self.imgs:
+            if num_case == len(size_list):
+                small_sizes = size_list
+            else:
+                small_sizes = get_list_sample(size_list, num_case)
+
+            for small_size in small_sizes:
+                new_img = resize(img, small_size)
+                new_imgs.append(new_img)
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def resize_for_test(self, rng):
+        '''
+        Args:
+            rng: a tuple (begin,end)
+        '''
+        size_list = [rng[0], rng[0]/2+rng[1]/2, rng[1]]
+        return self.resize_by_list(size_list, num_case=3)
+
+    def rotate_by_range(self, rng, inplace=True):
+        '''
+        Args:
+            rng: a tuple (begin,end) in degree, include begin, exclude end
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        angle_list = range(rng[0], rng[1])
+        return self.rotate_by_list(angle_list, 1, inplace)
+
+    def rotate_by_list(self, angle_list, num_case=1, inplace=True):
+        '''
+        Args:
+            num_case: num of rotate cases, must be <= the length of angle_list
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        new_imgs = []
+        if num_case < 1 or num_case > len(angle_list):
+            raise Exception(
+                'num_case must be smaller in [1,%d(length of angle_list)]' %
+                len(angle_list))
+
+        for img in self.imgs:
+            if num_case == len(angle_list):
+                angles = angle_list
+            else:
+                angles = get_list_sample(angle_list, num_case)
+
+            for angle in angles:
+                new_img = img.rotate(angle)
+                new_imgs.append(new_img)
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def crop5(self, patch, num_case=1, inplace=True):
+        '''Crop at positions from [left_top, left_bottom, right_top,
+        right_bottom, and center].
+
+        Args:
+            patch(tuple): width and height of the result image.
+            num_case: num of cases, must be in [1,5]
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        new_imgs = []
+        positions = [
+            "left_top",
+            "left_bottom",
+            "right_top",
+            "right_bottom",
+            "center"]
+        if num_case > 5 or num_case < 1:
+            raise Exception('num_case must be in [1,5]')
+        for img in self.imgs:
+
+            if num_case > 0 and num_case < 5:
+                positions = get_list_sample(positions, num_case)
+
+            for position in positions:
+                new_img = crop(img, patch, position)
+                new_imgs.append(new_img)
+
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def crop3(self, patch, num_case=1, inplace=True):
+        '''Crop a max square patch of the input image at given position and
+        scale it into given size.
+
+        According to img size, crop position could be either
+        (left, center, right) or (top, middle, bottom).
+
+        Args:
+            patch(tuple): the width and height the output image
+            num_case: num of cases, must be in [1,3]
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        if not patch[0] == patch[1]:
+            raise Exception('patch must be a square')
+        new_imgs = []
+        if num_case > 3 or num_case < 1:
+            raise Exception('num_case must be in [1,3]')
+        positions_horizental = ["left", "center", "right"]
+        positions_vertical = ["top", "middle", "bottom"]
+        for img in self.imgs:
+            size = img.size
+            if size[0] > size[1]:
+                if num_case > 0 and num_case < 3:
+                    positions = get_list_sample(positions_horizental, num_case)
+                else:
+                    positions = positions_horizental
+            else:
+                if num_case > 0 and num_case < 3:
+                    positions = get_list_sample(positions_vertical, num_case)
+                else:
+                    positions = positions_vertical
+
+            for position in positions:
+                new_img = crop_and_resize(img, patch, position)
+                new_imgs.append(new_img)
+
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def crop8(self, patch, num_case=1, inplace=True):
+        '''This is a union of patch_5 and patch_and_scale.
+
+        You can follow this example to union any num of cases of imgtool methods
+        '''
+        patch5 = 5
+        patch3 = 3
+        if num_case < 1 or num_case > patch5 + patch3:
+            raise Exception(
+                'num_case must be in [0,%d]' % (patch5+patch3))
+        if num_case == patch5 + patch3:
+            count = patch5
+        else:
+            sample_list = range(0, patch5 + patch3)
+            samples = get_list_sample(sample_list, num_case)
+            count = 0
+            for s in samples:
+                if s < patch5:
+                    count += 1
+        new_imgs = []
+        if count > 0:
+            new_imgs += self.crop5(patch, count, False)
+        if num_case-count > 0:
+            new_imgs += self.crop3(patch, num_case-count, False)
+
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def random_crop(self, patch, inplace=True):
+        '''Crop the image at random offset to get a patch of the given size.
+
+        Args:
+            patch(tuple): width and height of the patch
+            inplace(Boolean): replace the internal images list with the patches
+                              if True; otherwise, return the patches.
+        '''
+        new_imgs = []
+        for img in self.imgs:
+            assert img.size[0] >= patch[0] and img.size[1] >= patch[1],\
+                'img size (%d, %d), patch size (%d, %d)' % \
+                (img.size[0], img.size[1], patch[0], patch[1])
+            left_offset = random.randint(0, img.size[0] - patch[0])
+            top_offset = random.randint(0, img.size[1] - patch[1])
+            box = (left_offset, top_offset,
+                   left_offset + patch[0], top_offset + patch[1])
+            new_imgs.append(img.crop(box))
+
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def flip(self, num_case=1, inplace=True):
+        '''Randomly flip a img left to right.
+
+        Args:
+            num_case: num of cases, must be in {1,2}; if 2, then add the orignal
+                      and flipped img
+            inplace: inplace imgs or not (return new_imgs)
+        '''
+        new_imgs = []
+        for img in self.imgs:
+            if num_case == 1:
+                if random.randint(0, 1):
+                    new_imgs.append(flip(img))
+                else:
+                    new_imgs.append(img)
+            elif num_case == 2:
+                new_imgs.append(flip(img))
+                new_imgs.append(img)
+            else:
+                raise Exception('num_case must be in [0,2]')
+
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def color_cast(self, offset=20, inplace=True):
+        '''Add a random value from [-offset, offset] to each channel
+
+        Args:
+            offset: cast offset, >0 and <255
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        new_imgs = []
+        if offset < 0 or offset > 255:
+            raise Exception('offset must be >0 and <255')
+
+        for img in self.imgs:
+            new_img = color_cast(img, offset)
+            new_imgs.append(new_img)
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+    def enhance(self, scale=0.2, inplace=True):
+        '''Apply random enhancement for Color,Contrast,Brightness,Sharpness.
+
+        Args:
+            scale(float): enhancement degree is from [1-scale, 1+scale]
+            inplace: inplace imgs or not ( return new_imgs)
+        '''
+        new_imgs = []
+        for img in self.imgs:
+            new_img = enhance(img, scale)
+            new_imgs.append(new_img)
+        if inplace:
+            self.imgs = new_imgs
+            return self
+        else:
+            return new_imgs
+
+
+if __name__ == '__main__':
+    tool = ImageTool()
+    imgs = tool.load('input.png').\
+        resize_by_list([112]).crop5((96, 96), 5).enhance().flip().get()
+    for idx, img in enumerate(imgs):
+        img.save('%d.png' % idx)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/87320214/python/singa/imgtool.py
----------------------------------------------------------------------
diff --git a/python/singa/imgtool.py b/python/singa/imgtool.py
deleted file mode 100644
index 021a060..0000000
--- a/python/singa/imgtool.py
+++ /dev/null
@@ -1,462 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# =============================================================================
-
-import random
-import numpy as np
-from PIL import Image, ImageEnhance
-
-
-def load_img(path, grayscale=False):
-    '''Read the image from a give path'''
-    img = Image.open(path)
-    if grayscale:
-        img = img.convert('L')
-    else:  # Ensure 3 channel even when loaded image is grayscale
-        img = img.convert('RGB')
-    return img
-
-
-def do_crop(img, crop, position):
-    '''Crop the input image into given size at given position.
-
-    Args:
-        crop(tuple): width and height of the result image.
-        position(list(str)): left_top, left_bottom, right_top, right_bottom
-        and center.
-    '''
-    if img.size[0] < crop[0]:
-        raise Exception(
-            'img size[0] %d is smaller than crop[0]: %d' % (img[0], crop[0]))
-    if img.size[1] < crop[1]:
-        raise Exception(
-            'img size[1] %d is smaller than crop[1]: %d' % (img[1], crop[1]))
-
-    if position == 'left_top':
-        left, upper = 0, 0
-    elif position == 'left_bottom':
-        left, upper = 0, img.size[1]-crop[1]
-    elif position == 'right_top':
-        left, upper = img.size[0]-crop[0], 0
-    elif position == 'right_bottom':
-        left, upper = img.size[0]-crop[0], img.size[1]-crop[1]
-    elif position == 'center':
-        left, upper = (img.size[0]-crop[0])/2, (img.size[1]-crop[1])/2
-    else:
-        raise Exception('position is wrong')
-
-    box = (left, upper, left+crop[0], upper+crop[1])
-    new_img = img.crop(box)
-    # print "crop to box %d,%d,%d,%d" % box
-    return new_img
-
-
-def do_crop_and_scale(img, crop, position):
-    '''Crop a max square patch of the input image at given position and scale
-    it into given size.
-
-    Args:
-        crop(tuple): width, height
-        position(list(str)): left, center, right, top, middle, bottom.
-    '''
-    size = img.size
-    if position == 'left':
-        left, upper = 0, 0
-        right, bottom = size[1], size[1]
-    elif position == 'center':
-        left, upper = (size[0]-size[1])/2, 0
-        right, bottom = (size[0]+size[1])/2, size[1]
-    elif position == 'right':
-        left, upper = size[0]-size[1], 0
-        right, bottom = size[0], size[1]
-    elif position == 'top':
-        left, upper = 0, 0
-        right, bottom = size[0], size[0]
-    elif position == 'middle':
-        left, upper = 0, (size[1]-size[0])/2
-        right, bottom = size[0], (size[1]+size[0])/2
-    elif position == 'bottom':
-        left, upper = 0, size[1]-size[0]
-        right, bottom = size[0], size[1]
-    else:
-        raise Exception('position is wrong')
-    box = (left, upper, right, bottom)
-    new_img = img.crop(box)
-
-    new_img = img.resize(crop)
-    # print box+crop
-    # print "crop to box %d,%d,%d,%d and scale to %d,%d" % (box+crop)
-    return new_img
-
-
-def do_resize(img, small_size):
-    '''Resize the image to make the smaller side be at the given size'''
-    size = img.size
-    if size[0] < size[1]:
-        new_size = (small_size, int(small_size*size[1]/size[0]))
-    else:
-        new_size = (int(small_size*size[0]/size[1]), small_size)
-    new_img = img.resize(new_size)
-    # print 'resize to (%d,%d)' % new_size
-    return new_img
-
-
-def do_color_cast(img, offset):
-    '''Add a random number from [-offset, offset] to each channel'''
-    x = np.asarray(img, dtype='uint8')
-    x.flags.writeable = True
-    cast_value = [0, 0, 0]
-    for i in range(3):
-        r = random.randint(0, 1)
-        if r:
-            cast_value[i] = random.randint(-offset, offset)
-    for w in range(img.size[0]):
-        for h in range(img.size[1]):
-            for c in range(3):
-                if cast_value[c] == 0:
-                    continue
-                v = x[w][h][c]+cast_value[c]
-                if v < 0:
-                    v = 0
-                if v > 255:
-                    v = 255
-                x[w][h][c] = v
-    new_img = Image.fromarray(x.astype('uint8'), 'RGB')
-    return new_img
-
-
-def do_enhance(img, scale):
-    '''Apply random enhancement for Color,Contrast,Brightness,Sharpness.
-
-    Args:
-        scale(float): enhancement degree is from [1-scale, 1+scale]
-    '''
-    enhance_value = [1.0, 1.0, 1.0, 1.0]
-    for i in range(4):
-        r = random.randint(0, 1)
-        if r:
-            enhance_value[i] = random.uniform(1-scale, 1+scale)
-    if not enhance_value[0] == 1.0:
-        enhancer = ImageEnhance.Color(img)
-        img = enhancer.enhance(enhance_value[0])
-    if not enhance_value[1] == 1.0:
-        enhancer = ImageEnhance.Contrast(img)
-        img = enhancer.enhance(enhance_value[1])
-    if not enhance_value[2] == 1.0:
-        enhancer = ImageEnhance.Brightness(img)
-        img = enhancer.enhance(enhance_value[2])
-    if not enhance_value[3] == 1.0:
-        enhancer = ImageEnhance.Sharpness(img)
-        img = enhancer.enhance(enhance_value[3])
-    return img
-
-
-def do_flip(img):
-    # print 'flip'
-    new_img = img.transpose(Image.FLIP_LEFT_RIGHT)
-    return new_img
-
-
-def get_list_sample(l, sample_size):
-    return [l[i] for i in sorted(random.sample(xrange(len(l)), sample_size))]
-
-
-class Imgtool():
-
-    def __init__(self):
-        self.imgs = []
-        return
-
-    def load(self, path):
-        img = load_img(path)
-        self.imgs = [img]
-        return self
-
-    def set(self, imgs):
-        self.imgs = imgs
-        return self
-
-    def append(self, img):
-        self.imgs.append(img)
-        return self
-
-    def get(self):
-        return self.imgs
-
-    def resize_by_range(self, rng, k=1, update=True):
-        '''
-        Args:
-            rng: a tuple (begin,end), include begin, exclude end
-            k: number of samples, must be smaller than or equare to the length
-               of the range list, if k=0, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        size_list = range(rng[0], rng[1])
-        return self.resize_by_list(size_list, k, update)
-
-    def resize_by_list(self, size_list, k=1, update=True):
-        '''
-        Args:
-            k: number of samples, must be smaller than or equare to the length
-               of size_list, if k=0, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        new_imgs = []
-        if k < 0 or k > len(size_list):
-            raise Exception(
-                'k must be smaller in [0,%d(length of size_list)]' %
-                len(size_list))
-        for img in self.imgs:
-            if k == 0 or k == len(size_list):
-                small_sizes = size_list
-            else:
-                small_sizes = get_list_sample(size_list, k)
-
-            for small_size in small_sizes:
-                new_img = do_resize(img, small_size)
-                new_imgs.append(new_img)
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def resize_for_test(self, rng):
-        '''
-        Args:
-            rng: a tuple (begin,end)
-        '''
-        size_list = [rng[0], rng[0]/2+rng[1]/2, rng[1]]
-        return self.resize_by_list(size_list, k=3)
-
-    def rotate_by_range(self, rng, k=1, update=True):
-        '''
-        Args:
-            rng: a tuple (begin,end) in degree, include begin, exclude end
-            k: number of samples, must be smaller than or equare to the length
-               of the range list, if k=0, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        angle_list = range(rng[0], rng[1])
-        return self.rotate_by_list(angle_list, k, update)
-
-    def rotate_by_list(self, angle_list, k=1, update=True):
-        '''
-        Args:
-            k: number of samples, must be smaller than or equare to the length
-               of size_list, if k=0, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        new_imgs = []
-        if k < 0 or k > len(angle_list):
-            raise Exception(
-                'k must be smaller in [0,%d(length of angle_list)]' %
-                len(angle_list))
-
-        for img in self.imgs:
-            if k == 0 or k == len(angle_list):
-                angles = angle_list
-            else:
-                angles = get_list_sample(angle_list, k)
-
-            for angle in angles:
-                new_img = img.rotate(angle)
-                new_imgs.append(new_img)
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def crop_5(self, crop_size, k=1, update=True):
-        '''Crop at positions from [left_top, left_bottom, right_top,
-        right_bottom, and center].
-
-        Args:
-            crop_size(tuple): width and height of the result image.
-            k: number of samples, must be in [0,5], if k=0, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        new_imgs = []
-        positions = [
-            "left_top",
-            "left_bottom",
-            "right_top",
-            "right_bottom",
-            "center"]
-        if k > 5 or k < 0:
-            raise Exception('k must be in [0,5]')
-        for img in self.imgs:
-
-            if k > 0 and k < 5:
-                positions = get_list_sample(positions, k)
-
-            for position in positions:
-                new_img = do_crop(img, crop_size, position)
-                new_imgs.append(new_img)
-
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def crop_and_scale(self, crop_size, k=1, update=True):
-        '''Crop a max square patch of the input image at given position and
-        scale it into given size.
-
-        According to img size, crop position could be either
-        (left, center, right) or (top, middle, bottom).
-
-        Args:
-            crop_size(tuple): the width and height the output image
-            k: number of samples, must be in [0,3], if k=0, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        if not crop_size[0] == crop_size[1]:
-            raise Exception('crop_size must be a square')
-        new_imgs = []
-        if k > 3 or k < 0:
-            raise Exception('k must be in [0,3]')
-        positions_horizental = ["left", "center", "right"]
-        positions_vertical = ["top", "middle", "bottom"]
-        for img in self.imgs:
-            size = img.size
-            if size[0] > size[1]:
-                if k > 0 and k < 3:
-                    positions = get_list_sample(positions_horizental, k)
-                else:
-                    positions = positions_horizental
-            else:
-                if k > 0 and k < 3:
-                    positions = get_list_sample(positions_vertical, k)
-                else:
-                    positions = positions_vertical
-
-            for position in positions:
-                new_img = do_crop_and_scale(img, crop_size, position)
-                new_imgs.append(new_img)
-
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def crop_union(self, crop_size, k=1, update=True):
-        '''This is a union of crop_5 and crop_and_scale.
-
-        You can follow this example to union any number of imgtool methods
-        '''
-        crop_5_num = 5
-        crop_and_scale_num = 3
-        if k < 0 or k > crop_5_num+crop_and_scale_num:
-            raise Exception(
-                'k must be in [0,%d]' %
-                (crop_5_num+crop_and_scale_num))
-        if k == 0 or k == crop_5_num+crop_and_scale_num:
-            count = crop_5_num
-        else:
-            sample_list = range(0, crop_5_num+crop_and_scale_num)
-            samples = get_list_sample(sample_list, k)
-            count = 0
-            for s in samples:
-                if s < crop_5_num:
-                    count += 1
-        new_imgs = []
-        if count > 0:
-            new_imgs += self.crop_5(crop_size, k=count, update=False)
-        if k-count > 0:
-            new_imgs += self.crop_and_scale(crop_size, k=k-count, update=False)
-
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def flip(self, k=1, update=True):
-        '''
-        randomly flip a img left to right
-        Args:
-            k: number of samples, must be in [0,1,2], if k=0,2, then sample all
-            update: update imgs or not ( return new_imgs)
-        '''
-        new_imgs = []
-        if k < 0 or k > 2:
-            raise Exception('k must be in [0,2]')
-        for img in self.imgs:
-            flips = [0, 1]
-            if k > 0 and k < 2:
-                r = random.randint(0, 1)
-                flips = [r]
-            for flip in flips:
-                if flip:
-                    new_img = do_flip(img)
-                else:
-                    new_img = img
-                new_imgs.append(new_img)
-
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def color_cast(self, offset=20, k=1, update=True):
-        '''Add a random number from [-offset, offset] to each channel
-
-        Args:
-            offset: cast offset, >0 and <255
-            k: number of samples, must be larger than 0
-            update: update imgs or not ( return new_imgs)
-        '''
-        new_imgs = []
-        if k <= 0:
-            raise Exception('k must be larger than 0')
-        if offset < 0 or offset > 255:
-            raise Exception('offset must be >0 and <255')
-
-        for img in self.imgs:
-            for i in range(k):
-                new_img = do_color_cast(img, offset)
-                new_imgs.append(new_img)
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs
-
-    def enhance(self, scale=0.2, k=1, update=True):
-        '''Apply random enhancement for Color,Contrast,Brightness,Sharpness.
-
-        Args:
-            scale(float): enhancement degree is from [1-scale, 1+scale]
-            k: number of samples, must be larger than 0
-            update: update imgs or not ( return new_imgs)
-        '''
-        new_imgs = []
-        if k <= 0:
-            raise Exception('k must be larger than 0')
-        for img in self.imgs:
-            for i in range(k):
-                new_img = do_enhance(img, scale)
-                new_imgs.append(new_img)
-        if update:
-            self.imgs = new_imgs
-            return self
-        else:
-            return new_imgs


Mime
View raw message