File size: 7,804 Bytes
e55a383
013cfcb
048cde5
1c1cecc
82584ce
 
1c1cecc
 
82584ce
c911131
2513f8d
827c678
145e509
e47c833
8aea8aa
82584ce
8f5f0a0
3d516f2
006eb0f
62cd834
 
 
 
 
6048174
4498193
145e509
013cfcb
145e509
013cfcb
145e509
 
 
 
 
 
 
5d0f943
81cd5d8
6c12543
a797ab0
827c678
7c0d9fe
 
827c678
7c0d9fe
827c678
7c0d9fe
827c678
441598c
827c678
 
5d0f943
d5b6e52
6fe7836
c6a7e8e
6fe7836
ad93b87
6048174
5eefcd1
145e509
efc2897
dfe2f9b
 
145e509
85f4560
a4b5bc7
4ebf5f9
c6a7e8e
4ebf5f9
efc2897
5569b6f
efc2897
d86334e
d5b6e52
 
a09b6b2
d5b6e52
09feba5
5569b6f
6048174
d5b6e52
d86334e
3dadf2c
984d39e
 
c6a7e8e
cabebbd
ad93b87
565a8fd
984d39e
c07ae99
efc2897
c07ae99
984d39e
 
82651a6
5eefcd1
c07ae99
efc2897
c07ae99
 
 
565a8fd
0389cde
984d39e
62cd834
 
6048174
62cd834
 
 
476569f
62cd834
5569b6f
d5e12e5
024cc00
399f80b
024cc00
6048174
735acad
6048174
35ac861
6048174
35ac861
6048174
35ac861
6048174
35ac861
6048174
35ac861
024cc00
8f5f0a0
1c1cecc
8f5f0a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ce86e8
594ba3c
 
c61771f
145e509
 
8f5f0a0
594ba3c
1ad5ab6
8f5f0a0
 
594ba3c
8f5f0a0
1c1cecc
82584ce
145e509
 
82584ce
145e509
 
 
 
082550e
e2b827c
9f3c91f
145e509
 
8f5f0a0
145e509
 
 
 
 
 
 
 
 
 
 
 
594ba3c
145e509
 
 
 
 
 
 
594ba3c
145e509
0bebc49
511bb57
24581a2
 
 
e3db7cb
c2e4aba
1c1cecc
048cde5
013cfcb
048cde5
e3db7cb
048cde5
 
efc2897
048cde5
145e509
048cde5
01ffe44
c51de2e
8145ff6
a94aa20
 
e2d0b27
ca12a1c
673b400
efc2897
d5b6e52
d86334e
 
f2e6ba0
f069c27
013cfcb
 
01ffe44
d79056b
62cd834
09feba5
ca12a1c
f54ac7d
6048174
87802d1
62cd834
95824d8
024cc00
0b7082a
95824d8
1c1b784
013cfcb
12401ab
95824d8
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
import gradio as gr
import pandas as pd
import os
from PIL import Image
from ultralytics import RTDETR
from ultralytics import SAM
import cv2 as cv
import numpy as np
import re

etiquetas_filtradas=[]
cuenta = []

#Modelo de detecci贸n de objetos RT-DETR
model = RTDETR('Modelo/rtdetr-l_proyecto.pt')

#Modelo de segmentaci贸n de objetos MobileSAM basado en SAM
model_SAM = SAM('Modelo/mobile_sam.pt')

# DataFrame inicial
data = {
    "Comidas": ["Desayuno", "Almuerzo", "Comida", "Merienda", "Cena"],
    "Total": [0, 0, 0, 0, 0]
}
resumen = pd.DataFrame(data)

