RaulHuarote commited on
Commit
0a7b66b
verified
1 Parent(s): 8c10da8

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +16 -0
  2. app.py +184 -0
  3. haarcascade_frontalface_default.xml +0 -0
  4. requirements.txt +6 -0
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Usa una imagen base de Python
2
+ FROM python:3.12.7
3
+ # Establece el directorio de trabajo
4
+ WORKDIR /code
5
+
6
+ # Copia los archivos necesarios al contenedor
7
+ COPY ./requirements.txt /code/requirements.txt
8
+ RUN pip install --no-cache-dir -r /code/requirements.txt
9
+ RUN pip install fastapi uvicorn
10
+
11
+ COPY . .
12
+
13
+ RUN chmod -R 777 /code
14
+
15
+ # Comando para ejecutar la aplicaci贸n
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, HTTPException
2
+ from fastapi.responses import HTMLResponse
3
+ from pydantic import BaseModel
4
+ from typing import List
5
+ import cv2
6
+ import numpy as np
7
+
8
+ app = FastAPI()
9
+
10
+ def buscar_existe(image):
11
+ existe = "no"
12
+ face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
13
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
14
+ faces = face_cascade.detectMultiScale(gray, 1.3,5,minSize=(30, 30))
15
+ for (x,y,w,h) in faces:
16
+ existe = "si"
17
+ break
18
+ return existe
19
+
20
+ # Ruta para la p谩gina principal con formulario HTML
21
+ @app.get('/')
22
+ async def main():
23
+ content = """
24
+ <html>
25
+ <head>
26
+ <title>RECONOCIMIENTO FACIAL</title>
27
+ <style>
28
+ body {
29
+ font-family: Arial, sans-serif;
30
+ display: flex;
31
+ justify-content: center;
32
+ align-items: center;
33
+ height: 100vh;
34
+ margin: 0;
35
+ background-image: url('static/Background.png'); /* Reemplaza con la ruta de tu imagen */
36
+ background-size: cover; /* Ajusta el tama帽o para cubrir todo el cuerpo */
37
+ background-position: center; /* Centra la imagen en el cuerpo */
38
+ background-repeat: no-repeat; /* Evita que la imagen se repita */
39
+ }
40
+ .container {
41
+ position: relative;
42
+ padding: 20px;
43
+ border-radius: 10px;
44
+ box-shadow: 0px 0px 10px rgba(247, 15, 15, 0.808);
45
+ text-align: center;
46
+ }
47
+ .overlay{
48
+ position: absolute;
49
+ top: 0;
50
+ left: 0;
51
+ width: 100%;
52
+ height: 100%;
53
+ background-color: rgba(0, 0, 0, 0); /* Capa de opacidad */
54
+ border-radius: 10px;
55
+ }
56
+ .content {
57
+ position: relative;
58
+ z-index: 1;
59
+ }
60
+ .content h1 {
61
+ margin-bottom: 20px;
62
+ }
63
+ .custom-file-input {
64
+ display: none;
65
+ }
66
+ .file-label {
67
+ background-color: #007bff;
68
+ color: white;
69
+ padding: 10px 20px;
70
+ border-radius: 5px;
71
+ cursor: pointer;
72
+ display: inline-block;
73
+ margin-top: 20px;
74
+ margin-bottom: 20px;
75
+ }
76
+ .file-label:hover {
77
+ background-color: #000000;
78
+ }
79
+ .custom-button {
80
+ background-color: #2cb1ff;
81
+ color: white;
82
+ border: none;
83
+ padding: 10px 20px;
84
+ margin-top: 20px;
85
+ border-radius: 5px;
86
+ cursor: pointer;
87
+ display: inline-block;
88
+ }
89
+ .custom-button:hover {
90
+ background-color: #01050a;
91
+ }
92
+ .container img {
93
+ margin: 20px auto;
94
+ max-width: 100%;
95
+ max-height: 300px;
96
+ border-radius: 10px;
97
+ display: none;
98
+ }
99
+ </style>
100
+ </head>
101
+ <body style="background-image: url('static/Background.png'); background-size: cover; background-position: center; background-repeat: no-repeat;">
102
+ <div class="container">
103
+ <div class="overlay"></div>
104
+ <div class="content">
105
+ <h1>RECONOCIMIENTO FACIAL</h1>
106
+ <form action="/predict" method="post" enctype="multipart/form-data" onsubmit="mostrarResultado(event)">
107
+ <label for="file-input" class="file-label">Seleccionar archivo</label>
108
+ <input id="file-input" class="custom-file-input" name="file" type="file" accept="image/*" onchange="mostrarImagen(event)">
109
+ <img id="imagenSeleccionada">
110
+ <button type="submit" class="custom-button">Subir Imagen</button>
111
+ </form>
112
+ </div>
113
+ </div>
114
+ <script>
115
+ function mostrarImagen(event) {
116
+ const archivo = event.target.files[0];
117
+ if (archivo) {
118
+ const lector = new FileReader();
119
+ lector.onload = function(e) {
120
+ const imagen = document.getElementById('imagenSeleccionada');
121
+ imagen.src = e.target.result;
122
+ imagen.style.display = 'block';
123
+ }
124
+ lector.readAsDataURL(archivo);
125
+ }
126
+ }
127
+ // Funci贸n para mostrar el resultado como un alert
128
+ async function mostrarResultado(event) {
129
+ event.preventDefault(); // Evitar que el formulario se env铆e autom谩ticamente
130
+
131
+ try {
132
+ const formData = new FormData(event.target);
133
+ const response = await fetch('/predict', {
134
+ method: 'POST',
135
+ body: formData
136
+ });
137
+
138
+ if (!response.ok) {
139
+ throw new Error('HTTP error! Status: ${response.status}');
140
+ }
141
+
142
+ const data = await response.json();
143
+ alert('Rostro detectado : ${data}');
144
+ } catch (error) {
145
+ console.error('Error al procesar la solicitud:', error);
146
+ alert('Ocurri贸 un error al procesar la solicitud.');
147
+ }
148
+ }
149
+ </script>
150
+
151
+ </body>
152
+ </html>
153
+ """
154
+ return HTMLResponse(content)
155
+
156
+
157
+ # Ruta de predicci贸n
158
+ @app.post('/predict')
159
+ async def predict(file: UploadFile = File(...)):
160
+ try:
161
+ # Verificar si es una imagen v谩lida
162
+ if not file.content_type.startswith('image/'):
163
+ raise HTTPException(status_code=400, detail="El archivo debe ser una imagen.")
164
+
165
+ # Convertir la imagen a formato adecuado
166
+ image = cv2.imdecode(np.frombuffer(await file.read(), np.uint8), cv2.IMREAD_COLOR)
167
+
168
+ # Realizar el reconocimiento de emociones en la imagen
169
+ emotion = buscar_existe(image)
170
+ print(emotion)
171
+ # Devolver la emoci贸n detectada como respuesta en formato JSON
172
+ return emotion#{'emotion': emotion}
173
+
174
+ except HTTPException as he:
175
+ raise he
176
+ except Exception as e:
177
+ print(f"Error general: {str(e)}")
178
+ raise HTTPException(status_code=500, detail="Error durante la predicci贸n de emociones.")
179
+
180
+ # Punto de entrada principal para la aplicaci贸n
181
+ if __name__ == '__main__':
182
+ # Ejecutar la aplicaci贸n FastAPI utilizando Uvicorn
183
+ import uvicorn
184
+ uvicorn.run(app, host='0.0.0.0', port=8000)
haarcascade_frontalface_default.xml ADDED
The diff for this file is too large to render. See raw diff
 
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi
2
+ numpy
3
+ pydantic
4
+ opencv-python-headless
5
+ uvicorn[standard]
6
+ python-multipart