import pandas as pd from numpy import ndarray from sklearn import preprocessing from sklearn.neighbors import KNeighborsClassifier from scipy import stats from sklearn.naive_bayes import GaussianNB import statistics from sklearn.metrics import pairwise_distances_argmin_min import numpy as np from random import randint import matplotlib.pyplot as plt import cv2 import glob import math import os import random ''' Funções para pré-processamento dos dados ''' # Carregando fotos da pasta def loadFiles(path, array): for i in glob.glob(path): img = cv2.imread(i) array.append(img) return array # Função que faz o filtro cinza nas fotos def grayConversion(arrayphotos): size = len(arrayphotos) for x in range (0,size): arrayphotos[x] = cv2.cvtColor(arrayphotos[x], cv2.COLOR_BGR2GRAY) return arrayphotos # Função que aplic o filtro blur nas fotos do array def blurConversion(arrayphotos ,val1, val2): for x in range(len(arrayphotos)): arrayphotos[x] = cv2.GaussianBlur(arrayphotos[x],(val1,val1), val2) return arrayphotos #Função que faz a binarização das fotos def binaryConversion(arrayphotos,threshold,val1): for x in range(len(arrayphotos)): arrayphotos[x] = cv2.adaptiveThreshold(arrayphotos[x],threshold,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,val1,10) return arrayphotos #Função que inverte as fotos binárias def invertConversion(arrayphotos): for x in range(len(arrayphotos)): arrayphotos[x] = cv2.bitwise_not(arrayphotos[x]) return arrayphotos # função de normalização dos dados usando o modelo de # normalização por reescala def normalizar(dados): x = dados.values min_max_scaler = preprocessing.MinMaxScaler() x_scaled = min_max_scaler.fit_transform(x) dados_norm = pd.DataFrame(x_scaled) return dados_norm def extratorCaracteristicas(arrayimgs): squarescarac = [] for x in arrayimgs: aux = [] im2, countours, hierachy = cv2.findContours(x, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) if len(countours) == 0: for b in range(0,45): aux.append(0) elif len(countours) > 0: momentum = cv2.moments(x) momentum = list(dict.values(momentum)) # momentos for i in momentum: aux.append(i) moments = cv2.HuMoments(momentum, True).flatten() # Hu moments for i in moments: aux.append(i) area = cv2.contourArea(countours[0]) # area aux.append(area) peri = cv2.arcLength(countours[0], True) # perimetro aux.append(peri) if peri > 0: compactness = (4 * math.pi * area) / (peri ** 2) # compacidade aux.append(compactness) elif peri == 0: aux.append(0) aproxx = cv2.approxPolyDP(countours[0], 0.04 * peri, True) # vertices vertc = len(aproxx) aux.append(vertc) histogram = get_histogram(aproxx) # Histograma da Frequencia de angulos for h in histogram: aux.append(h) squarescarac.append(aux) return squarescarac def resizeImages(images,width,height): i = len(images) for x in range(0,i): images[x] = cv2.resize(images[x],(width,height)) return images def get_angle(p0, p1, p2): v0 = np.array(p0) - np.array(p1) v1 = np.array(p2) - np.array(p1) angle = np.math.atan2(np.linalg.det([v0, v1]), np.dot(v0, v1)) return np.degrees(angle) def get_histogram(aproxx): zero = [] zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) zero.append(0) #transformando em um array bidimensional retornopollyDP = np.reshape(aproxx, (aproxx.shape[0], (aproxx.shape[1] * aproxx.shape[2]))) #checando se não é uma linha if (len(retornopollyDP) < 3): return zero arraysdeangulo = [] for x in range(len(retornopollyDP)): # caso especial : quando a primeira posição do array for o angulo central if x == 0: bla3 = get_angle(retornopollyDP[x + 1], retornopollyDP[x], retornopollyDP[len(retornopollyDP) - 1]) arraysdeangulo.append(math.fabs(bla3)) # caso especial : quando a última posição do array for o ângulo central if x == len(retornopollyDP) - 1: bla4 = get_angle(retornopollyDP[x - 1], retornopollyDP[x], retornopollyDP[0]) arraysdeangulo.append(math.fabs(bla4)) if x > 0 and x < len(retornopollyDP) - 1: bla5 = get_angle(retornopollyDP[x + 1], retornopollyDP[x], retornopollyDP[x - 1]) arraysdeangulo.append(math.fabs(bla5)) hist, bins = np.histogram(arraysdeangulo, bins=[0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180]) return hist # funcão que seleciona num quantidade de imagens aleatoriamente # em um vetor e retorna um vetor auxiliar apenas com as imagens # selecionadas def seleciona_imagens (arrayImgs, num): tamanho = len(arrayImgs) selecionadas = [] nao_selecionadas = [] aux = [] var = 0 for x in range(0, num): if x == 0: var = randint(0, tamanho - 1) aux.append(var) selecionadas.append(arrayImgs[var]) elif x > 0: var = randint(0, tamanho - 1) while np.isin(var ,aux): var = randint(0, tamanho - 1) selecionadas.append(arrayImgs[var]) aux.append(var) for x in range(0, tamanho): if np.isin(x,aux): continue else: nao_selecionadas.append(arrayImgs[x]) return selecionadas, nao_selecionadas #função que salva as imagens na pasta dada como parâmetro def save_images(images, path): cont = 0 for i in images: y = str(cont) cv2.imwrite(path + y + '.jpg', i) cont += 1 return 0 # função que retorna população de cromossomos e tem como parametros # tamanho da população (número de cromossomos) e tamanho dos cromossomos def create_population(size_population, size_chromossome): population = [] for y in range(0, size_population): aux = [] for i in range(0, size_chromossome): x = randint(0, 200) if x % 2 == 0: aux.append(0) elif x % 2 != 0: aux.append(1) population.append(aux) return population # função que identifica o tamanho do cromossomo e retorna o vetor de características correspondente def decode_chromossome(chromossome): images_class = [] if chromossome[0] == 0 and chromossome[1] == 0: images_class = pd.read_csv('C:/Users/Auricelia/Desktop/DataSetsML/Images_16_s.csv') images_class = pd.DataFrame(images_class) elif chromossome[0] == 0 and chromossome[1] == 1: images_class = pd.read_csv('C:/Users/Auricelia/Desktop/DataSetsML/Images_32_s.csv') images_class = pd.DataFrame(images_class) elif chromossome[0] == 1 and chromossome[1] == 0: images_class = pd.read_csv('C:/Users/Auricelia/Desktop/DataSetsML/Images_64_s.csv') images_class = pd.DataFrame(images_class) elif chromossome[0] == 1 and chromossome[1] == 1: images_class = pd.read_csv('C:/Users/Auricelia/Desktop/DataSetsML/Images_128_s.csv') images_class = pd.DataFrame(images_class) return images_class #fucção que retorna as posições do array que #são usadas pelo cromossomo para a classificação def positions_chromossome(chromossome): selected_pos = [] for c in range(2,len(chromossome)): aux = [] if chromossome[c] == 1: selected_pos.append(c) elif chromossome[c] == 0: continue return selected_pos # função que retorna o array com características selecionadas # pelo cromossomo passando as posicoes selecionadas # e o vetor com as características def carac_imagens(selected_position,array_images): arrayzao = [] z = 0 for j in range(0,len(array_images)): aux = [] for i in range(0,len(selected_position)): z = selected_position[i] aux.append(array_images[j][z]) arrayzao.append(aux) arrayzao = pd.DataFrame(arrayzao) return arrayzao #gera o conjunto dos dois melhores cromossomos para #garantir o elitismo no algoritmo genético def get_best_cromossomos(acuracias,cromossomos): index = [] melhor = [] best_acuracia = [] print('index antes',index) index.append(acuracias.index(max(acuracias))) print('index melhor',acuracias.index(max(acuracias))) best_acuracia.append(max(acuracias)) print('best acc',max(acuracias)) acuracias[acuracias.index(max(acuracias))] = 0 index.append(acuracias.index(max(acuracias))) print('index melhor',acuracias.index(max(acuracias))) best_acuracia.append(max(acuracias)) print('best acc',max(acuracias)) acuracias[acuracias.index(max(acuracias))] = 0 print('index dpeois',index) for i in range(0,len(index)): melhor.append(cromossomos[index[i]]) cromossomos[index[i]] = 0 print('melhor',cromossomos[i]) # melhor.append(cromossomos[index[0]]) # melhor.append(cromossomos[index[1]]) return melhor, best_acuracia, cromossomos # seleção por torneio gera aleatoriamente dois # cromossomos e retorna o melhor deles def tournament_selection(acuracias, cromossomos): melhor = [] aux =[] rand1 = randint(0,len(cromossomos)-1) rand2 = randint(0,len(cromossomos)-1) while rand2 == rand1: rand2 = randint(0,len(cromossomos)-1) aux.append(rand1) aux.append(rand2) if acuracias[rand1] > acuracias[rand2]: melhor.append(cromossomos[rand1]) cromossomos[rand1] = 0 elif acuracias[rand2] > acuracias[rand1]: melhor.append(cromossomos[rand2]) cromossomos[rand2] = 0 return melhor, cromossomos #função que retorna o casal gerado a partir do torneio def generate_parents(melhores): duplas = [] usados = [] for i in range(int(len(melhores)/2)): aux = [] rand = randint(0, len(melhores)-1) if i == 0: aux.append(melhores[rand]) usados.append(rand) rand2 = randint(0,len(melhores)-1) while usados.__contains__(rand2): rand2 = randint(0,len(melhores)-1) aux.append(melhores[rand2]) usados.append(rand2) duplas.append(aux) elif i > 0: while usados.__contains__(rand): rand = randint(0,len(melhores)-1) aux.append(melhores[rand]) usados.append(rand) rand2 = randint(0,len(melhores)-1) while usados.__contains__(rand2): rand2 = randint(0,len(melhores)-1) aux.append(melhores[rand2]) usados.append(rand2) duplas.append(aux) return duplas #função que realiza o crossover entre os dois cromossomos #pais para a geração def crossover(taxa_crossover, parents): offspring = [] seed = random.uniform(0,1) if seed < taxa_crossover: cromo1_a = parents[0][:19] cromo1_b = parents[0][19:] cromo2_a = parents[1][:19] cromo2_b = parents[1][19:] offspring.append(cromo1_a+cromo2_b) offspring.append(cromo2_a+cromo1_b) elif seed > taxa_crossover or seed == taxa_crossover : offspring.append(parents[0].copy()) offspring.append(parents[1].copy()) return offspring # função que inverte os bits de uma posição # do cromossomo caso a seed seja superior à taxa de mutação def mutation(taxa_mutation, offsp_1): seed = 0 for i in range(0,len(offsp_1)): seed = random.uniform(0,1) if seed < taxa_mutation: if offsp_1[i] == 0: offsp_1[i] = 1 elif offsp_1[i] == 1: offsp_1[i] = 0 elif seed > taxa_mutation or seed == taxa_mutation: continue return offsp_1, # função que calcula os valores de média, moda , mediana e desvio padrão # para os vetores de acerto de um algoritmo, recebe como parâmetro o vetor # de acerto e o nome do algoritmo def tendencia_central (nomeAlgoritmo, vetorAcerto, vetorTempo): print('________________________________________________\n') print(nomeAlgoritmo) print('Tempo Média = ', np.mean(vetorTempo)) print('Tempo Desvio padrão = ', statistics.pstdev(vetorTempo)) print('Tempo Moda = ', stats.mode(vetorTempo, axis=None)) print('Tempo Mediana =', np.median(vetorTempo)) print('----------------------------------------------') print('Acurácia Média = ', np.mean(vetorAcerto)) print('Acurácia Desvio padrão = ', statistics.pstdev(vetorAcerto)) print('Acurácia Moda = ', stats.mode(vetorAcerto, axis=None)) print('Acurácia Mediana = ', np.median(vetorAcerto)) print('________________________________________________\n')