Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Nesac128 committed Jan 19, 2019
2 parents 0d1c2ca + b263378 commit 21e9084
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 120 deletions.
6 changes: 5 additions & 1 deletion tensorimage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@
from tensorimage.data_augmentation.ops import AddPepperSaltNoise
from tensorimage.data_augmentation.ops import GaussianBlur
from tensorimage.data_augmentation.ops import FlipImages
from tensorimage.data_augmentation.ops import ModifyLighting
from tensorimage.data_augmentation.ops import RandomHue
from tensorimage.data_augmentation.ops import RandomBrightness
from tensorimage.data_augmentation.ops import RandomContrast
from tensorimage.data_augmentation.ops import RandomSaturation
from tensorimage.data_augmentation.ops import ColorFilter
from tensorimage.data_augmentation.builder import DataAugmentationBuilder
from tensorimage.data_augmentation.src import AugmentImageData
from tensorimage.classify.restore_model import ModelRestorer
Expand Down
52 changes: 37 additions & 15 deletions tensorimage/data_augmentation/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,53 @@


class DataAugmentationBuilder:
def __init__(self, *operations):
def __init__(self, *operations, exclude_original_data=False):
"""
:param operations: data augmentation classmethods *args
:param exclude_original_data: boolean value specifying
whether original data is returned or only generated data
"""
self.eod = exclude_original_data
self.operations = operations

def start(self, x, y, n_classes, dims, n_channels):
augmented_data = np.ndarray([0, dims[0], dims[1], n_channels])
augmented_labels = np.ndarray([0, n_classes])
data_augmenter = AugmentImageData(x, y, n_classes)
def start(self, x, y, verbose, n_classes, dims, n_channels):
if not self.eod:
augmented_data = np.concatenate((np.ndarray([0, dims[0], dims[1], n_channels]), x))
augmented_labels = np.concatenate((np.ndarray([0, n_classes]), y))
else:
augmented_data = np.ndarray([0, dims[0], dims[1], n_channels])
augmented_labels = np.ndarray([0, n_classes])

data_augmenter = AugmentImageData(x, y, verbose, n_classes)
for op in self.operations:
if op.__doc__ == data_augmenter.flip.__doc__:
data, labels = data_augmenter.flip(dims)
augmented_data = np.concatenate((augmented_data, data))
augmented_labels = np.concatenate((augmented_labels, labels))
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.add_salt_pepper_noise.__doc__:
data, labels = data_augmenter.add_salt_pepper_noise(op.salt_vs_pepper, op.amount)
augmented_data = np.concatenate((augmented_data, data))
augmented_labels = np.concatenate((augmented_labels, labels))
elif op.__doc__ == data_augmenter.modify_lighting.__doc__:
data, labels = data_augmenter.modify_lighting(op.max_delta)
augmented_data = np.concatenate((augmented_data, data))
augmented_labels = np.concatenate((augmented_labels, labels))
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.random_brightness.__doc__:
data, labels = data_augmenter.random_brightness(op.max_delta)
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.gaussian_blur.__doc__:
data, labels = data_augmenter.gaussian_blur(op.sigma)
augmented_data = np.concatenate((augmented_data, data))
augmented_labels = np.concatenate((augmented_labels, labels))
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.color_filter.__doc__:
data, labels = data_augmenter.color_filter(op.lower_hsv_bound, op.upper_hsv_bound)
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.random_hue.__doc__:
data, labels = data_augmenter.random_hue(op.max_delta)
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.random_contrast.__doc__:
data, labels = data_augmenter.random_contrast(op.lower_contrast_bound, op.upper_contrast_bound)
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
elif op.__doc__ == data_augmenter.random_saturation.__doc__:
data, labels = data_augmenter.random_saturation(op.lower_saturation_bound, op.upper_saturation_bound)
augmented_data, augmented_labels = self.update_data(data, labels, augmented_data, augmented_labels)
return augmented_data, augmented_labels

@staticmethod
def update_data(data, labels, augmented_data, augmented_labels):
augmented_data = np.concatenate((augmented_data, data))
augmented_labels = np.concatenate((augmented_labels, labels))
return augmented_data, augmented_labels
33 changes: 30 additions & 3 deletions tensorimage/data_augmentation/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,40 @@ def __init__(self, salt_vs_pepper: float=0.1, amount: float = 0.0004):
self.amount = amount


class ModifyLighting:
"""modify_lighting"""
class RandomBrightness:
"""random_brightness"""
def __init__(self, max_delta: float):
self.max_delta = max_delta


class GaussianBlur:
"""gaussian_blur"""
def __init__(self, sigma=1):
self.sigma=sigma
self.sigma = sigma


class ColorFilter:
"""color_filter"""
def __init__(self, lower_hsv_bound: tuple, upper_hsv_bound: tuple):
self.lower_hsv_bound = lower_hsv_bound
self.upper_hsv_bound = upper_hsv_bound


class RandomHue:
"""random_hue"""
def __init__(self, max_delta):
self.max_delta = max_delta


