So verschwenden Sie nicht die Zeit, die Sie am Computer verbringen. Anwendung zur Überwachung der Arbeit und Pflege der Statistiken





Ich arbeite als Lehrerin im Quantorium Kindertechnologiepark. In der Zeit der Selbstisolation haben wir wie alle anderen auf Fernunterricht umgestellt. Und aufgrund der Tatsache, dass Kinder noch mehr Zeit am Computer verbrachten, beschloss die Verwaltung, die akademische Stunde zu verkürzen und zwischen den Arbeiten Pausen einzulegen - um ihr Sehvermögen zu bewahren. Wir haben eine Anwendung geschrieben, die die am Computer verbrachte Zeit berechnet, Statistiken in Excel hält - nützlich für Eltern - und einen akustischen Alarm ausgibt, wenn es Zeit ist, eine Pause einzulegen.



Die Anwendung ist nützlich für diejenigen, die Zeit verlieren, wenn sie am PC arbeiten und sich in den Zeitrahmen hineinversetzen oder verfolgen möchten, welcher Teil des Lebens im digitalen Raum verloren geht.



Link zum Repository



Unter dem Schnitt eine detaillierte Analyse.



Um ein Programm zu erstellen, müssen Sie die folgenden Aufgaben lösen:



  • web ( mtcnn);
  • ( time)
  • excel ( openpyxl);
  • ;
  • .


web



Wir haben die Option in Betracht gezogen, die Präsenz am Computer durch die Bewegung der Computermaus zu verfolgen. Vielleicht ist dies einfacher und die Webkamera bleibt frei, aber dann können wir das Ansehen von Fernsehsendungen oder YouTube-Videos nicht berücksichtigen. Außerdem ist die Verwendung der Gesichtserkennung viel interessanter.



Für die Gesichtserkennung verwenden wir die mtcnn-Architektur. Ein Kopf, der in einem beliebigen Winkel positioniert ist und eine Brille trägt, bei schlechten Lichtverhältnissen, auch wenn das Gesicht nicht vollständig in den Rahmen fällt oder von einer Hand bedeckt wird, funktioniert das neuronale Netzwerk ordnungsgemäß. Wir werden es nicht selbst erstellen, sondern die gleichnamige Bibliothek verbinden, wodurch unser Problem mit wenigen Codezeilen gelöst wird.



Zunächst wurde die Viola-Jones-Methode angewendet. Die Genauigkeit ist viel schlechter als die von mtcnn, der Prozessor lädt das gleiche.











Wir werden die Ausgabe des Ergebnisses in eine separate Funktion verschieben. Sie wird nur benötigt, um zu sehen, wie die Erkennung funktioniert.



import cv2
import os
from mtcnn.mtcnn import MTCNN


def show_face_frame():
    if faces:
        bounding_box = faces[0]['box']
        keypoints = faces[0]['keypoints']
        cv2.rectangle(img,
                      (bounding_box[0], bounding_box[1]),
                      (bounding_box[0] + bounding_box[2], 
                      bounding_box[1] + bounding_box[3]),
                      (0, 0, 255),
                      2)
        cv2.circle(img, (keypoints['left_eye']), 3, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['right_eye']), 2, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['nose']), 3, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['mouth_left']), 3, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['mouth_right']), 3, (0, 0, 255), 2)
    cv2.imshow('frame', img)

cap = cv2.VideoCapture(0)
detector = MTCNN()

while cap.isOpened():
        _, img = cap.read()
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        faces = detector.detect_faces(img)
        show_face_frame()
        cv2.waitKey(300)

cap.release()
cv2.destroyAllWindows()


Lange cv2.waitKey (300) -Latenz , um eine CPU-Überlastung zu vermeiden . Durch die Verarbeitung von 3-4 Bildern pro Sekunde wird der i3-8145U durchschnittlich um 15% belastet.



Zeit zählen



