mvp1/scan_faces.py

153 lines
4.2 KiB
Python
Raw Normal View History

2017-12-15 23:22:09 +01:00
#!/usr/bin/python
2017-12-11 20:55:07 +01:00
import io
import picamera
import cv2
import numpy as np
import datetime
import time
import os
from si_prefix import si_format
2017-12-15 19:29:58 +01:00
import Adafruit_CharLCD as LCD
2018-01-04 21:07:50 +01:00
import urllib2
2018-01-05 00:10:44 +01:00
import socket
2017-12-11 20:55:07 +01:00
2017-12-15 19:29:58 +01:00
# Set FPS (though RPi is probably to slow to meet it ;-)
2017-12-11 20:55:07 +01:00
FPS = 1.0
frameTimeDelta = datetime.timedelta(seconds=1.0/FPS)
2017-12-15 23:22:09 +01:00
dimTimeDelta = datetime.timedelta(seconds=10)
2017-12-11 20:55:07 +01:00
2017-12-15 19:29:58 +01:00
# Init LCD
lcd_rs = 27
lcd_en = 22
lcd_d4 = 25
lcd_d5 = 24
lcd_d6 = 23
lcd_d7 = 18
lcd_backlight = 4
lcd_columns = 16
lcd_rows = 2
lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7,
lcd_columns, lcd_rows, lcd_backlight)
2018-01-05 00:10:44 +01:00
# ip if config is needed over ssh. Username pi, Password: artwork1
2018-01-05 00:17:03 +01:00
try:
ip = (([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0]
except Exception:
ip = "No network"
2017-12-15 23:22:09 +01:00
lcd.clear()
2018-01-05 00:10:44 +01:00
lcd.message("Init scanner.\n{}".format(ip) )
time.sleep(6) # give some time to read the ip.
2017-12-15 23:22:09 +01:00
# Init camera
camera = picamera.PiCamera()
2018-01-04 20:07:56 +01:00
#~ camera.resolution = (1280, 720)
camera.resolution = (1920, 1080)
2017-12-15 23:22:09 +01:00
lcd.clear()
lcd.message("Init scanner..")
# Init classifier, various options:
#~ /usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml (~22sec)
#~ /usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml (>25sec)
#~ /usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml (~21sec)
#~ /usr/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml (~14sec, seems to miss many faces)
classifier = cv2.CascadeClassifier('/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml')
lcd.clear()
lcd.message("Init scanner...")
2017-12-15 19:29:58 +01:00
prevFaceCount = 0
2017-12-15 23:22:09 +01:00
totalUse = 0 #in face-seconds
2018-01-04 21:19:58 +01:00
logfile = "/home/pi/scan_faces/scan_face.log"
2018-01-04 21:18:32 +01:00
def tail(filepath):
"""
Thanks: https://stackoverflow.com/a/41491521
"""
2018-01-04 23:46:40 +01:00
with open(filepath, "rb") as f:
first = f.readline() # Read the first line.
f.seek(-2, 2) # Jump to the second last byte.
while f.read(1) != b"\n": # Until EOL is found...
try:
f.seek(-2, 1) # ...jump back the read byte plus one more.
except IOError:
f.seek(-1, 1)
if f.tell() == 0:
break
last = f.readline() # Read last line.
return last
2018-01-04 21:18:32 +01:00
# make sure log file exists
2018-01-04 21:18:32 +01:00
if not os.path.exists(logfile):
with open(logfile,"w") as f:
f.write("{},{},{}".format(time.time(), 0,0))
# get last line of log file and update 'total use' using that.
2018-01-04 23:46:40 +01:00
last = tail(logfile)
2018-01-04 21:18:32 +01:00
bits = last.split(",")
2018-01-04 23:46:40 +01:00
totalUse = float(bits[2])
print "Total use:", totalUse
2018-01-04 21:18:32 +01:00
log = open(logfile, "a")
2017-12-15 23:22:09 +01:00
lastFaceTime = datetime.datetime.utcnow()
2017-12-15 19:29:58 +01:00
2017-12-11 20:55:07 +01:00
while True:
2018-01-05 00:04:52 +01:00
try:
print(time.time(),"GO")
start = datetime.datetime.utcnow()
stream = io.BytesIO()
camera.capture(stream, format='jpeg')
print(time.time(),"captured")
buff = np.fromstring(stream.getvalue(), dtype=np.uint8)
image = cv2.imdecode(buff,1)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(time.time(),"grayed")
faces = classifier.detectMultiScale(gray, 1.2, 5, minSize=(30,20))
print(time.time(),"Found {} faces".format(len(faces)))
end = datetime.datetime.utcnow()
# take the frame as being representative of whole frame
scanDuration = (end - start).total_seconds()
totalUse += len(faces) * scanDuration
lcd.clear()
#~ lcd.message("viewers {:>8}\nview-min. {:>7.2f}".format(len(faces), totalUse/60))
lcd.message("{:>7} viewers \n{:>7}view-sec".format(len(faces), si_format(totalUse,precision=1)))
log.write("{},{},{}\n".format(time.time(), len(faces), int(totalUse)))
log.flush()
os.fsync(log.fileno())
if len(faces) < 1 and end - lastFaceTime > dimTimeDelta:
lcd.set_backlight(0)
else:
lcd.set_backlight(1)
2017-12-15 23:22:09 +01:00
2018-01-05 00:04:52 +01:00
if len(faces) > 0:
lastFaceTime = end
2017-12-11 20:55:07 +01:00
2018-01-05 01:07:20 +01:00
content = urllib2.urlopen("https://artstats.rubenvandeven.com/artwork1/views.php?time=%d&count=%d&total=%d&duration=%f" % (int(time.time()), len(faces), int(totalUse), scanDuration) ).read()
2018-01-05 00:04:52 +01:00
#~ if end - start < frameTimeDelta:
#~ waitTime = frameTimeDelta - (end-start)
#~ print("wait {}".waitTime.total_seconds())
#~ time.sleep(waitTime.total_seconds())
except Exception as e:
print e
2017-12-11 20:55:07 +01:00