class RandomContrast:
"""random_contrast"""
def __init__(self, lower_contrast_bound, upper_contrast_bound):
self.lower_contrast_bound = lower_contrast_bound
self.upper_contrast_bound = upper_contrast_bound


class RandomSaturation:
"""random_saturation"""
def __init__(self, lower_saturation_bound, upper_saturation_bound):
self.lower_saturation_bound = lower_saturation_bound
self.upper_saturation_bound = upper_saturation_bound
85 changes: 61 additions & 24 deletions tensorimage/data_augmentation/src.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import numpy as np
import scipy.ndimage
import scipy.misc
from progress.bar import Bar
import cv2
import tensorimage.util.log as log


class AugmentImageData:
def __init__(self, x, y, n_classes: int, n_channels=3):
def __init__(self, x, y, verbose, n_classes: int, n_channels=3):
"""
:param x: image data of type numpy.ndarray
:param y: labels of type numpy.ndarray
Expand All @@ -15,21 +16,24 @@ def __init__(self, x, y, n_classes: int, n_channels=3):
"""
self.x = x
self.y = y
self.verbose = verbose
self.n_classes = n_classes
self.n_channels = n_channels

assert len(self.x.shape) == 4 and len(self.y.shape) == 2
assert self.x.shape[0] == self.y.shape[0]

self.n_images = self.x.shape[0]
self.sess = tf.Session()

log.info("Applying data augmentation techniques: ", self)

def _copy_xy(self):
return np.copy(self.x), np.copy(self.y)

def flip(self, dims):
"""flip_images"""
flipping_bar = Bar("Flipping images:", max=self.n_images)
sess = tf.Session()
log.info("Image flipping", self)
augmented_data = tf.constant([], tf.float32, shape=[0, dims[0], dims[1], self.n_channels])
augmented_labels = tf.constant([], tf.float32, shape=[0, self.n_classes])
for (image_n, image), (label_n, label) in zip(enumerate(self.x), enumerate(self.y)):
Expand All @@ -47,50 +51,83 @@ def flip(self, dims):
tf.expand_dims(label, 0)], 0)
augmented_data = tf.concat([augmented_data, tf.cast(data, tf.float32)], 0)
augmented_labels = tf.concat([augmented_labels, tf.cast(labels, tf.float32)], 0)
flipping_bar.next()
with sess.as_default():
with self.sess.as_default():
augmented_data = augmented_data.eval()
augmented_labels = augmented_labels.eval()
return augmented_data, augmented_labels

def add_salt_pepper_noise(self, salt_vs_pepper: float=0.1, amount: float=0.0004):
"""add_pepper_salt_noise"""
sp_noise_bar = Bar("Adding salt pepper noise:", max=self.n_images)
log.info("Salt-pepper noise", self)
salt_n = np.ceil(amount * self.x[0].size * salt_vs_pepper)
pepper_n = np.ceil(amount * self.x[0].size * (1.0 - salt_vs_pepper))

images_copy, labels_copy = self._copy_xy()

for (image_n, image), (label_n, label) in zip(enumerate(images_copy), enumerate(labels_copy)):
for image_n, image in enumerate(images_copy):
salt = [np.random.randint(0, i - 1, int(salt_n)) for i in image.shape]
images_copy[image_n][salt[0], salt[1], :] = 1

coords = [np.random.randint(0, i - 1, int(pepper_n)) for i in image.shape]
images_copy[image_n][coords[0], coords[1], :] = 0
return images_copy, labels_copy

def gaussian_blur(self, sigma=1):
"""gaussian_blur"""
log.info("Gaussian blur", self)
images_copy, labels_copy = self._copy_xy()
for image_n, image in enumerate(self.x):
gaussian_image = scipy.ndimage.filters.gaussian_filter(image, sigma=sigma)
images_copy[image_n] = gaussian_image
return images_copy, labels_copy

labels_copy[label_n] = label
sp_noise_bar.next()
def color_filter(self, lower_hsv_bound, upper_hsv_bound):
"""color_filter"""
log.info("Color filters", self)
images_copy, labels_copy = self._copy_xy()
for image_n, image in enumerate(self.x):
image_hsv = cv2.cvtColor(np.uint8(image), cv2.COLOR_RGB2HSV)
image_mask = cv2.inRange(image_hsv, lower_hsv_bound, upper_hsv_bound)
image_rgb = cv2.bitwise_and(image, image, image_mask)
images_copy[image_n] = image_rgb
return images_copy, labels_copy

def modify_lighting(self, max_delta: float):
"""modify_lighting"""
lighting_bar = Bar("Modifying lighting:", max=self.n_images)
def random_brightness(self, max_delta: float):
"""random_brightness"""
log.info("Random brightness", self)
images_copy, labels_copy = self._copy_xy()
sess = tf.Session()
for (image_n, image), (label_n, label) in zip(enumerate(self.x), enumerate(self.y)):
for (image_n, image), in enumerate(self.x):
random_brightness_image = tf.image.random_brightness(image, max_delta).eval(session=sess)
images_copy[image_n] = random_brightness_image
labels_copy[label_n] = label
lighting_bar.next()
return images_copy, labels_copy