Das Programm sollte in den folgenden Fällen nicht in das Protokoll schreiben:



  • setzte sich 5 Sekunden lang an den Computer, um etwas zu tun byrik;
  • ging aus, um Kaffee einzuschenken oder meine Beine zu strecken.


Um diese Probleme zu lösen, verwendet das Programm zwei Stoppuhren time_here (zählt die Zeit herunter, wenn sich das Gesicht im Frame befindet) und time_not_here (wenn kein Gesicht vorhanden ist). Beide Stoppuhren werden zurückgesetzt, wenn ein Protokolleintrag vorgenommen wird. Außerdem wird time_not_here jedes Mal zurückgesetzt, wenn ein Gesicht im Frame angezeigt wird .



Die Variable min_time_here gibt die Mindestzeit an, die am Computer verbracht wird. Danach lohnt es sich, in das Protokoll zu schreiben. Die Aufzeichnung erfolgt, nachdem die Person länger als in min_time_not_here angegeben vom Computer abgelenkt wurde .



Im folgenden Code wird die Aufzeichnung ausgeführt, wenn Sie mindestens 5 Minuten am Computer verbracht haben. Das Programm berücksichtigt nicht die Tatsache, dass ich weniger als 2 Minuten abgelenkt bin.



import cv2
import time
import os
from mtcnn.mtcnn import MTCNN

cap = cv2.VideoCapture(0)
path = os.path.abspath(__file__)[:-11]  #      

here, not_here = 0, 0  # 
time_here, time_not_here = 0, 0  #  
switch = True  #        
min_time_here = 300  #     ,     ( ) 
min_time_not_here = 120  #          ( )

detector = MTCNN()

try:
    while cap.isOpened():
        _, img = cap.read()
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        faces = detector.detect_faces(img)
       show_face_frame()
       audio_message(path, here)

        if faces and switch:
            not_here = 0
            switch = False
            if here == 0:
                here = time.time()
                print('     ' + time.strftime("%H:%M:%S", time.localtime(here)))
        elif not faces and not switch:
            not_here = time.time()
            switch = True

        if not_here != 0:
            time_not_here = time.time() - not_here
        if here != 0 and not switch:
            time_here = time.time() - here

        if time_here > min_time_here and time_not_here > min_time_not_here:  #        min_time_here
            write_excel(path, here)
            print('    ' + time.strftime('%H:%M:%S', time.gmtime(time.time() - here)))
            time_here, time_not_here = 0, 0
            here, not_here = 0, 0
        elif time_not_here > min_time_not_here and  time_here < min_time_here:  #      min_time_here,    
            print('  ')
            time_here, time_not_here = 0, 0
            here, not_here = 0, 0

        cv2.waitKey(300)
except KeyboardInterrupt:
    if time_here > min_time_here:  #        min_time_here
        write_excel(path, here)
    cap.release()
    cv2.destroyAllWindows()


Wenn der Benutzer den Computer ausschalten möchte, müssen Sie zuerst das Programm unterbrechen (Strg + C) und die Zeit der aktuellen Arbeit wird protokolliert. Hierfür wird ein Exception-Handler verwendet.



Daten schreiben, um Dokumente zu übertreffen



Für die Arbeit mit Excel hilft die wunderbare openpyxl-Bibliothek, die gleichzeitig Daten liest und schreibt.



Jeden Tag erstellt das Programm ein neues Blatt mit dem aktuellen Datum.





Auf einem Blatt werden die täglichen Informationen aufgezeichnet, an welchem ​​Tag wie viel Zeit am Computer verbracht wurde.







Die Funktion write_excel öffnet das Dokument, schreibt Daten und schließt es sofort.



Sie können ein Dokument nicht über openpyxl ändern, wenn es vom Benutzer bereits geöffnet ist. Für diesen Fall wurde eine Ausnahme hinzugefügt.



