Project

General

Profile

semaforo_beta.py

Versión beta del archivo principal - Tiara Canepa, 01/05/2026 10:35 PM

Download (6.1 KB)

 
1
import cv2
2
import time
3
from grovepi import *
4
from enum import Enum
5

    
6
hog = cv2.HOGDescriptor()
7
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
8

    
9
cap = cv2.VideoCapture(0)
10
cap.open("peatones-dublin.mp4", cv2.CAP_FFMPEG)
11

    
12
class Estado(Enum):
13
    ROJO = 1
14
    AMARILLO = 2
15
    VERDE = 3
16

    
17
class Ultrasonico:
18

    
19
    def __init__(self, pin):
20
        self.pin = pin
21
        self.activo = True
22
        self.distancia = 0
23

    
24
        pinMode(pin, "INPUT")
25

    
26
    def activar(self):
27
        self.activo = True
28

    
29
    def desactivar(self):
30
        self.activo = False
31

    
32
    def getDistancia(self):
33
        try:
34
            distance = ultrasonicRead(self.pin)
35
            return distance
36
        except IOError as e:
37
            print("Error: " + str(e))
38

    
39
class Camara:
40

    
41
    def __init__(self):
42
        self.activo = True
43
        self.cap = cv2.VideoCapture(0)
44

    
45
    def activar(self):
46
        self.activo = True
47

    
48
    def desactivar(self):
49
        self.activo = False
50

    
51
    def getImagen(self):
52
        ret, frame = self.cap.read()
53

    
54
        return ret, frame
55

    
56
class Buzzer:
57

    
58
    def __init__(self, pin):
59
        self.pin = pin
60
        self.activo = True
61
        self.volumen = 50
62

    
63
        pinMode(pin, "OUTPUT")
64

    
65
    def activar(self):
66
        self.activo = True
67

    
68
    def desactivar(self):
69
        self.activo = False
70

    
71
    # TODO
72
    def pulsar(self, tiempo):
73
        pass
74

    
75
    def setVolumen(self, newVolumen):
76
        self.volumen = newVolumen
77

    
78
class Led:
79

    
80
    def __init__(self, pin):
81
        self.pin = pin
82
        self.activo = False
83

    
84
        pinMode(pin, "OUTPUT")
85

    
86
    def prender(self):
87
        digitalWrite(self.pin, 1)
88

    
89
    def apagar(self):
90
        digitalWrite(self.pin, 0)
91

    
92
class Boton:
93

    
94
    def __init__(self, pin):
95
        self.pin = pin
96

    
97
        pinMode(pin, "INPUT")
98

    
99
    def getEstado(self):
100
        try:
101
            status = digitalRead(self.pin)
102
            print("Button pressed")
103
            return status
104
        except IOError as e:
105
            print("Error: " + str(e))
106

    
107
class Sistema:
108

    
109
    def __init__(self, pinUts = 2, pinBoton = 3, pinBuzzer = 4, \
110
                pinLedRojo = 5, pinLedAmarillo = 6, pinLedVerde = 7):
111
        self.ultrasonico = Ultrasonico(pinUts)
112
        self.boton = Boton(pinBoton)
113
        self.buzzer = Buzzer(pinBuzzer)
114
        self.ledRojo = Led(pinLedRojo)
115
        self.ledAmarillo = Led(pinLedAmarillo)
116
        self.ledVerde = Led(pinLedVerde)
117
        self.camara = Camara()
118
        self.timer = Timer()
119
        self.timerEstado = Timer()
120

    
121
        self.prioridadPeatones = 0
122
        self.prioridadVehiculos = 100
123
        self.cantidadPeatones = 0
124
        self.distanciaVehiculos = 0
125
        self.estado = Estado.ROJO
126

    
127
    def setEstado(self, nuevoEstado):
128
        self.estado = nuevoEstado
129

    
130
        if nuevoEstado == Estado.ROJO:
131
            self.ledAmarillo.apagar()
132
            self.ledVerde.apagar()
133
            self.ledRojo.prender()
134
        elif nuevoEstado == Estado.AMARILLO:
135
            self.ledVerde.apagar()
