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
2017-12-19 23:20:11 +01:00
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
2017-12-19 23:20:11 +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 :
2017-12-19 23:20:11 +01:00
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-19 23:20:11 +01:00
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