SOL4Py Sample: CustomAugmentedImagePreview
|
#******************************************************************************
#
# Copyright (c) 2018-2019 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#******************************************************************************
# CustomAugmentedImagePreview.py
# 2019/07/16
# encodig: utf-8
import sys
import os
import traceback
import errno
sys.path.append('../../')
from SOL4Py.ZApplicationView import *
from SOL4Py.ZImageView import *
from SOL4Py.ZPushButton import *
from SOL4Py.ZScaleComboBox import *
from SOL4Py.ZHorizontalLayouter import *
from SOL4Py.ZVerticalPane import *
from SOL4Py.ZLabeledCheckBox import *
from SOL4Py.ZLabeledDoubleSpinBox import *
from SOL4Py.opencv.ZOpenCVCroppedImageReader import *
from SOL4Py.ZCustomImageDataGenerator import *
class MainView(ZApplicationView):
IMAGE_COUNT = 25
IMAGE_COUNT_PERLINE= 5
CROP_SIZE = 224
# MainView Constructor
def __init__(self, title, x, y, width, height):
super(MainView, self).__init__(title, x, y, width, height, Z.Vertical)
self.get_layout().setSpacing(0)
self.scale = 50
self.get_layout().setContentsMargins(0,0,0,0);
self.scale_combobox = ZScaleComboBox(None, "Scale")
self.scale_combobox.current_scale(self.scale)
self.add(self.scale_combobox)
self.image_views = [None] * self.IMAGE_COUNT #
self.filename = "./girl.jpg"
# 1. Create our default ZCutomImageDataGenerator with rotation_range
self.generator = self.create_generator()
# 2 Create an inner widget.
self.inner = QWidget(self.main_layouter)
# 3 Set QSizePolicy.Expanding to the self.inner
self.inner.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# 4 Create a grid layout for the inner widget.
self.grid = QGridLayout(self.inner)
# 5 Add an instance of ZImageView to the grid.
try:
self.size = (self.CROP_SIZE, self.CROP_SIZE)
self.image = Image.open(self.filename)
# 6 Get flow from the self.generator
flow = self.generator.flow(self.image, n_augmentation=self.IMAGE_COUNT)
# 7 Get generated images from the flow.
for i in range(self.IMAGE_COUNT):
# 8 Create an instance of ZImageView
self.image_views[i] = ZImageView(self, 0, 0, 300, 300)
# 9 Get a generated image from the flow.
cropped_image = next(flow)
generated = np.asarray(cropped_image)
self.image_views[i].set_image(generated)
self.image_views[i].rescale(self.scale)
x = int(i % self.IMAGE_COUNT_PERLINE)
y = int(i / self.IMAGE_COUNT_PERLINE)
self.grid.addWidget(self.image_views[i], y, x)
self.set_filenamed_title(self.filename)
except:
traceback.print_exc()
# 10 Add the inner to the self.
self.add(self.inner)
# 11 Add scale_changed callback to the self.scale_combobox.
self.scale_combobox.add_activate_callback(self.scale_changed)
self.show()
def create_generator(self):
# Create an instance ZImageDataGenerator.
return ZCustomImageDataGenerator(crop_size=self.CROP_SIZE,
rotation_angle = self.rotation_range.get_value(),
left_top_shift = (self.left_shift_range.get_value(), self.top_shift_range.get_value()),
shrink_ratio = (self.width_shrink_range.get_value(), self.height_shrink_range.get_value()),
contrast = self.contrast.get_value(),
saultpepper_noise = self.saultpepper_noise.get_value(),
horizontal_flip = self.horizontal_flip.is_checked(),
vertical_flip = self.vertical_flip.is_checked())
def add_control_pane(self, fixed_width=200):
self.vpane = ZVerticalPane(self, fixed_width)
# Create preview PushButton
self.preview = ZPushButton("Preview", self.vpane)
self.preview.add_activated_callback(self.do_preview)
self.vpane.add(self.preview)
self.spacing = QLabel(" ")
self.vpane.add(self.spacing)
self.label = QLabel("ImageDataGenerator Parameters:")
self.vpane.add(self.label)
#self.groupBox.setLayout(self.vpane.get_layout())
self.rotation_range = ZLabeledDoubleSpinBox(self.vpane, "rotation_range",
0, 20.0, 10.0, step=1.0)
self.left_shift_range = ZLabeledDoubleSpinBox(self.vpane, "left_shift_range",
0, 20.0, 10.0, step=1.0)
self.top_shift_range = ZLabeledDoubleSpinBox(self.vpane, "top_shift_range",
0, 20.0, 10.0, step =1.0)
self.width_shrink_range = ZLabeledDoubleSpinBox(self.vpane, "width_shrink_range",
0.80, 0.99, 0.90, step=0.01)
self.height_shrink_range = ZLabeledDoubleSpinBox(self.vpane, "height_shrink_range",
0.80, 0.99, 0.90, step=0.01)
#self.channel_shift_range = ZLabeledDoubleSpinBox(self.vpane, "channel_shift",
# 0, 3.0, 2.0, step=0.1)
self.contrast = ZLabeledDoubleSpinBox(self.vpane, "contrast",
0.01, 0.06, 0.02, step=0.01)
self.saultpepper_noise = ZLabeledDoubleSpinBox(self.vpane, "saultpepper_noise",
0.01, 0.05, 0.02, step=0.01)
self.horizontal_flip = ZLabeledCheckBox(self.vpane, "horizontal_flip")
#self.horizontal_flip.set_check()
self.vertical_flip = ZLabeledCheckBox(self.vpane, "vertical_flip")
self.vpane.add(self.rotation_range)
self.vpane.add(self.left_shift_range)
self.vpane.add(self.top_shift_range)
self.vpane.add(self.width_shrink_range)
self.vpane.add(self.height_shrink_range)
self.vpane.add(self.contrast)
self.vpane.add(self.saultpepper_noise)
self.vpane.add(self.horizontal_flip)
self.vpane.add(self.vertical_flip)
self.set_right_dock(self.vpane)
# Callback to the preview PushButton
def do_preview(self):
self.inner.hide()
try:
self.size = (self.CROP_SIZE, self.CROP_SIZE)
self.image = Image.open(self.filename)
self.generator = self.create_generator()
# 1 Get flow from the self.generator
flow = self.generator.flow(self.image, n_augmentation=self.IMAGE_COUNT)
# 2 Get generated images from the flow.
for i in range(self.IMAGE_COUNT):
# 3 Get a generated image from the flow.
cropped_image = next(flow)
generated = np.asarray(cropped_image)
self.image_views[i].set_image(generated)
self.image_views[i].rescale(self.scale)
x = int(i % self.IMAGE_COUNT_PERLINE)
y = int(i / self.IMAGE_COUNT_PERLINE)
self.grid.addWidget(self.image_views[i], y, x)
self.set_filenamed_title(self.filename)
except:
traceback.print_exc()
self.grid.update()
self.inner.show()
def load_file(self, filename):
self.do_preview()
# Scale changed callback
def scale_changed(self, text):
text = text.replace("%", "")
scale = int(text) # percentage
# Hide self.inner to avoid the flickering of image_views
self.inner.hide()
for i in range(self.IMAGE_COUNT):
self.image_views[i].rescale(scale)
# You should call update method of self.grid layout
self.grid.update()
self.inner.show()
def file_open(self):
options = QFileDialog.Options()
self.filename, _ = QFileDialog.getOpenFileName(self,"FileOpenDialog", "",
"All Files (*);;Image Files (*.png;*jpg;*.jpeg)", options=options)
if self.filename:
self.load_file(self.filename)
self.set_filenamed_title(self.filename)
def file_save(self):
# 1 Show a folderDialog to select a folder to save generated images
folder = QFileDialog.getExistingDirectory(self,
"OpenFolder",
os.path.expanduser('.'),
QFileDialog.ShowDirsOnly)
if folder:
#dir = dir.replace('/', os.sep)
print("Folder button clicked {}".format(folder))
self.inner.hide()
try:
self.generator = self.create_generator()
# Get a flow from the self.generator
flow = self.generator.flow_from_directory(self.filename,
save_folder = folder,
save_format= "jpg",
n_augmentation=self.IMAGE_COUNT)
# Get generated images from the flow.
for i in flow:
image = next(flow)
print("generated {} image size: {}".format(i, image.size))
except:
traceback.print_exc()
self.grid.update()
self.inner.show()
#*************************************************
#
if main(__name__):
try:
app_name = os.path.basename(sys.argv[0])
applet = QApplication(sys.argv)
main_view = MainView(app_name, 40, 40, 800, 640)
main_view.show ()
applet.exec_()
except:
traceback.print_exc()
Last modified:17 July 2019