def write_excel(path_excel, time_start):
    wb = openpyxl.load_workbook(path_excel + r'\dnevnik.xlsx')
    today = time.strftime("%d.%m.%Y", time.localtime(time.time()))
    if today not in wb.sheetnames:  #        ,   
        wb.create_sheet(title=today)
        sheet = wb[today]
        sheet.column_dimensions['A'].width = 20
        sheet.column_dimensions['B'].width = 20
        sheet.column_dimensions['C'].width = 20
        sheet.column_dimensions['D'].width = 31
        sheet['A1'] = '   '
        sheet['B1'] = '   '
        sheet['C1'] = ' '
        sheet['D1'] = '  :'
        sheet['D2'] = '    :'
        sheet = wb[today]
        row = 2
        all_time = 0
    else:  #      
        sheet = wb[today]
        row = sheet['E1'].value  #    excel 
        all_time = sheet['E2'].value  #        
        all_time = all_time.split(':')
        all_time = int(all_time[0]) * 3600 + int(all_time[1]) * 60 + int(all_time[2])  #    
        row = row + 2  #      

    sheet['A' + str(row)] = time.strftime("%H:%M:%S", time.localtime(time_start))  #      
    sheet['C' + str(row)] = time.strftime("%H:%M:%S", time.localtime(time.time()))  #   - 
    seconds = time.time() - time_start  #      
    sheet['B' + str(row)] = time.strftime('%H:%M:%S', time.gmtime(seconds))
    sheet['E1'] = row - 1  #   
    all_time = all_time + seconds
    all_time = time.strftime('%H:%M:%S', time.gmtime(all_time))
    sheet['E2'] = all_time
    #   
    sheet_0 = wb.worksheets[0]
    sheet_0['A' + str(len(wb.sheetnames))] = today
    sheet_0['B' + str(len(wb.sheetnames))] = all_time
    while True:  #  
        try:
            wb.save(path_excel + r'\dnevnik.xlsx')
        except PermissionError:
            input('  excel     enter')
        else:
            break


Sirenenalarm



Zur Abwechslung haben wir 8 Audiodateien mit einem Sprachsynthesizer generiert , die nach einer Arbeitsstunde zufällig ausgeführt werden. Bis Sie eine Pause einlegen, werden keine wiederholten akustischen Warnungen angezeigt.



def audio_message(path, here):
    if here == 0:
        pass
    elif time.strftime('%H:%M:%S', time.gmtime(time.time()-here)) == "01:00:00":
        wav = random.choice(os.listdir(path + r'\audio'))
        winsound.PlaySound(path + r'\audio\\' + wav, winsound.SND_FILENAME)


Startskript beim Einschalten des PCs



Damit das Programm zusammen mit Windows geladen werden kann, können Sie eine Batchdatei erstellen, in der das Python-Skript ausgeführt wird. Die Batchdatei sollte sich im folgenden Verzeichnis befinden:



C: \ Benutzer \% Benutzername% \ AppData \ Roaming \ Microsoft \ Windows \ Startmenü \ Programme \ Start



Da die Batchdatei und die Quelldatei in verschiedenen Verzeichnissen gespeichert sind, können Sie os.getcwd ( nicht verwenden ). ), da der Pfad zur Batch-Datei zurückgegeben wird. Wir verwenden os.path.abspath (__ file __) [: - 11]



UPD: ak545schlug eine bessere Option vor os.path.dirname (os.path.abspath (__ file__))



In der Zukunft



Ich wollte, dass das Programm meinem Gesicht folgt und nicht jeder, der am Computer sitzt. Hierzu wird FaceNet verwendet, das zur Gesichtserkennung fähig ist.

Es gibt auch Pläne, ein schönes Widget anstelle einer hässlichen schwarzen Konsole zu entwickeln, damit die Aufnahme beim Ausschalten des Computers automatisch und ohne Interrupt erfolgt.

Vielen Dank für Ihre Aufmerksamkeit. Wenn Sie Fragen haben, schreiben Sie in die Kommentare oder unter https://www.linkedin.com/in/evg-voronov/



All Articles