-
Notifications
You must be signed in to change notification settings - Fork 0
/
clase_05_10_optuna.py
174 lines (133 loc) · 5.46 KB
/
clase_05_10_optuna.py
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
"""
Universidad Adolfo Ibañez
Facultad de Ingeniería y Ciencias
TICS 585 - Reconocimiento de Patrones en imágenes
Aplicación del algoritmo OPTUNA
Autor:. Miguel Carrasco (04-08-2021)
rev.1.0
"""
import cv2
from skimage.feature import graycomatrix, graycoprops
import numpy as np
from math import radians
from sklearn import preprocessing
from skimage.io import imread_collection
import pandas as pd
import matplotlib.pyplot as plt
from itertools import combinations
from math import pi
from numpy.matlib import repmat
from numpy.linalg import inv
import optuna
def objective(trial):
level = trial.suggest_int("level", 4, 60)
no_cols = 3
df = feature_extraction(level)
# no empleamos la ultima columna ya que en ella está la clase
cols = df.shape[1] -1 #numero de columnas
col_features = df.columns
# numero de clases
clases = len(df['clase'].unique())
#% combinaciones caracteristicas
combs = np.array(list(combinations(np.arange(cols),no_cols))).reshape(-1,no_cols)
J = []
for i in range(len(combs)):
a = combs[i]
sub_data = []
for k in range(1,clases+1):
#%Seleccionamos las caracteristicas
id_class= df['clase']==k
tmp = df[id_class]
sub_data.append(tmp[col_features[a]].to_numpy())
# Determinamos el indice de Fisher para dichas columnas
J.append(fisher_extraction_list(sub_data,clases))
out_value = np.max(J)
id_best_comb = np.argmax(J)
#print(combs[id_best_comb])
#retornamos dos valores
return out_value
def fisher_extraction_list(data, clases):
# función calcula el índice de Fisher para un determinado
# conjunto de datos.
# Input: data: lista con submatrices (una por cada clase)
# clases: lista con valores de las clases.
# unimos los datos en una sola matriz
D = np.vstack(data)
# Buscamos la media de todos los datos
Vm = np.mean(D, axis =0)
# numero de columnas
cols = D.shape[1]
# inicializacion de matrices
p = np.zeros((clases,1))
Vk = np.zeros((clases,cols))
Gn = []
# Centrado
for i in range(clases):
Vk[i,:] = np.mean(data[i], axis=0)-Vm # centramos las medias de cada clase
pts = data[i].shape[0] # numero de puntos de ese clase
Gn.append(data[i]-repmat(Vm,pts,1)) # centramos los puntos de cada clase
p[i] = data[i].shape[0] /len(D) # probabilidad de cada cluster
# Inicialización
Cb = np.zeros((cols,cols))
Cw = np.zeros((cols,cols))
# construccion de matrices inter e intraclase
for k in range(clases):
Cb = Cb + p[k]*np.matmul((Vk[k,:]-Vm).reshape(cols,1), (Vk[k,:]-Vm).reshape(1,cols))
MGn = np.array(Gn[k])
Cw = Cw + p[k]*np.cov(MGn.T)
#Calculamos el índice de Fisher
J = np.trace(np.matmul(inv(Cw),Cb))
return J
def feature_extraction(level):
# funcion utiliza el algoritmo de extracción de
# características de haralick
# Input: level: numero de niveles de matriz de salida que utiliza Haralick
#caracteristicas de matriz de textura
features = ['contrast','correlation', 'dissimilarity','homogeneity','ASM','energy']
#clases de las imagenes (clasificación supervisada)
clase = np.array([1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 3, 3, 3, 3, 3])
# leemos todas las imagenes que cumplan el siguiente formato
col_dir = 'texturas_fisher/textura*.tif'
col = imread_collection(col_dir) #coleccion de imágenes
col_files = col.files
# vamos a almacenar en la matriz F todos los descriptores
F = []
# >> recorremos la lista de archivos
for i,filename in enumerate(col_files):
# lectura de la imagen en formato .tif
img = cv2.imread(filename)
# convertimos la imagen a escala de grises
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_column = gray.reshape(-1,1) #la definimos como columna
# Escalamos los datos en una matriz con menos valores
new_scale = (0,level)
new_gray = preprocessing.MinMaxScaler(new_scale).fit_transform(gray_column).astype(int)
# redimensionamos la imagen
new_gray = new_gray.reshape(gray.shape)
# --> algoritmo graycomatrix P01
# numero de niveles de la imagenq
l = np.max(new_gray)+1
P_1_0 = graycomatrix(new_gray, distances=[2], angles=[radians(90)], levels=l, symmetric=False, normed=True)
# extracción de caracteristicas a traves de greycomatrix
S = []
# para cada imagen extraemos las caracteristicas definidas en la lista features
for ft in features:
sts = graycoprops(P_1_0, ft).squeeze()
S.append(float(sts))
#agregamos los características en la matriz F
F.append(S)
# >> FIN ciclo para cada imagen de textura
# almacenamos los datos en un dataframe
df = pd.DataFrame(F, columns=features, index=col_files)
df['clase'] = clase
return df
#*********************************
# PROGRAMA PRINCIPAL SBS *
#*********************************
colores = {1:'red', 2:'blue', 3:'green'}
sel_features = 3 # numero de características seleccionadas
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100, show_progress_bar=True)
best_params = study.best_params
found_level = best_params["level"]
print(f'best level {found_level}')