kebincontreras/Fermentation_Level_Classification_for_Cocoa_Beans
0
1import gradio as gr2from PIL import Image3import numpy as np4from scipy.ndimage import label, find_objects5 6# Función para generar la máscara7def generate_mask(image):8 # Convertir la entrada en un objeto PIL.Image si no lo es9 if isinstance(image, np.ndarray):10 image = Image.fromarray(image)11 12 # Convertir la imagen a RGB y array de numpy13 image_rgb = image.convert("RGB")14 np_image = np.array(image_rgb)15 16 # Aplicar los límites RGB basados en los análisis anteriores17 min_red, max_red = 21, 18318 min_green, max_green = 0, 14219 min_blue, max_blue = 0, 12420 21 # Generar la máscara binaria22 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 etiqueten29 inverted_mask = 1 - mask30 labeled_mask, num_features = label(inverted_mask)31 32 # Filtrar objetos pequeños de valor 033 for i, region in enumerate(find_objects(labeled_mask)):34 if region is not None:35 # Calcular el área del objeto con valor 036 area = np.sum(labeled_mask[region] == i + 1)37 # Si el área es menor a 3000 píxeles, establece el objeto en blanco38 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 original42 filtered_mask = 1 - inverted_mask43 44 # Convertir la máscara modificada a una imagen en blanco y negro45 mask_image = Image.fromarray((filtered_mask * 255).astype(np.uint8))46 47 return mask_image48 49# Crear la interfaz con ejemplos50examples = [["cacao_1.png"], ["cacao_2.jpg"]] # Asegúrate de que estos archivos estén en la misma carpeta que el script51 52# CSS personalizado para la interfaz53css = """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 adicionales72with gr.Blocks(css=css) as demo:73 # Logo y título en la parte superior74 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 centrado79 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 procesada82 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áscara87 btn_classify = gr.Button("Generate Mask for Fermentation Level")88 btn_classify.click(generate_mask, inputs=img_input, outputs=img_output)89 90 # Descripción de las clases de cacao91 gr.Markdown("""92 **Cacao Classes According to NTC1252:2021:**93 - **a) Well-fermented:** Optimal fermentation process.94 - **b) Partially fermented:** Incomplete fermentation process.95 - **c) Non-fermented:** Lack of adequate fermentation.96 """)97 gr.Image(value="cacao.png", label="a) Well-fermented, b) Partially fermented, c) Non-fermented")98 99 # Explicación final según la norma100 gr.Markdown("**Explanation According to NTC1252:2021:** Here you can explain how the NTC1252:2021 norm applies to the classification of fermentation levels.")101 102# Ejecutar la aplicación103if __name__ == "__main__":104 demo.launch()105 