def gaussian_blur(self, sigma=1):
"""gaussian_blur"""
gaussian_blur_bar = Bar("Adding gaussian blur:", max=self.n_images)
def random_hue(self, max_delta):
"""random_hue"""
log.info("Random hue", self)
images_copy, labels_copy = self._copy_xy()
for (image_n, image), (label_n, label) in zip(enumerate(self.x), enumerate(self.y)):
gaussian_image = scipy.ndimage.filters.gaussian_filter(image, sigma=sigma)
images_copy[image_n] = gaussian_image
labels_copy[label_n] = label
gaussian_blur_bar.next()
for image_n, image in enumerate(self.x):
image_random_hue = tf.image.random_hue(image, max_delta)
image_random_hue = self.sess.run(image_random_hue)
images_copy[image_n] = image_random_hue
return images_copy, labels_copy

def random_contrast(self, lower_contrast_bound, upper_contrast_bound):
"""random_contrast"""
log.info("Random contrast", self)
images_copy, labels_copy = self._copy_xy()
for image_n, image in enumerate(self.x):
image_random_contrast = tf.image.random_contrast(image, lower_contrast_bound, upper_contrast_bound)
image_random_contrast = self.sess.run(image_random_contrast)
images_copy[image_n] = image_random_contrast
return images_copy, labels_copy

def random_saturation(self, lower_saturation_bound, upper_saturation_bound):
"""random_saturation"""
log.info("Random saturation", self)
images_copy, labels_copy = self._copy_xy()
for image_n, image in enumerate(self.x):
image_random_saturation = tf.image.random_saturation(image, lower_saturation_bound, upper_saturation_bound)
image_random_saturation = self.sess.run(image_random_saturation)
images_copy[image_n] = image_random_saturation
return images_copy, labels_copy
2 changes: 1 addition & 1 deletion tensorimage/train/trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def build_dataset(self):
if self.data_augmentation_builder[1]:
self.augmented_train_x, self.augmented_test_y = \
self.data_augmentation_builder[0].start(
self.train_x, self.train_y, self.n_classes,
self.train_x, self.train_y, self.verbose, self.n_classes,
(self.height, self.width), n_channels)

def train(self):
Expand Down
78 changes: 2 additions & 76 deletions tensorimage/util/log.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,6 @@
import platform
import logging


def add_coloring_to_emit_windows(fn):
def _out_handle(self):
import ctypes
return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)

out_handle = property(_out_handle)

def _set_color(self, code):
import ctypes
self.STD_OUTPUT_HANDLE = -11
hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)

setattr(logging.StreamHandler, '_set_color', _set_color)

def new(*args):
FOREGROUND_BLUE = 0x0001 # text color contains blue.
FOREGROUND_GREEN = 0x0002 # text color contains green.
FOREGROUND_RED = 0x0004 # text color contains red.
FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
FOREGROUND_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
# winbase.h
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12

# wincon.h
FOREGROUND_BLACK = 0x0000
FOREGROUND_BLUE = 0x0001
FOREGROUND_GREEN = 0x0002
FOREGROUND_CYAN = 0x0003
FOREGROUND_RED = 0x0004
FOREGROUND_MAGENTA = 0x0005
FOREGROUND_YELLOW = 0x0006
FOREGROUND_GREY = 0x0007
FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.

BACKGROUND_BLACK = 0x0000
BACKGROUND_BLUE = 0x0010
BACKGROUND_GREEN = 0x0020
BACKGROUND_CYAN = 0x0030
BACKGROUND_RED = 0x0040
BACKGROUND_MAGENTA = 0x0050
BACKGROUND_YELLOW = 0x0060
BACKGROUND_GREY = 0x0070
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.

levelno = args[1].levelno
if levelno >= 50:
color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY
elif levelno >= 40:
color = FOREGROUND_RED | FOREGROUND_INTENSITY
elif levelno >= 30:
color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
elif levelno >= 20:
color = FOREGROUND_GREEN
elif levelno >= 10:
color = FOREGROUND_MAGENTA
else:
color = FOREGROUND_WHITE
args[0]._set_color(color)

ret = fn(*args)
args[0]._set_color(FOREGROUND_WHITE)
return ret

return new


def add_coloring_to_emit_ansi(fn):
def new(*args):
levelno = args[1].levelno
Expand All @@ -93,7 +23,7 @@ def new(*args):


def warning(msg: str, obj, *args, **kwargs): # Verbose level 3
if obj.verbose == 3:
if obj.verbose >= 3:
logging.warning(msg, *args, **kwargs)


Expand Down Expand Up @@ -122,11 +52,7 @@ def getLogger(name: str):


def _setup():

if platform.system() == 'Windows':
logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
else:
logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)

root = logging.getLogger()
root.setLevel(logging.DEBUG)
Expand Down

0 comments on commit 21e9084

Please sign in to comment.