Merge branch 'master' of rubenvandeven.com:~/git/artwork1
This commit is contained in:
commit
e2c8d5b3c3
3 changed files with 283 additions and 4 deletions
4
logrotate.conf
Normal file
4
logrotate.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/home/pi/scan_faces/scan_face.log {
|
||||||
|
rotate 10
|
||||||
|
weekly
|
||||||
|
}
|
|
@ -6,8 +6,10 @@ import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
|
import os
|
||||||
|
from si_prefix import si_format
|
||||||
import Adafruit_CharLCD as LCD
|
import Adafruit_CharLCD as LCD
|
||||||
|
import urllib2
|
||||||
|
|
||||||
# Set FPS (though RPi is probably to slow to meet it ;-)
|
# Set FPS (though RPi is probably to slow to meet it ;-)
|
||||||
FPS = 1.0
|
FPS = 1.0
|
||||||
|
@ -52,6 +54,23 @@ lcd.message("Init scanner...")
|
||||||
prevFaceCount = 0
|
prevFaceCount = 0
|
||||||
totalUse = 0 #in face-seconds
|
totalUse = 0 #in face-seconds
|
||||||
|
|
||||||
|
# make sure log file exists
|
||||||
|
if not os.path.exists("scan_face.log")
|
||||||
|
with open("scan_face.log","w") as f:
|
||||||
|
f.write("{},{},{}".format(time.time(), 0,0))
|
||||||
|
|
||||||
|
# get last line of log file and update 'total use' using that.
|
||||||
|
with open("scan_face.log", "rb") as f:
|
||||||
|
first = f.readline() # Read the first line.
|
||||||
|
f.seek(-2, os.SEEK_END) # Jump to the second last byte.
|
||||||
|
while f.read(1) != b"\n": # Until EOL is found...
|
||||||
|
f.seek(-2, os.SEEK_CUR) # ...jump back the read byte plus one more.
|
||||||
|
last = f.readline() # Read last line.
|
||||||
|
bits = last.split(",")
|
||||||
|
totalUse = bits[2]
|
||||||
|
|
||||||
|
log = open("scan_face.log", "a")
|
||||||
|
|
||||||
lastFaceTime = datetime.datetime.utcnow()
|
lastFaceTime = datetime.datetime.utcnow()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -65,8 +84,7 @@ while True:
|
||||||
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||||
print(time.time(),"grayed")
|
print(time.time(),"grayed")
|
||||||
faces = classifier.detectMultiScale(gray, 1.2, 5, minSize=(30,20))
|
faces = classifier.detectMultiScale(gray, 1.2, 5, minSize=(30,20))
|
||||||
|
|
||||||
# TODO: time passed since last * prevFaceCount = usage
|
|
||||||
|
|
||||||
print(time.time(),"Found {} faces".format(len(faces)))
|
print(time.time(),"Found {} faces".format(len(faces)))
|
||||||
|
|
||||||
|
@ -77,7 +95,15 @@ while True:
|
||||||
|
|
||||||
lcd.clear()
|
lcd.clear()
|
||||||
#~ lcd.message("viewers {:>8}\nview-min. {:>7.2f}".format(len(faces), totalUse/60))
|
#~ lcd.message("viewers {:>8}\nview-min. {:>7.2f}".format(len(faces), totalUse/60))
|
||||||
lcd.message("viewers {:>8}\nview-sec {:>7}".format(len(faces), int(totalUse)))
|
lcd.message("{:>7} viewers \n{:>7}view-sec".format(len(faces), si_format(totalUse,precision=1)))
|
||||||
|
|
||||||
|
log.write("{},{},{}".format(time.time(), len(faces), int(totalUse)))
|
||||||
|
log.flush()
|
||||||
|
|
||||||
|
content = urllib2.urlopen("https://artstats.rubenvandeven.com/artwork1/views.php?time=%d&count=%d&total=%d" % (int(time.time()), len(faces), int(totalUse)) ).read()
|
||||||
|
|
||||||
|
os.fsync(log.fileno())
|
||||||
|
|
||||||
if len(faces) < 1 and end - lastFaceTime > dimTimeDelta:
|
if len(faces) < 1 and end - lastFaceTime > dimTimeDelta:
|
||||||
lcd.set_backlight(0)
|
lcd.set_backlight(0)
|
||||||
else:
|
else:
|
||||||
|
|
249
si_prefix.py
Normal file
249
si_prefix.py
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
# coding: utf-8
|
||||||
|
from __future__ import division
|
||||||
|
import math
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Print a floating-point number in engineering notation.
|
||||||
|
# Ported from [C version][1] written by
|
||||||
|
# Jukka “Yucca” Korpela <jkorpela@cs.tut.fi>.
|
||||||
|
#
|
||||||
|
# [1]: http://www.cs.tut.fi/~jkorpela/c/eng.html
|
||||||
|
|
||||||
|
SI_PREFIX_UNITS = "yzafpnum kMGTPEZY"
|
||||||
|
CRE_SI_NUMBER = re.compile(r'\s*(?P<sign>[\+\-])?'
|
||||||
|
r'(?P<integer>\d+)'
|
||||||
|
r'(?P<fraction>.\d+)?\s*'
|
||||||
|
r'(?P<si_unit>[%s])?\s*' % SI_PREFIX_UNITS)
|
||||||
|
|
||||||
|
|
||||||
|
def split(value, precision=1):
|
||||||
|
'''
|
||||||
|
Split `value` into value and "exponent-of-10", where "exponent-of-10" is a
|
||||||
|
multiple of 3. This corresponds to SI prefixes.
|
||||||
|
|
||||||
|
Returns tuple, where the second value is the "exponent-of-10" and the first
|
||||||
|
value is `value` divided by the "exponent-of-10".
|
||||||
|
|
||||||
|
Args
|
||||||
|
----
|
||||||
|
value : int, float
|
||||||
|
Input value.
|
||||||
|
precision : int
|
||||||
|
Number of digits after decimal place to include.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
tuple
|
||||||
|
The second value is the "exponent-of-10" and the first value is `value`
|
||||||
|
divided by the "exponent-of-10".
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
si_prefix.split(0.04781) -> (47.8, -3)
|
||||||
|
si_prefix.split(4781.123) -> (4.8, 3)
|
||||||
|
|
||||||
|
See `si_prefix.format` for more examples.
|
||||||
|
'''
|
||||||
|
negative = False
|
||||||
|
digits = precision + 1
|
||||||
|
|
||||||
|
if value < 0.:
|
||||||
|
value = -value
|
||||||
|
negative = True
|
||||||
|
elif value == 0.:
|
||||||
|
return 0., 0
|
||||||
|
|
||||||
|
expof10 = int(math.log10(value))
|
||||||
|
if expof10 > 0:
|
||||||
|
expof10 = (expof10 // 3) * 3
|
||||||
|
else:
|
||||||
|
expof10 = (-expof10 + 3) // 3 * (-3)
|
||||||
|
|
||||||
|
value *= 10 ** (-expof10)
|
||||||
|
|
||||||
|
if value >= 1000.:
|
||||||
|
value /= 1000.0
|
||||||
|
expof10 += 3
|
||||||
|
elif value >= 100.0:
|
||||||
|
digits -= 2
|
||||||
|
elif value >= 10.0:
|
||||||
|
digits -= 1
|
||||||
|
|
||||||
|
if negative:
|
||||||
|
value *= -1
|
||||||
|
|
||||||
|
return value, int(expof10)
|
||||||
|
|
||||||
|
|
||||||
|
def prefix(expof10):
|
||||||
|
'''
|
||||||
|
Args:
|
||||||
|
|
||||||
|
expof10 : Exponent of a power of 10 associated with a SI unit
|
||||||
|
character.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
str : One of the characters in "yzafpnum kMGTPEZY".
|
||||||
|
'''
|
||||||
|
prefix_levels = (len(SI_PREFIX_UNITS) - 1) // 2
|
||||||
|
si_level = expof10 // 3
|
||||||
|
|
||||||
|
if abs(si_level) > prefix_levels:
|
||||||
|
raise ValueError("Exponent out range of available prefixes.")
|
||||||
|
return SI_PREFIX_UNITS[si_level + prefix_levels]
|
||||||
|
|
||||||
|
|
||||||
|
def si_format(value, precision=1, format_str='{value} {prefix}',
|
||||||
|
exp_format_str='{value}e{expof10}'):
|
||||||
|
'''
|
||||||
|
Format value to string with SI prefix, using the specified precision.
|
||||||
|
|
||||||
|
Args
|
||||||
|
----
|
||||||
|
|
||||||
|
value : int, float
|
||||||
|
Input value.
|
||||||
|
precision : int
|
||||||
|
Number of digits after decimal place to include.
|
||||||
|
format_str : str
|
||||||
|
Format string where `{prefix}` and `{value}` represent the SI prefix
|
||||||
|
and the value (scaled according to the prefix), respectively. The
|
||||||
|
default format matches the `SI prefix style`_ format.
|
||||||
|
exp_str : str
|
||||||
|
Format string where `{expof10}` and `{value}` represent the exponent of
|
||||||
|
10 and the value (scaled according to the exponent of 10),
|
||||||
|
respectively. This format is used if the absolute exponent of 10 value
|
||||||
|
is greater than 24.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str
|
||||||
|
`value` formatted according to the `SI prefix style`_.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
For example, with `precision=2`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
1e-27 --> 1.00e-27
|
||||||
|
1.764e-24 --> 1.76 y
|
||||||
|
7.4088e-23 --> 74.09 y
|
||||||
|
3.1117e-21 --> 3.11 z
|
||||||
|
1.30691e-19 --> 130.69 z
|
||||||
|
5.48903e-18 --> 5.49 a
|
||||||
|
2.30539e-16 --> 230.54 a
|
||||||
|
9.68265e-15 --> 9.68 f
|
||||||
|
4.06671e-13 --> 406.67 f
|
||||||
|
1.70802e-11 --> 17.08 p
|
||||||
|
7.17368e-10 --> 717.37 p
|
||||||
|
3.01295e-08 --> 30.13 n
|
||||||
|
1.26544e-06 --> 1.27 u
|
||||||
|
5.31484e-05 --> 53.15 u
|
||||||
|
0.00223223 --> 2.23 m
|
||||||
|
0.0937537 --> 93.75 m
|
||||||
|
3.93766 --> 3.94
|
||||||
|
165.382 --> 165.38
|
||||||
|
6946.03 --> 6.95 k
|
||||||
|
291733 --> 291.73 k
|
||||||
|
1.22528e+07 --> 12.25 M
|
||||||
|
5.14617e+08 --> 514.62 M
|
||||||
|
2.16139e+10 --> 21.61 G
|
||||||
|
9.07785e+11 --> 907.78 G
|
||||||
|
3.8127e+13 --> 38.13 T
|
||||||
|
1.60133e+15 --> 1.60 P
|
||||||
|
6.7256e+16 --> 67.26 P
|
||||||
|
2.82475e+18 --> 2.82 E
|
||||||
|
1.1864e+20 --> 118.64 E
|
||||||
|
4.98286e+21 --> 4.98 Z
|
||||||
|
2.0928e+23 --> 209.28 Z
|
||||||
|
8.78977e+24 --> 8.79 Y
|
||||||
|
3.6917e+26 --> 369.17 Y
|
||||||
|
1.55051e+28 --> 15.51e+27
|
||||||
|
6.51216e+29 --> 651.22e+27
|
||||||
|
|
||||||
|
|
||||||
|
.. _SI prefix style:
|
||||||
|
http://physics.nist.gov/cuu/Units/checklist.html
|
||||||
|
'''
|
||||||
|
svalue, expof10 = split(value, precision)
|
||||||
|
value_format = '%%.%df' % precision
|
||||||
|
value_str = value_format % svalue
|
||||||
|
try:
|
||||||
|
return format_str.format(value=value_str,
|
||||||
|
prefix=prefix(expof10).strip())
|
||||||
|
except ValueError:
|
||||||
|
sign = ''
|
||||||
|
if expof10 > 0:
|
||||||
|
sign = "+"
|
||||||
|
return exp_format_str.format(value=value_str,
|
||||||
|
expof10=''.join([sign, str(expof10)]))
|
||||||
|
|
||||||
|
|
||||||
|
def si_parse(value):
|
||||||
|
'''
|
||||||
|
Parse a value expressed using SI prefix units to a floating point number.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
|
||||||
|
value (str) : Value expressed using SI prefix units (as returned by
|
||||||
|
`si_format` function).
|
||||||
|
'''
|
||||||
|
CRE_10E_NUMBER = re.compile(r'^\s*(?P<integer>[\+\-]?\d+)?'
|
||||||
|
r'(?P<fraction>.\d+)?\s*([eE]\s*'
|
||||||
|
r'(?P<expof10>[\+\-]?\d+))?$')
|
||||||
|
CRE_SI_NUMBER = re.compile(r'^\s*(?P<number>(?P<integer>[\+\-]?\d+)?'
|
||||||
|
r'(?P<fraction>.\d+)?)\s*'
|
||||||
|
r'(?P<si_unit>[%s])?\s*$' % SI_PREFIX_UNITS)
|
||||||
|
match = CRE_10E_NUMBER.match(value)
|
||||||
|
if match:
|
||||||
|
# Can be parse using `float`.
|
||||||
|
assert(match.group('integer') is not None or
|
||||||
|
match.group('fraction') is not None)
|
||||||
|
return float(value)
|
||||||
|
match = CRE_SI_NUMBER.match(value)
|
||||||
|
assert(match.group('integer') is not None or
|
||||||
|
match.group('fraction') is not None)
|
||||||
|
d = match.groupdict()
|
||||||
|
si_unit = d['si_unit'] if d['si_unit'] else ' '
|
||||||
|
prefix_levels = (len(SI_PREFIX_UNITS) - 1) // 2
|
||||||
|
scale = 10 ** (3 * (SI_PREFIX_UNITS.index(si_unit) - prefix_levels))
|
||||||
|
return float(d['number']) * scale
|
||||||
|
|
||||||
|
|
||||||
|
def si_prefix_scale(si_unit):
|
||||||
|
'''
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
si_unit : str
|
||||||
|
SI unit character, i.e., one of "yzafpnum kMGTPEZY".
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
int
|
||||||
|
Multiple associated with `si_unit`, e.g., 1000 for `si_unit=k`.
|
||||||
|
'''
|
||||||
|
return 10 ** si_prefix_expof10(si_unit)
|
||||||
|
|
||||||
|
|
||||||
|
def si_prefix_expof10(si_unit):
|
||||||
|
'''
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
si_unit : str
|
||||||
|
SI unit character, i.e., one of "yzafpnum kMGTPEZY".
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
int
|
||||||
|
Exponent of the power of ten associated with `si_unit`, e.g., 3 for
|
||||||
|
`si_unit=k` and -6 for `si_unit=u`.
|
||||||
|
'''
|
||||||
|
prefix_levels = (len(SI_PREFIX_UNITS) - 1) // 2
|
||||||
|
return (3 * (SI_PREFIX_UNITS.index(si_unit) - prefix_levels))
|
||||||
|
|
Loading…
Reference in a new issue