136
            self.ledRojo.apagar()
137
            self.ledAmarillo.prender()
138
        else:
139
            self.ledRojo.apagar()
140
            self.ledAmarillo.apagar()
141
            self.ledVerde.prender()
142

    
143
    def cambiarPaso(self):
144
        if self.estado == Estado.ROJO:
145
            self.setEstado(Estado.VERDE)
146

    
147
        elif self.estado == Estado.VERDE:
148
            self.setEstado(Estado.AMARILLO)
149
            time.sleep(3)
150
            self.setEstado(Estado.ROJO)
151

    
152
    def isPasoPeatones(self):
153
        return self.estado == Estado.ROJO
154

    
155
    # TODO
156
    def activarBuzzer(self):
157
        self.buzzer.activar()
158

    
159
    # TODO
160
    def calcularPrioridades(self):
161
        self.prioridadPeatones = 0
162
        self.prioridadVehiculos = 100
163

    
164
    def getCantidadPersonas(self):
165
        """Se usan HOGDescriptors para reconocer personas.
166
           Devuelve los rectángulos que encierran a las personas detectadas"""
167

    
168
        ret, frame = self.camara.getImagen()
169

    
170
        if not ret:
171
            print("Error obteniendo frame.")
172
            return -1
173

    
174
        # Reducir resolución para mayor rendimiento
175
        frame = cv2.resize(frame, (960, 540))
176
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
177

    
178
        personas, _ = hog.detectMultiScale(
179
            gray,
180
            winStride=(4,4),
181
            padding=(32,32),
182
            scale=1.3
183
            )
184

    
185
        return personas
186

    
187
class Timer:
188

    
189
    def __init__(self, startTime=time.time()):
190
        self.startTime = startTime
191
        self.currentTime = startTime
192

    
193
    def getDiferenciaTiempo(self):
194
        return self.currentTime - self.startTime
195

    
196
    def reiniciar(self):
197
        self.startTime = time.time()
198

    
199
    def actualizarTiempo(self):
200
        self.currentTime = time.time()
201

    
202
SEGUNDOS_SEMAFORO = 30
203
METROS_DISTANCIA_AUTO = 5
204
SEGUNDOS_INTERVALO_FOTO = 3
205
SEGUNDOS_INCREMENTO_TIMER = 3
206

    
207
def main():
208
    sistema = Sistema()
209
    personas = 0
210

    
211
    while True:
212
        distancia = sistema.ultrasonico.getDistancia()
213

    
214
        # Foto cada 3 segundos
215
        if sistema.timer.getDiferenciaTiempo() >= SEGUNDOS_INTERVALO_FOTO:
216
            personas = sistema.getCantidadPersonas()
217
            sistema.timer.reiniciar()
218

    
219
            if personas == -1:
220
                continue
221

    
222
        # Si hay personas esperando y ha pasado un segundo desde el último chequeo
223
        if sistema.isPasoPeatones() and sistema.timer.getDiferenciaTiempo() >= 1:
224
            sistema.timer.reiniciar()
225
            if distancia <= METROS_DISTANCIA_AUTO:
226
                sistema.timerEstado.currentTime += SEGUNDOS_INCREMENTO_TIMER
227

    
228
        # Si hay autos esperando y ha pasado un segundo desde el último chequeo
229
        elif not sistema.isPasoPeatones() and sistema.timer.getDiferenciaTiempo() >= 1:
230
            sistema.timer.reiniciar()
231
            if personas >= 3 and distancia >= METROS_DISTANCIA_AUTO:
232
                sistema.timerEstado.currentTime += SEGUNDOS_INCREMENTO_TIMER
233

    
234
        # Si el timer indica que hay que cambiar el paso
235
        if sistema.timerEstado.getDiferenciaTiempo() >= SEGUNDOS_SEMAFORO:
236
            sistema.cambiarPaso()
237
            sistema.timerEstado.reiniciar()
238

    
239
        sistema.timer.actualizarTiempo()
240
        sistema.timerEstado.actualizarTiempo()
241

    
242
if __name__ == "__main__":
243
    main()
244

    
245
    cap.release()
246
    cv2.destroyAllWindows()