kebincontreras commited on
Commit
f993b97
·
verified ·
1 Parent(s): 54cfa97

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -0
app.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image
3
+ import numpy as np
4
+ from scipy.ndimage import label, find_objects
5
+
6
+ # Función para generar la máscara
7
+ def generate_mask(image):
8
+ # Convertir la entrada en un objeto PIL.Image si no lo es
9
+ if isinstance(image, np.ndarray):
10
+ image = Image.fromarray(image)
11
+
12
+ # Convertir la imagen a RGB y array de numpy
13
+ image_rgb = image.convert("RGB")
14
+ np_image = np.array(image_rgb)
15
+
16
+ # Aplicar los límites RGB basados en los análisis anteriores
17
+ min_red, max_red = 21, 183
18
+ min_green, max_green = 0, 142
19
+ min_blue, max_blue = 0, 124
20
+
21
+ # Generar la máscara binaria
22
+ mask = (
23
+ (np_image[:, :, 0] >= min_red) & (np_image[:, :, 0] <= max_red) &
24
+ (np_image[:, :, 1] >= min_green) & (np_image[:, :, 1] <= max_green) &
25
+ (np_image[:, :, 2] >= min_blue) & (np_image[:, :, 2] <= max_blue)
26
+ ).astype(np.uint8)
27
+
28
+ # Invertir la máscara para que los objetos de fondo (valor 0) se conviertan en 1 y se etiqueten
29
+ inverted_mask = 1 - mask
30
+ labeled_mask, num_features = label(inverted_mask)
31
+
32
+ # Filtrar objetos pequeños de valor 0
33
+ for i, region in enumerate(find_objects(labeled_mask)):
34
+ if region is not None:
35
+ # Calcular el área del objeto con valor 0
36
+ area = np.sum(labeled_mask[region] == i + 1)
37
+ # Si el área es menor a 3000 píxeles, establece el objeto en blanco
38
+ if area < 3000:
39
+ inverted_mask[region] = np.where(labeled_mask[region] == i + 1, 0, inverted_mask[region])
40
+
41
+ # Invertir de nuevo para restaurar los valores de la máscara original
42
+ filtered_mask = 1 - inverted_mask
43
+
44
+ # Convertir la máscara modificada a una imagen en blanco y negro
45
+ mask_image = Image.fromarray((filtered_mask * 255).astype(np.uint8))
46
+
47
+ return mask_image
48
+
49
+ # Crear la interfaz con ejemplos
50
+ examples = [["cacao_1.png"], ["cacao_2.jpg"]] # Asegúrate de que estos archivos estén en la misma carpeta que el script
51
+
52
+ # CSS personalizado para la interfaz
53
+ css = """
54
+ .app-container { background-color: white; }
55
+ .title-container {
56
+ background-color: white;
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ height: 300px;
61
+ font-size: 24px;
62
+ font-weight: bold;
63
+ text-align: center;
64
+ }
65
+ .centered-image {
66
+ display: block;
67
+ margin: auto;
68
+ }
69
+ """
70
+
71
+ # Configuración de la interfaz con elementos adicionales
72
+ with gr.Blocks(css=css) as demo:
73
+ # Logo y título en la parte superior
74
+ with gr.Row():
75
+ gr.Image(value="Cacaotin.png", width=300, height=300, elem_id="centered-image")
76
+ gr.Markdown("<div class='title-container'>Fermentation Level Classification for Cocoa Beans</div>")
77
+
78
+ # Botón de GitHub centrado
79
+ gr.Markdown("<center><a href='https://github.com/kebincontreras/cocoa_beans_interfaces' target='_blank'><button style='background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 5px; font-size: 16px;'>View on GitHub</button></a></center>")
80
+
81
+ # Fila para cargar la imagen y mostrar la salida procesada
82
+ with gr.Row():
83
+ img_input = gr.Image(label="Upload Image")
84
+ img_output = gr.Image(label="Image with Generated Mask")
85
+
86
+ # Botón para generar la máscara
87
+ btn_classify = gr.Button("Generate Mask for Fermentation Level")
88
+ btn_classify.click(generate_mask, inputs=img_input, outputs=img_output)
89
+
90
+ # Añadir las imágenes de ejemplo
91
+ gr.Examples(
92
+ examples=examples,
93
+ inputs=img_input,
94
+ label="Example Images"
95
+ )
96
+
97
+ # Descripción de las clases de cacao
98
+ gr.Markdown("""
99
+ **Cacao Classes According to NTC1252:2021:**
100
+ - **a) Well-fermented:** Optimal fermentation process.
101
+ - **b) Partially fermented:** Incomplete fermentation process.
102
+ - **c) Non-fermented:** Lack of adequate fermentation.
103
+ """)
104
+ gr.Image(value="cacao.png", label="a) Well-fermented, b) Partially fermented, c) Non-fermented")
105
+
106
+ # Explicación final según la norma
107
+ gr.Markdown("**Explanation According to NTC1252:2021:** Here you can explain how the NTC1252:2021 norm applies to the classification of fermentation levels.")
108
+
109
+ # Ejecutar la aplicación
110
+ if __name__ == "__main__":
111
+ demo.launch()