File size: 6,168 Bytes
e6b3e35 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# -*- 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)) |