def obtencion_etiquetas(result):

    object_count = {}

    #Obtenci贸n de las etiquetas y el n煤mero de veces que se han detectado en la imagen
    for box in result.boxes:
      object_label = result.names[box.cls[0].item()]
      if object_label in object_count:
          object_count[object_label] += 1
      else:
          object_count[object_label] = 1

    global etiquetas_filtradas, cuenta

    etiquetas_filtradas = []
    cuenta = []
        
    for label, count in object_count.items():
      # Obtiene la etiqueta correspondiente y la agrega a la lista
      etiquetas_filtradas.append(label)
      cuenta.append(count)
      print(f"{label}: {count}")      
    print('\n')
    print(etiquetas_filtradas)
    print('\n')
    print(cuenta)

def cargar_dataframe_1(eleccion):

    global etiquetas_filtradas, cuenta

    df = pd.read_csv('Dataset/Tabla_alimentos.csv')
    global nuevo_df, resumen
    
    nombre_primera_columna = df.columns[0]
    columnas_siguientes = df.columns[5:8]
    nuevo_df = df[[nombre_primera_columna] + list(columnas_siguientes)]

    # Filtrar las filas que corresponden a los nombres dados
    nuevo_df = nuevo_df[nuevo_df[nombre_primera_columna].isin(etiquetas_filtradas)]

    # Add a new column "Uds" with the values from contador
    nuevo_df['Uds'] = cuenta

    # Obtener las kcal multiplicadas por la cantidad correspondiente en la columna de Uds
    nuevo_df['Kcal'] = round(nuevo_df['Uds'] * nuevo_df['Kcal'],2)
    
    version2 = cargar_dataframe_2()
    suma = 0.0
    # Utilizar un bucle for para sumar todas las filas de la columna
    for valor in nuevo_df['Kcal']:
        suma += float(valor)
        
    suma = round(suma, 2)
    mod_resumen_dataframe(eleccion, suma)
    
    return nuevo_df, f"{suma} kcal", version2
    
def cargar_dataframe_2():

    global etiquetas_filtradas, cuenta
    
    df = pd.read_csv('Dataset/Tabla_alimentos.csv')
    
    nombre_primera_columna = df.columns[0]
    nombre_segunda_columna = df.columns[6]
    columnas_siguientes = df.columns[8:11]
    nuevo_df = df[[nombre_primera_columna] + [nombre_segunda_columna] + list(columnas_siguientes)]

    # Filtrar las filas que corresponden a los nombres dados
    nuevo_df = nuevo_df[nuevo_df[nombre_primera_columna].isin(etiquetas_filtradas)]
    
    nuevo_df['Uds'] = cuenta

    nuevo_df['Grasas'] = round(nuevo_df['Uds'] * nuevo_df['Grasas'],2)
    nuevo_df['Carbh'] = round(nuevo_df['Uds'] * nuevo_df['Carbh'],2)
    nuevo_df['Prot'] = round(nuevo_df['Uds'] * nuevo_df['Prot'],2)
    
    return nuevo_df

def cargar_dataframe_resumen(eleccion):

    global resumen
    
    suma = 0.0
    # Utilizar un bucle for para sumar todas las filas de la columna
    for valor in resumen['Total']:
        suma += float(valor)
    suma = round(suma, 2)
    return resumen, f"{suma} kcal"

def mod_resumen_dataframe(eleccion, suma):

    global resumen

    if(eleccion == "Desayuno"):
        resumen["Total"][0] = suma
    elif (eleccion == "Almuerzo"):
        resumen["Total"][1] = suma
    elif (eleccion == "Comida"):
        resumen["Total"][2] = suma
    elif (eleccion == "Merienda"):
        resumen["Total"][3] = suma
    elif (eleccion == "Cena"):
        resumen["Total"][4] = suma
    
def umbralizar_imagen(imagen, umbral):

  # Obtener la imagen original
  ancho, alto, canales = imagen.shape

  # Definir la imagen de salida
  imagen_umbralizada = np.zeros((ancho, alto, canales), dtype=np.uint8)

  # Recorrer la imagen, pixel por pixel
  for x in range(ancho):
    for y in range(alto):
      # Obtener el brillo del pixel
      brillo = imagen[x, y]

      # Si todos los canales del pixel tienen un brillo mayor o igual al umbral, copiarlo a la imagen de salida
      if np.any(brillo >= umbral):
        imagen_umbralizada[x, y] = imagen[x, y]

  return imagen_umbralizada
    
