Skip to content

Commit

Permalink
added image eda app section
Browse files Browse the repository at this point in the history
  • Loading branch information
soft-nougat committed Jan 24, 2022
1 parent 414298a commit ba24ff6
Show file tree
Hide file tree
Showing 7 changed files with 445 additions and 4 deletions.
9 changes: 7 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
selected_structure = st.selectbox("Choose data structure to analyse",
("Structured data",
"Unstructured, text data",
"Unstructured, audio data"))
"Unstructured, audio data",
"Unstructured, image data"))

if selected_structure == "Structured data":

Expand All @@ -41,12 +42,16 @@
from text_eda.text_data import *
text_data_app()


elif selected_structure == "Unstructured, audio data":

from audio_eda.audio_data import *
audio_data_app()

elif selected_structure == "Unstructured, image data":

from image_eda.image_data import *
image_data_app()


except KeyError:
st.error("Please select a key value from the dropdown to continue.")
Expand Down
71 changes: 70 additions & 1 deletion helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
from PIL import Image
import pandas as pd

import io
from PIL import Image
from pprint import pprint
from zipfile import ZipFile
from image_eda.augment import apply_augmentations

def set_bg_hack(main_bg):
'''
A function to unpack an image from root folder and set as bg.
Expand Down Expand Up @@ -173,4 +179,67 @@ def check_input_method(data_input_mthd):
st.session_state.is_batch_process = True
st.session_state.is_file_uploaded = True

return df,st.session_state.txt
return df,st.session_state.txt

def load_images():

data = st.sidebar.file_uploader("Upload image dataset",
type=['png', 'jpg', 'jpeg'],
accept_multiple_files=True)

if data:
images = []
augmentations = get_augmentations()
for image_file in data:
file_details = {"None": None, "File name":image_file.name, "File type":image_file.type, "File size":image_file.size}
image = Image.open(image_file)
images.append((file_details, image))

images = apply_augmentations(images, augmentations)
return images

def _get_default_augmentations() -> dict:
augmentations = {
'resize': {
'width': None,
'height': None
},
'grayscale': False,
'contrast': {'value':None},
'brightness': {'value':None},
'sharpness': {'value':None},
'color': {'value':None},
'denoise': False,
}
return augmentations

def get_augmentations() -> dict:
if 'augmentations' not in st.session_state:
st.session_state.augmentations = _get_default_augmentations()
return st.session_state.augmentations

def update_augmentations(augmentations) -> None:
st.session_state.augmentations = augmentations

def _file_process_in_memory(images):
""" Converts PIL image objects into BytesIO in-memory bytes buffers. """
new_images = []
for image_name, pil_image in images:
file_object = io.BytesIO()
pil_image.save(file_object, "PNG")
pil_image.close()
new_images.append((image_name, file_object))

return new_images

def export(images):
images = _file_process_in_memory(images)

# Create an in-memory zip file from the in-memory image file data.
zip_file_bytes_io = io.BytesIO()

with ZipFile(zip_file_bytes_io, 'w') as zip_file:
for image_name, bytes_stream in images:
zip_file.writestr(image_name["File name"]+".png", bytes_stream.getvalue())
name = st.sidebar.text_input("File name", value="My augmented dataset")
st.sidebar.download_button('Download Zip', zip_file_bytes_io.getvalue(), file_name=f'{name}.zip')
28 changes: 28 additions & 0 deletions image_eda/augment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import streamlit as st
from PIL import Image, ImageEnhance
import cv2
import numpy as np

def apply_augmentations(images, augmentations) -> list:
new_images = []
for details, image in images:
new_image = image
if augmentations["resize"]["width"] is not None and augmentations["resize"]["height"] is not None:
new_image = new_image.resize((augmentations["resize"]["width"], augmentations["resize"]["height"]), Image.ANTIALIAS)
if augmentations["grayscale"] == True:
new_image = new_image.convert('L')
if augmentations["contrast"]["value"] is not None:
new_image = ImageEnhance.Contrast(new_image).enhance(augmentations["contrast"]["value"])
if augmentations["brightness"]["value"] is not None:
new_image = ImageEnhance.Brightness(new_image).enhance(augmentations["brightness"]["value"])
if augmentations["sharpness"]["value"] is not None:
new_image = ImageEnhance.Sharpness(new_image).enhance(augmentations["sharpness"]["value"])
if augmentations["color"]["value"] is not None:
new_image = ImageEnhance.Color(new_image).enhance(augmentations["color"]["value"])
if augmentations["denoise"] == True:
if len(new_image.split()) != 3:
new_image = Image.fromarray(cv2.fastNlMeansDenoising(np.array(new_image)))
else:
new_image = Image.fromarray(cv2.fastNlMeansDenoisingColored(np.array(new_image)))
new_images.append((details, new_image))
return new_images
73 changes: 73 additions & 0 deletions image_eda/image_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
A file with the high level image eda app functions
"""
import streamlit as st
from helper_functions import *
from image_eda.preparation import show_grid, show_sizes, show_histograms, show_channels, augmentations, export_images


def image_data_app():

st.write("Welcome to the DQW for unsupervised image data. ",
"Understanding your data is an important step ",
"in AI model development. This app ",
"offers visualisation of descriptive statistics of a ",
"collection of images using a multitude of packages.")

display_app_header(main_txt = "Step 1",
sub_txt= "Upload data",
is_sidebar=True)

images = load_images()

if images:

display_app_header(main_txt = "Step 2",
sub_txt= "Choose what you want to see/do",
is_sidebar=True)

selected_structure = st.sidebar.radio(
"",
("Image grid",
"Image sizes",
"Color histograms",
"Color channels",
"Augmentations"))

if selected_structure == "Image grid":
show_grid(images)
elif selected_structure == "Image sizes":
show_sizes(images)
elif selected_structure == "Color histograms":
show_histograms(images)
elif selected_structure == "Color channels":
show_channels(images)
elif selected_structure == "Augmentations":
augmentations(images)

display_app_header(main_txt = "Step 3",
sub_txt= "Export augmented data",
is_sidebar=True)

is_export = st.sidebar.button("Export ⬇️")
if is_export:
export_images(images)



# prompt the user with an option to select which data they want to
# analyse - save code, right now we only have 1 option
#selected_structure = st.selectbox("Choose data structure to analyse",
#("Unsupervised image data",
#"Supervised image data, Classification",
#"Supervised image data, Segmentation",
#"Supervised image data, Regression"))

#elif selected_structure == "Supervised image data, Classification":
#st.error("This feature has not been implemented yet!")
#elif selected_structure == "Supervised image data, Segmentation":
#st.error("This feature has not been implemented yet!")
#elif selected_structure == "Supervised image data, Regression":
#st.error("This feature has not been implemented yet!")
Loading

0 comments on commit ba24ff6

Please sign in to comment.