coder commited on
Commit
4b3b02a
1 Parent(s): 11a6d17

first commit

Browse files
Home.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from core.controllers.pages_controller import Page
2
+ from core.controllers.main_process import Generador
3
+
4
+
5
+ class Home(Page):
6
+ variables_globales = {
7
+ "img_bytes": None,
8
+ "img_src": None,
9
+ "settings": {
10
+ "model": str("facebook/detr-resnet-50"),
11
+ "tokenizer": str("facebook/detr-resnet-50"),
12
+ },
13
+ "img_output": None,
14
+ "predicciones": None,
15
+ "fuentes": [
16
+ {"titulo": "Papper",
17
+ "url": "https://arxiv.org/abs/2005.12872"},
18
+ {"titulo": "Transformers",
19
+ "url": "https://huggingface.co/docs/transformers/v4.32.1/en/index"},
20
+ {"titulo": "Modelo FaceBook/DETR-ResNet-50",
21
+ "url": "https://huggingface.co/facebook/detr-resnet-50"},
22
+ {"titulo": "Repositorio",
23
+ "url": "https://github.com/facebookresearch/detr"},
24
+ {"titulo": "PIL",
25
+ "url": "https://pypi.org/project/Pillow/"},
26
+ {"titulo": "requests",
27
+ "url": "https://pypi.org/project/requests/"},
28
+ {"titulo": "timm",
29
+ "url": "https://pypi.org/project/timm/"}]
30
+ }
31
+
32
+ archivos_css = ["main",
33
+ "home"]
34
+
35
+ def __init__(self, title=str("Bienvenido"), icon=str("🖼️"), init_page=False):
36
+ super().__init__()
37
+ if init_page:
38
+ self.new_page(title=title,
39
+ icon=icon)
40
+ self.init_globals(globals=self.variables_globales)
41
+ for archivo in self.archivos_css:
42
+ self.cargar_css(archivo_css=archivo)
43
+ self.about()
44
+
45
+ def about(self):
46
+ self.builder().sidebar.markdown(unsafe_allow_html=False,
47
+ help=None,
48
+ body="""
49
+ ## Tema
50
+
51
+ La detección de objetos es una tarea fundamental en la Visión Artificial que implica identificar y localizar objetos específicos en una imagen o en una secuencia de video.
52
+
53
+ Se basa en algoritmos y modelos que analizan características visuales, como bordes, colores y texturas, para identificar objetos y sus ubicaciones en la imagen.
54
+
55
+ La detección de objetos es esencial en aplicaciones como la conducción autónoma, la vigilancia, la automatización industrial y la realidad aumentada.
56
+
57
+ ## Recursos
58
+ """)
59
+
60
+ for fuente in self.get_global('fuentes'):
61
+ self.builder().sidebar.markdown(
62
+ unsafe_allow_html=False,
63
+ help=None,
64
+ body=f"""
65
+ * **{fuente.get('titulo')}** - {fuente.get('url')}
66
+ """
67
+ )
68
+ self.builder().sidebar.markdown(
69
+ unsafe_allow_html=False,
70
+ help=None,
71
+ body="""
72
+ ###### Es **importante** mencionar que esta **compilación** se encuentra en proceso de **construcción**.
73
+
74
+ *Si deseas **participar**, eres **bienvenido** de aportar en el repositorio oficial:*
75
+
76
+ https://github.com/coder160/cuadernos/
77
+ """)
78
+
79
+ def obtener_bytes(self, archivo):
80
+ self.set_global(key='img_src',
81
+ value=archivo)
82
+
83
+ def actualizar_modelo_tokenizer(self, modelo, tokenizer):
84
+ self.set_global(key='settings',
85
+ value={'model': modelo,
86
+ 'tokenizer': tokenizer})
87
+
88
+ def procesar_imagen(self):
89
+ proceso = Generador(configuraciones=self.get_global('settings'))
90
+ proceso.generar_prediccion(imagen_bytes=self.imgg.open(
91
+ self.get_global('img_src')).convert("RGB"))
92
+ self.set_global(key='predicciones', value=proceso.prediccion)
93
+
94
+ def expander_instrucciones(self, placeholder):
95
+ instrucciones = placeholder.expander(expanded=False,
96
+ label="Instrucciones")
97
+ instrucciones.markdown(unsafe_allow_html=False,
98
+ help=None,
99
+ body="""
100
+ 1. **Cargue su Imagen Base**:
101
+
102
+ Elija cualquiera de las dos opciones para cargar su imagen:
103
+
104
+ * **Desde su Galería**: cargue la imagen desde la galería de su teléfono o computadora.
105
+
106
+ * **Desde su Cámara**: cargue la imagen directamente desde la cámara de su teléfono o computadora.
107
+
108
+
109
+ 2. **Detectar / Predecir**:
110
+
111
+ Realice la **detección de objetos** con base a las predicciones realizadas por el **modelo** pre-entrenado seleccionado.
112
+
113
+ A partir del dataset con el que fue pre-entrenado el modelo, tratará de predecir cuales son los objetos en la imagen cargada.
114
+
115
+
116
+ * **Configuraciones Avanzadas**:
117
+
118
+ *Elija un modelo y procesador de la lista disponible, o elija uno directamente de la base de modelos disponible en HuggingFace.*
119
+ """)
120
+
121
+ def expander_imagen_base(self, placeholder):
122
+ imagen_base = placeholder.container()
123
+ imagen_base.markdown(unsafe_allow_html=False,
124
+ help=None,
125
+ body="""
126
+ **Cargue su Imagen Base**:
127
+ """)
128
+ archivo_expander = imagen_base.expander(expanded=False,
129
+ label="Desde su Galería")
130
+ _archivo = archivo_expander.file_uploader(label="Galería",
131
+ on_change=None,
132
+ accept_multiple_files=False,
133
+ label_visibility="visible")
134
+ if (archivo_expander.button(label="Cargar Archivo", type="secondary", use_container_width=True,
135
+ help="Suba un archivo.") and _archivo is not None):
136
+ self.obtener_bytes(_archivo)
137
+
138
+ camara_expander = imagen_base.expander(expanded=False,
139
+ label="Desde su Cámara")
140
+ _captura = camara_expander.camera_input(label="Cámara",
141
+ on_change=None,
142
+ label_visibility="visible")
143
+ if (camara_expander.button(label="Cargar Captura", type="secondary", use_container_width=True,
144
+ help="Tome una fotografía.") and _captura is not None):
145
+ self.obtener_bytes(_captura)
146
+
147
+ def expander_configuraciones(self, placeholder):
148
+ configuraciones = placeholder.expander(
149
+ expanded=False, label="Configuraciones Avanzadas")
150
+ modelo = configuraciones.text_input(
151
+ label="MODELO", on_change=None, label_visibility="visible",
152
+ value=self.get_global('settings').get('model'))
153
+ tokenizer = configuraciones.text_input(
154
+ label="TOKENIZER", on_change=None, label_visibility="visible",
155
+ value=self.get_global('settings').get('tokenizer'))
156
+
157
+ if configuraciones.button(label="Configurar", type="secondary", use_container_width=True,
158
+ help="Actualice configuraciones"):
159
+ self.actualizar_modelo_tokenizer(modelo, tokenizer)
160
+
161
+ def resultados(self, placeholder):
162
+ resultados = placeholder.container()
163
+
164
+ if self.get_global('img_src', None) is not None:
165
+ resultados.image(
166
+ image=self.get_global('img_src').getvalue(),
167
+ caption="Su resultado",
168
+ use_column_width="auto",
169
+ channels="RGB",
170
+ output_format="auto"
171
+ )
172
+ if self.get_global('predicciones', None) is not None:
173
+ resultados.success(body=self.get_global(
174
+ 'predicciones'), icon=None)
175
+
176
+ def agregar_card_base(self, columna):
177
+ card_principal = columna.container()
178
+
179
+ columna_inputs, columna_outputs = card_principal.columns(
180
+ [0.3, 0.7], gap="small")
181
+
182
+ self.expander_instrucciones(columna_inputs)
183
+ self.expander_imagen_base(columna_inputs)
184
+ self.expander_configuraciones(columna_inputs)
185
+ if columna_inputs.button(label="Detectar / Predecir", help="Realizar Predicciones",
186
+ type="secondary", use_container_width=True):
187
+ self.procesar_imagen()
188
+ self.resultados(columna_outputs)
189
+
190
+ def build(self):
191
+
192
+ columna_principal = self.get_body().columns(1, gap="small")[0]
193
+ self.agregar_card_base(columna_principal)
194
+
195
+
196
+ if __name__ == "__main__":
197
+ Home(init_page=True).build()
core/controllers/main_process.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import DetrImageProcessor, DetrForObjectDetection
2
+ from io import BytesIO
3
+ from PIL import Image
4
+ import requests
5
+ import torch
6
+
7
+
8
+ class Generador():
9
+ def __init__(self, configuraciones):
10
+ self.modelo = configuraciones.get('model')
11
+ self.tokenizer = configuraciones.get('tokenizer')
12
+
13
+ def generar_prediccion(self, imagen_bytes):
14
+ # @title **Ejemplo práctico**
15
+ prediccion = str()
16
+ try:
17
+ # Inicializamos los procesadores y el modelo
18
+ procesador = DetrImageProcessor.from_pretrained(self.tokenizer)
19
+ modelo = DetrForObjectDetection.from_pretrained(self.modelo)
20
+ # Procesamos nuestra imagen y objetos
21
+ inputs = procesador(images=imagen_bytes, return_tensors="pt")
22
+ outputs = modelo(**inputs)
23
+ objetos = torch.tensor([imagen_bytes.size[::-1]])
24
+ # filtramos objetos con probabilidad mayor al 90%
25
+ resultados = procesador.post_process_object_detection(
26
+ outputs, target_sizes=objetos, threshold=0.9)[0]
27
+ # imprimimos cada resultado con su probabilidad
28
+ for probabilidad, etiqueta, ubicacion in zip(resultados["scores"], resultados["labels"], resultados["boxes"]):
29
+ ubicacion = [round(i, 2) for i in ubicacion.tolist()]
30
+ _text = f"Encontrado:\t {modelo.config.id2label[etiqueta.item()]}\nProbabilidad: {round(probabilidad.item(), 3)} en ubicación: {ubicacion}."
31
+ prediccion = prediccion + _text
32
+
33
+ except Exception as error:
34
+ print(f"No es Chems\n{error}")
35
+ prediccion = str(error)
36
+ finally:
37
+ self.prediccion = prediccion
core/controllers/pages_controller.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as BaseBuilder
2
+ from PIL import Image
3
+ import json
4
+
5
+
6
+ class Page():
7
+ def __init__(self):
8
+ self.__ = BaseBuilder
9
+ self.imgg = Image
10
+
11
+ def builder(self):
12
+ return self.__
13
+
14
+ def new_page(self, title: str, icon=str(), color_divider="rainbow"):
15
+ self.builder().set_page_config(page_title=title,
16
+ page_icon=icon,
17
+ layout="wide")
18
+ self.builder().title(f"Clasificación de imágenes con Visión Artificial",
19
+ anchor="titulo-proyecto",
20
+ help=None)
21
+ self.builder().subheader(f"{title} {icon}",
22
+ anchor="titulo-pagina",
23
+ divider=color_divider,
24
+ help=None)
25
+ self.__body = self.builder().empty()
26
+
27
+ def get_body(self):
28
+ return self.__body
29
+
30
+ def init_globals(self, globals=dict({})):
31
+ for _k, _v in globals.items():
32
+ if self.get_global(_k, None) is None:
33
+ self.set_global(_k, _v)
34
+
35
+ def set_global(self, key=str(), value=None):
36
+ self.builder().session_state[key] = value
37
+
38
+ def get_global(self, key=str(), default=None, is_secret=False):
39
+ if is_secret:
40
+ return self.builder().secrets.get(key, default)
41
+ else:
42
+ return self.builder().session_state.get(key, default)
43
+
44
+ def cargar_css(self, archivo_css=str("default")):
45
+ ruta = f"core/estilos/{archivo_css}.css"
46
+ try:
47
+ with open(ruta) as archivo:
48
+ self.builder().markdown(
49
+ f'<style>{archivo.read()}</style>', unsafe_allow_html=True)
50
+ except Exception as er:
51
+ print(f"Error:\n{er}")
core/estilos/home.css ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Estilo Cards */
2
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"] {
3
+ background-color: #070707;
4
+ box-shadow: 1px 1px 2px 2px #000000d2;
5
+ box-sizing: border-box;
6
+ padding: 4px 0px 20px 0px;
7
+ border-radius: 14px;
8
+ backdrop-filter: blur(4px);
9
+ transition: ease-out;
10
+ transition-property: background-color box-shadow transition;
11
+ transition-duration: 88ms;
12
+ }
13
+
14
+ /* Estilo Cards:Hover*/
15
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]:hover {
16
+ border: 2px thin;
17
+ box-shadow: 2px 2px 3px 3px #000000fe;
18
+ transition: ease-in;
19
+ transition-property: box-shadow transition;
20
+ transition-duration: 110ms;
21
+ }
22
+
23
+
24
+ /* Interno Card: Titulo */
25
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="element-container"]>.stHeadingContainer {
26
+ text-align: center;
27
+ align-self: center;
28
+ }
29
+
30
+ /* Interno Card: Texto */
31
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="element-container"]>.stTextLabelWrapper>[data-testid="stText"] {
32
+ padding: 0px 8px 0px 8px;
33
+ color: white;
34
+ }
35
+
36
+ /* Interno Card: Markup */
37
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="element-container"]>.stMarkdown>[data-testid="stMarkdownContainer"] {
38
+ padding: 0px 8px 0px 8px;
39
+ color: white;
40
+ }
41
+
42
+ /* Interno Card: Row imagenes */
43
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="stHorizontalBlock"] {
44
+ padding: 0px 8px 0px 8px;
45
+ display: flex;
46
+ }
47
+
48
+ /* Interno Card: Imágenes */
49
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="stHorizontalBlock"]>[data-testid="column"] {
50
+ display: flex;
51
+ justify-content: center;
52
+ align-items: center;
53
+ }
54
+
55
+ /* Interno Card: Botones */
56
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="element-container"]>[data-testid="stButton"]>.stTooltipIcon>div>[data-testid="stTooltipIcon"]>[data-testid="tooltipHoverTarget"]>button {
57
+ padding: 8px;
58
+ display: flex;
59
+ justify-content: center;
60
+ text-align: center;
61
+ width: 100%;
62
+ background-color: crimson;
63
+ color: white;
64
+ }
65
+
66
+
67
+ /* Interno Card: Expander */
68
+ [data-testid="stVerticalBlock"]>[style*="flex-direction: column;"]>[data-testid="stVerticalBlock"]>[data-testid="stExpander"]>ul {
69
+ background-color: transparent;
70
+ box-shadow: none;
71
+ border: none;
72
+ }
73
+
74
+ .st-by {
75
+ color: white !important;
76
+ }
core/estilos/main.css ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ /* Contenedor principal de la aplicación*/
2
+ section>[data-testid="block-container"]{
3
+ height: 100vh;
4
+ }
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ transformers
4
+ transformers[torch]
5
+ transformers[tf-cpu]
6
+ transformers[flax]
7
+ Pillow
8
+ requests
9
+ timm