-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
520 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#:kivy 2.0 | ||
# -*- coding: utf-8 -*- | ||
<Gerenciador>: | ||
TelaInicial: | ||
name: 'tela_inicial' | ||
ConfiguracaoRotina: | ||
name: 'configuracao_rotina' | ||
TelaDeteccao: | ||
name: 'tela_deteccao' | ||
TelaFimExecucao: | ||
name: 'tela_fim_execucao' | ||
|
||
<TelaInicial>: | ||
BoxLayout: | ||
orientation: 'vertical' | ||
padding: 200 | ||
spacing: 50 | ||
Label: | ||
text: "Detector de Fadiga" | ||
font: "Roboto" | ||
font_size: 36 | ||
Button: | ||
text: "Iniciar execução" | ||
on_release: pass | ||
Button: | ||
text: "Fechar" | ||
on_release: app.stop() | ||
|
||
<ConfiguracaoRotina>: | ||
|
||
|
||
<TelaDeteccao>: | ||
|
||
|
||
<TelaFimExecucao>: | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from kivy.uix.screenmanager import ScreenManager, Screen | ||
from kivy.uix.boxlayout import BoxLayout | ||
|
||
class Gerenciador(ScreenManager): | ||
pass | ||
|
||
class TelaInicial(Screen): | ||
pass | ||
|
||
class ConfiguracaoRotina(Screen): | ||
pass | ||
|
||
class TelaDeteccao(Screen): | ||
pass | ||
|
||
class TelaFimExecucao(Screen): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,145 +1,17 @@ | ||
from scipy.spatial import distance as dist | ||
from imutils.video import VideoStream | ||
from imutils import face_utils | ||
from threading import Thread | ||
import numpy as np | ||
import playsound | ||
import imutils | ||
import time | ||
import dlib | ||
import cv2 | ||
import matplotlib.pyplot as plt | ||
|
||
|
||
# definir constantes | ||
ALARM = "alarm.wav" | ||
WEBCAM = 0 | ||
EYE_AR_THRESH = 0.3 | ||
EYE_AR_CONSEC_FRAMES = 40 | ||
COUNTER = 0 | ||
ALARM_ON = False | ||
|
||
|
||
def sound_alarm(path=ALARM): | ||
# play an alarm sound | ||
playsound.playsound(ALARM) | ||
|
||
|
||
def eye_aspect_ratio(eye): | ||
# compute the euclidean distances between the two sets of | ||
# vertical eye landmarks (x, y)-coordinates | ||
A = dist.euclidean(eye[1], eye[5]) | ||
B = dist.euclidean(eye[2], eye[4]) | ||
|
||
# compute the euclidean distance between the horizontal | ||
# eye landmark (x, y)-coordinates | ||
C = dist.euclidean(eye[0], eye[3]) | ||
|
||
# compute the eye aspect ratio | ||
ear = (A + B) / (2.0 * C) | ||
|
||
# return the eye aspect ratio | ||
return ear | ||
|
||
|
||
# dlib's face detector (HOG-based) | ||
print("[INFO] carregando o preditor de landmark...") | ||
detector = dlib.get_frontal_face_detector() | ||
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") | ||
|
||
# pegar os índices do previsor, para olhos esquerdo e direito | ||
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] | ||
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"] | ||
|
||
# inicializar vídeo | ||
print("[INFO] inicializando streaming de vídeo...") | ||
vs = VideoStream(src=WEBCAM).start() | ||
time.sleep(1.0) | ||
|
||
# desenhar um objeto do tipo figure | ||
y = [None] * 100 | ||
x = np.arange(0,100) | ||
fig = plt.figure() | ||
ax = fig.add_subplot(111) | ||
li, = ax.plot(x, y) | ||
|
||
# loop sobre os frames do vídeo | ||
while True: | ||
frame = vs.read() | ||
frame = imutils.resize(frame, width=800) | ||
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) | ||
|
||
# detectar faces (grayscale) | ||
rects = detector(gray, 0) | ||
|
||
# loop nas detecções de faces | ||
for rect in rects: | ||
shape = predictor(gray, rect) | ||
shape = face_utils.shape_to_np(shape) | ||
|
||
# extrair coordenadas dos olhos e calcular a proporção de abertura | ||
leftEye = shape[lStart:lEnd] | ||
rightEye = shape[rStart:rEnd] | ||
leftEAR = eye_aspect_ratio(leftEye) | ||
rightEAR = eye_aspect_ratio(rightEye) | ||
|
||
# ratio média para os dois olhos | ||
ear = (leftEAR + rightEAR) / 2.0 | ||
|
||
# convex hull para os olhos | ||
leftEyeHull = cv2.convexHull(leftEye) | ||
rightEyeHull = cv2.convexHull(rightEye) | ||
cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1) | ||
cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1) | ||
|
||
# salvar historico para plot | ||
y.pop(0) | ||
y.append(ear) | ||
|
||
# update canvas | ||
plt.xlim([0, 100]) | ||
plt.ylim([0, 0.4]) | ||
ax.relim() | ||
ax.autoscale_view(True, True, True) | ||
fig.canvas.draw() | ||
plt.show(block=False) | ||
li.set_ydata(y) | ||
fig.canvas.draw() | ||
time.sleep(0.01) | ||
|
||
# checar ratio x threshold | ||
if ear < EYE_AR_THRESH: | ||
COUNTER += 1 | ||
|
||
# dentro dos critérios, soar o alarme | ||
if COUNTER >= EYE_AR_CONSEC_FRAMES: | ||
# ligar alarme | ||
if not ALARM_ON: | ||
ALARM_ON = True | ||
t = Thread(target=sound_alarm) | ||
t.deamon = True | ||
t.start() | ||
|
||
cv2.putText(frame, "[ALERTA] FADIGA!", (10, 30), | ||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) | ||
|
||
# caso acima do threshold, resetar o contador e desligar o alarme | ||
else: | ||
COUNTER = 0 | ||
ALARM_ON = False | ||
|
||
# desenhar a proporção de abertura dos olhos | ||
cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30), | ||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) | ||
|
||
# show frame | ||
cv2.imshow("Frame", frame) | ||
key = cv2.waitKey(1) & 0xFF | ||
|
||
# tecla para sair do script "q" | ||
if key == ord("q"): | ||
break | ||
|
||
# clean | ||
cv2.destroyAllWindows() | ||
vs.stop() | ||
from kivy.app import App | ||
from Interface import Gerenciador | ||
from kivy.lang.builder import Builder | ||
from kivy.core.window import Window | ||
from kivy.config import Config | ||
|
||
Config.set('graphics', 'resizable', False) | ||
rgba_divider = 255 | ||
|
||
class Aplicativo(App): | ||
def build(self): | ||
Window.size = (600, 600) | ||
Window.clearcolor = (208/rgba_divider,244/rgba_divider,234/rgba_divider,1) | ||
Builder.load_string(open("Aplicativo.kv", encoding='utf-8').read(), rulesonly=True) | ||
return Gerenciador() | ||
|
||
Aplicativo().run() |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from kivy.app import App | ||
from kivy.uix.widget import Widget | ||
from kivy.uix.boxlayout import BoxLayout | ||
from kivy.uix.image import Image | ||
from kivy.clock import Clock | ||
from kivy.graphics.texture import Texture | ||
from kivy.uix.label import Label | ||
|
||
import cv2 | ||
import numpy as np | ||
|
||
class CamApp(App): | ||
|
||
def build(self): | ||
self.img1 = Image(source='camera.jpg') | ||
label1= Label(text="Experimentos com vídeo (II)") #label superior | ||
label2= Label(text="www.cadernodelaboratorio.com.br") #label inferior | ||
layout = BoxLayout(orientation='vertical') | ||
layout.add_widget(label1) | ||
layout.add_widget(self.img1) | ||
layout.add_widget(label2) | ||
|
||
#opencv2 stuffs | ||
self.capture = cv2.VideoCapture(0) | ||
ret, frame = self.capture.read() | ||
# cv2.namedWindow("CV2 Image") | ||
# cv2.imshow("CV2 Image", frame) | ||
Clock.schedule_interval(self.update, 1.0/33.0) | ||
return layout | ||
|
||
def CreateImage(self, height, width, bits=np.uint8, channels=3, color=(0, 0, 0)): # (cv.GetSize(frame), 8, 3) | ||
"""Create new image(numpy array) filled with certain color in RGB""" | ||
# Create black blank image | ||
if bits == 8: | ||
bits = np.uint8 | ||
elif bits == 32: | ||
bits = np.float32 | ||
elif bits == 64: | ||
bits = np.float64 | ||
image = np.zeros((height, width, channels), bits) | ||
if color != (0, 0, 0): | ||
# Fill image with color | ||
image[:] = color | ||
return image | ||
|
||
def update(self, dt): | ||
# display image from cam in opencv window | ||
ret, frame = self.capture.read() | ||
# cv2.imshow("CV2 Image", frame) | ||
# convert it to texture | ||
buf1 = cv2.flip(frame, 0) | ||
buf = buf1.tostring() | ||
texture1 = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr') | ||
texture1.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte') | ||
# display image from the texture | ||
self.img1.texture = texture1 | ||
|
||
if __name__ == '__main__': | ||
CamApp().run() |
Oops, something went wrong.