grapevine_classification / utilitarios /data_augmentation.py
gabri14el's picture
Upload with huggingface_hub
e6b3e35
# -*- coding: utf-8 -*-
"""dl_data_augmentation.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1I7cHYydsGwZjG_axddRZMqWvrZiapwyu
C贸digo utilizado para gerar o data augmentation de imagens no geral
"""
#Imports necess谩rios
import numpy as np
import keras,glob,os
import pandas as pd
import cv2
from shutil import copy2
from keras.preprocessing.image import ImageDataGenerator, array_to_img,img_to_array, load_img
img_path = r'C:\Users\Gabriel\Downloads\castasv3\normal'
outpath = r'C:\Users\Gabriel\Downloads\castasv3\normal-splited'
sep = os.path.sep
teste_path = os.path.join(outpath, 'test')
validacao_path = os.path.join(outpath, 'validation')
treino_path = os.path.join(outpath, 'train')
paths = [outpath, teste_path, validacao_path, treino_path]
#verifica se as paths de saida existem
for path in paths:
if not os.path.lexists(path):
os.mkdir(path)
#metodo que itera pelos arquivos do diretorio salvando a path da imagem e sua respectiva classe
def directory_from_df_with_class(df, directory):
for r, d, f in os.walk(directory):
for file in f:
row = {}
row['path'] = os.path.join(r, file)
row['class'] = row['path'].split(os.path.sep)[-2]
#print(row['class'])
df= df.append(row, ignore_index=True)
return df
columns_df = ['path', 'class']
df = pd.DataFrame(columns=columns_df)
df = directory_from_df_with_class(df, img_path)
"""C贸digo que separa os datasets em treino, valida莽茫o e teste."""
from random import randint
def separa_df_treino_test(df, coluna_classe, percentual_teste):
#obtem as classes
#classes = df[coluna_classe].unique()
#contadores = df.groupby(coluna_classe).count()
contadores = df[coluna_classe].value_counts()
df_treino = pd.DataFrame(columns=df.columns)
df_teste = pd.DataFrame(columns=df.columns)
#define classe com valor minimo
minimo = np.min(contadores.values)
print("a classe com menor quantidade de amostras eh '{}' e possui {} amostras...".format(contadores.index[np.argmin(contadores.values)],minimo))
#define quantidade de imagens que serao utilizadas
tam_teste = int(minimo*percentual_teste)
print("tamanho do conjunto de teste eh: {}...".format(tam_teste))
print("o tamanho do dataframe original eh: {}...".format(len(df)))
for coluna in contadores.index:
#filtra o dataframe
df_aux = df[df[coluna_classe] == coluna]
#repete a quantidade de vezes que o tam teste e necessario
for i in range(tam_teste):
#obtem o indice
indice = randint(0, len(df_aux)-1)
#obtem valor
df_teste = df_teste.append(df_aux.iloc[[indice]], ignore_index=True)
#remove do df
df_aux.drop(df_aux.index[[indice]], inplace=True)
df_treino = pd.concat([df_aux, df_treino], ignore_index=True)
print("o tamanho do dataframe de teste eh: {}...".format(len(df_teste)))
print("o tamanho do dataframe de treino eh: {}...".format(len(df_treino)))
return df_treino, df_teste
def imagem_por_classe(df, coluna_classe, path_classe, quantidade=1):
#captura as classes
classes = df[coluna_classe].unique()
lista_imagens = []
#itera sobre as classes
for classe in classes:
df_classe = df[df[coluna_classe] == classe]
#captura a path imagens
for i in range(quantidade):
indice = randint(0, len(df_classe)-1)
lista_imagens.append(df_classe.iloc[[indice]][path_classe].values[0])
df_classe.drop(df_classe.index[[indice]], inplace=True)
return lista_imagens
df_treino, df_teste = separa_df_treino_test(df, 'class', 0.1)
imgs_visualizar = imagem_por_classe(df_teste, 'class', 'path', 1)
df_treino, df_validacao = separa_df_treino_test(df_treino, 'class', 0.2)
#imprimindo pesos
contadores = pd.DataFrame(df_treino['class'].value_counts())
contadores['peso'] = contadores.values/len(df_treino)
print('=================')
print(contadores)
#define funcao de salvar imagem
def salva_imagens_df(df, class_column, path_column, outpath):
for i, row in df.iterrows():
if not row[path_column] is None:
nome = row[path_column].split(os.path.sep)[-1]
path_destino = os.path.join(outpath, row[class_column])
if not os.path.lexists(path_destino):
os.mkdir(path_destino)
arquivo_path = os.path.join(path_destino, nome)
copy2(row[path_column], arquivo_path)
salva_imagens_df(df=df_treino, class_column='class', path_column='path', outpath=treino_path)
salva_imagens_df(df=df_teste, class_column='class', path_column='path', outpath=teste_path)
salva_imagens_df(df=df_validacao, class_column='class', path_column='path', outpath=validacao_path)
"""Faz o data augmentation:"""
filenames=df_treino['path'].values
for img in filenames:
if "DS_Store" in img: continue
src_fname, ext = os.path.splitext(img)
datagen = ImageDataGenerator(rotation_range=50,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
brightness_range=[0.6,1.0],
vertical_flip=True)
img = load_img(img)
x = img_to_array(img)
x = x.reshape((1,) + x.shape)
img_name = src_fname.split(os.path.sep)[-1]
class_name = src_fname.split(os.path.sep)[-2]
new_dir = os.path.join(treino_path, class_name)
if not os.path.lexists(new_dir):
os.mkdir(new_dir)
#save_fname = os.path.join(new_dir, os.path.basename(img_name))
save_fname = new_dir
i = 0
for batch in datagen.flow (x, batch_size=1, save_to_dir = save_fname,
save_prefix = img_name, save_format='jpg'):
i+=1
if i>5:
break
#gerar um zip com o novo dataset
#!zip -r -q dataset_aumentado.zip dataset_aumentado/*
columns_df = ['path', 'class']
df = pd.DataFrame(columns=columns_df)
df = directory_from_df_with_class(df, treino_path)
#imprimindo pesos
contadores = pd.DataFrame(df['class'].value_counts())
contadores['peso'] = contadores.values/len(df)
contadores = contadores.sort_index()
print('=================')
print(contadores)
print(contadores['peso'].values.tolist())
print('tamanho df: ', len(df))