def image_mod(Original):
    ancho, alto = Original.size
    Original = Original.resize((640, 640))
    results = model(Original)  # results list
    
    result = results[0]

    Original = np.array(Original)

    #Baja el brillo de la imagen para mejorar la umbralizaci贸n
    factor_brillo = 0.23
    img_oscura = np.clip(Original * factor_brillo, 0, 255).astype(np.uint8)
    
    for r  in results:
        boxes = r.boxes.xyxy
        
    if boxes is not None and len(boxes) > 0:

        results_SAM = model_SAM(img_oscura, bboxes = boxes)
    
        for x in results_SAM:
            mascara_objeto = x.plot() 
        
        obtencion_etiquetas(result)
        
        # Definir el umbral de brillo
        umbral = 60
    
        # Umbralizar la imagen para extraer solo las m谩scaras de los objetos
        imagen_umbralizada = umbralizar_imagen(mascara_objeto, umbral)
    
        # Convertir la imagen a escala de grises
        img_gris = cv.cvtColor(imagen_umbralizada, cv.COLOR_BGR2GRAY)
    
        # Aplicar umbralizaci贸n de Otsu
        _, th = cv.threshold(img_gris, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
    
        #Bajar el brillo de la imagen para que destaquen m谩s las m谩scaras de los 
        #objetos segmentados
        factor_brillo = 0.55
        img_mod = np.clip(Original * factor_brillo, 0, 255).astype(np.uint8)
        
        # Hacer la capa blanca m谩s transparente y combinar la imagen con las m谩scaras
        alpha = 0.4
        img_resultante = cv.addWeighted(img_mod, 1 - alpha, cv.cvtColor(th, cv.COLOR_GRAY2BGR), alpha, 0)
    
    else:
        factor_brillo = 0.55
        img_resultante = np.clip(Original * factor_brillo, 0, 255).astype(np.uint8)
        
    img_resultante = cv.cvtColor(img_resultante, cv.COLOR_BGR2RGB)

    image_with_predictions  = Image.fromarray(img_resultante[..., ::-1])  # RGB PIL image

    image_with_predictions = image_with_predictions.resize((ancho, alto))

    return image_with_predictions 


Imagen = gr.Interface(
    image_mod,
    gr.Image(type="pil"),
    "image",
    examples=[
        #os.path.join(os.path.abspath(''), "Demo_web/1.jpg"),
    ],
    description = "Detecci贸n y segmentaci贸n de los alimentos de la imagen aportada por el usuario.",
)

Tabla1 = gr.Interface(
    fn= cargar_dataframe_1,
    inputs = gr.Dropdown(
        ["Desayuno", "Almuerzo", "Comida", "Merienda", "Cena"], label="Comida", info="Comida del d铆a"
    ),
    live=True,
    outputs=[gr.Dataframe(
            headers=["Alimento", "Raci贸n(g)", "Uds", "Kcal"],
            label="Resumen alimenticio",
    ), gr.Textbox(label="Total kcal"), 
    gr.Dataframe(
            headers=["Alimento", "Grasas", "Carbh", "Prot"],
            label="M谩s detalles")],
    description="Desglose de los alimentos y sus calor铆as, as铆 como recuento total.",
)

Tabla2 = gr.Interface(
    fn=cargar_dataframe_resumen,
    inputs = gr.Textbox(visible=False,label="Actualizar"),
    live=True,
    outputs=[gr.Dataframe(
            resumen,
            label="Resumen alimenticio"
    ), gr.Textbox(label="Total kcal del d铆a")],
    description="Resumen del las kcal ingeridas durante el d铆a.",
)

demo = gr.TabbedInterface([Imagen, Tabla1, Tabla2], ["Inicio", "Detalles", "Diario"], 
                          title = "Detecci贸n de alimentos", theme='gradio/soft')

if __name__ == "__main__": 
    demo.launch()