Storing metrics + displaying table
This commit is contained in:
parent
d37c50e394
commit
6d7c870be3
1 changed files with 47 additions and 10 deletions
|
@ -15,13 +15,18 @@ import subprocess
|
||||||
import json
|
import json
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import termios, fcntl, os
|
import termios, fcntl, os
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
|
||||||
class Heatmap:
|
class Heatmap:
|
||||||
def __init__(self, metricsSize, logger, coordinates_filename):
|
def __init__(self, metricsSize, logger, coordinates_filename, tag):
|
||||||
self.coordinates_filename = coordinates_filename
|
self.coordinates_filename = coordinates_filename
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.metricsSize = metricsSize
|
self.metricsSize = metricsSize
|
||||||
self.metrics = np.zeros((metricsSize[1], metricsSize[0])) # (y, x)
|
self.tag = tag
|
||||||
|
self.metricSaveDiff = 60*5 # save metrics every 5 minutes
|
||||||
|
self.loadMetrics()
|
||||||
|
|
||||||
self.screenDrawCorners = np.array([
|
self.screenDrawCorners = np.array([
|
||||||
[0,0],
|
[0,0],
|
||||||
[metricsSize[0]-1,0],
|
[metricsSize[0]-1,0],
|
||||||
|
@ -32,15 +37,17 @@ class Heatmap:
|
||||||
self.loadCoordinates()
|
self.loadCoordinates()
|
||||||
self.windowRoot = Tk.Tk()
|
self.windowRoot = Tk.Tk()
|
||||||
self.windowRoot.geometry('800x600+4000+0')
|
self.windowRoot.geometry('800x600+4000+0')
|
||||||
|
self.windowRoot.title('Heatmap')
|
||||||
self.windowRoot.attributes("-fullscreen", True)
|
self.windowRoot.attributes("-fullscreen", True)
|
||||||
imageWindowSize = tuple(metricsSize)
|
imageWindowSize = tuple(metricsSize)
|
||||||
# self.windowRoot.geometry('%dx%d+%d+%d' % (imageWindowSize[0],imageWindowSize[1],0,0)) # we go full screen so not needed
|
# self.windowRoot.geometry('%dx%d+%d+%d' % (imageWindowSize[0],imageWindowSize[1],0,0)) # we go full screen so not needed
|
||||||
self.canvas = Tk.Canvas(self.windowRoot,width=imageWindowSize[0],height=imageWindowSize[1],bd=0, highlightthickness=0, relief='ridge')
|
self.canvas = Tk.Canvas(self.windowRoot,width=imageWindowSize[0],height=imageWindowSize[1],bd=0, highlightthickness=0, relief='ridge')
|
||||||
self.canvas.pack(fill="both", expand=True)
|
self.canvas.pack(fill="both", expand=True)
|
||||||
|
|
||||||
self.mapSize = [1200,400]
|
self.mapSize = [1600,600]
|
||||||
self.mapWindowRoot = Tk.Toplevel(master=self.windowRoot)
|
self.mapWindowRoot = Tk.Toplevel(master=self.windowRoot)
|
||||||
self.mapWindowRoot.geometry('%dx%d' % tuple(self.mapSize))
|
self.mapWindowRoot.geometry('%dx%d+0+800' % tuple(self.mapSize))
|
||||||
|
self.mapWindowRoot.title("Tracking Overview")
|
||||||
self.mapCanvas = Tk.Canvas(self.mapWindowRoot,width=self.mapSize[0],height=self.mapSize[1],bd=0, highlightthickness=0, relief='ridge')
|
self.mapCanvas = Tk.Canvas(self.mapWindowRoot,width=self.mapSize[0],height=self.mapSize[1],bd=0, highlightthickness=0, relief='ridge')
|
||||||
self.mapCanvas.create_rectangle(20, 50, 22, 350, fill="black", width=0, tags="screenTop")
|
self.mapCanvas.create_rectangle(20, 50, 22, 350, fill="black", width=0, tags="screenTop")
|
||||||
self.mapCanvas.create_rectangle(600, 50, 602, 300, fill="black", width=0, tags="screenSide")
|
self.mapCanvas.create_rectangle(600, 50, 602, 300, fill="black", width=0, tags="screenSide")
|
||||||
|
@ -79,6 +86,25 @@ class Heatmap:
|
||||||
self.logger.info("Window size: %s", self.windowGeometry)
|
self.logger.info("Window size: %s", self.windowGeometry)
|
||||||
self.updateWindow()
|
self.updateWindow()
|
||||||
|
|
||||||
|
def getOutputPrefix(self):
|
||||||
|
return "output/metrics-%s-%dx%d-" % (self.tag, self.metricsSize[0], self.metricsSize[1])
|
||||||
|
|
||||||
|
def loadMetrics(self):
|
||||||
|
list_of_files = glob.glob('%s*.p' % self.getOutputPrefix())
|
||||||
|
if len(list_of_files) < 1:
|
||||||
|
self.metrics = np.zeros((self.metricsSize[1], self.metricsSize[0])) # (y, x)
|
||||||
|
else:
|
||||||
|
latest_file = max(list_of_files, key=os.path.getctime)
|
||||||
|
with open(latest_file, "rb") as f:
|
||||||
|
self.metrics = pickle.load(f)
|
||||||
|
self.lastMetricSave = time.time()
|
||||||
|
|
||||||
|
def saveMetrics(self):
|
||||||
|
name = "{}{}.p".format(self.getOutputPrefix(), time.strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
|
with open(name, "wb") as fp:
|
||||||
|
pickle.dump(self.metrics, fp)
|
||||||
|
self.lastMetricSave = time.time()
|
||||||
|
|
||||||
def onKeyPress(self, event=None, charachter=None):
|
def onKeyPress(self, event=None, charachter=None):
|
||||||
if event is None and charachter is not None:
|
if event is None and charachter is not None:
|
||||||
k = charachter
|
k = charachter
|
||||||
|
@ -124,6 +150,8 @@ class Heatmap:
|
||||||
def keepWindowUpdated(self):
|
def keepWindowUpdated(self):
|
||||||
while True:
|
while True:
|
||||||
self.updateWindow()
|
self.updateWindow()
|
||||||
|
if time.time() - self.lastMetricSave > self.metricSaveDiff:
|
||||||
|
self.saveMetrics()
|
||||||
|
|
||||||
def updateFromJson(self, frame):
|
def updateFromJson(self, frame):
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
|
@ -168,7 +196,7 @@ class Heatmap:
|
||||||
dz = face['head_pos'][2]/mmPerPixel # front/back
|
dz = face['head_pos'][2]/mmPerPixel # front/back
|
||||||
|
|
||||||
p1x = int(20 + dz)
|
p1x = int(20 + dz)
|
||||||
p1y = int(virtualWidth / 2 + 50 + dx)
|
p1y = int(virtualWidth / 2 + 50 - dx)
|
||||||
|
|
||||||
p2x = int(600 + dz)
|
p2x = int(600 + dz)
|
||||||
p2y = int(virtualHeight / 2 + 50 + dy)
|
p2y = int(virtualHeight / 2 + 50 + dy)
|
||||||
|
@ -176,7 +204,7 @@ class Heatmap:
|
||||||
self.mapCanvas.create_oval(p2x-3, p2y-3, p2x+3, p2y+3, fill="red", width=0, tags="figure")
|
self.mapCanvas.create_oval(p2x-3, p2y-3, p2x+3, p2y+3, fill="red", width=0, tags="figure")
|
||||||
|
|
||||||
p3x = int(20)
|
p3x = int(20)
|
||||||
p3y = int(float(face['target'][0]) / self.metricsSize[0] * virtualWidth + 50)
|
p3y = int(virtualWidth + 50 - (float(face['target'][0]) / self.metricsSize[0] * virtualWidth))
|
||||||
|
|
||||||
p4x = int(600)
|
p4x = int(600)
|
||||||
p4y = int(float(face['target'][1]) / self.metricsSize[1] * virtualHeight + 50)
|
p4y = int(float(face['target'][1]) / self.metricsSize[1] * virtualHeight + 50)
|
||||||
|
@ -185,7 +213,13 @@ class Heatmap:
|
||||||
|
|
||||||
self.logger.debug("DRAW FACE TO", face, (p1x,p1y), "AND", (p2x,p2y))
|
self.logger.debug("DRAW FACE TO", face, (p1x,p1y), "AND", (p2x,p2y))
|
||||||
|
|
||||||
|
def updateTable(self):
|
||||||
|
# clear terminal
|
||||||
|
os.system('cls' if os.name == 'nt' else 'clear')
|
||||||
|
print("{} gazes".format(len(self.currentTargets)))
|
||||||
|
print("{:>5} {:>10} {:>10} {:>10} {:>5} {:>5}".format(" ", "x", "y", "z", "angle", "angle", ))
|
||||||
|
for face in self.currentTargets:
|
||||||
|
print(u"{:>5} {:>10} mm {:>10} mm {:>10} mm {:>5.2f}\xb0 {:>5.2f}\xb0".format(face['fid'], face['head_pos'][0], face['head_pos'][1], face['head_pos'][2], face['gaze_angle'][0], face['gaze_angle'][1]))
|
||||||
|
|
||||||
def updateWindow(self):
|
def updateWindow(self):
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
|
@ -193,9 +227,11 @@ class Heatmap:
|
||||||
# convert to colormap, thanks to: https://stackoverflow.com/a/10967471
|
# convert to colormap, thanks to: https://stackoverflow.com/a/10967471
|
||||||
colormap = cm.plasma
|
colormap = cm.plasma
|
||||||
colormap = cm.CMRmap
|
colormap = cm.CMRmap
|
||||||
|
colormap = cm.nipy_spectral
|
||||||
normalisedMetrics = np.uint8(colormap(normalisedMetrics)*255)
|
normalisedMetrics = np.uint8(colormap(normalisedMetrics)*255)
|
||||||
image = Image.fromarray(normalisedMetrics)
|
image = Image.fromarray(normalisedMetrics)
|
||||||
self.updateMap()
|
self.updateMap()
|
||||||
|
self.updateTable()
|
||||||
# Too clunky for now:
|
# Too clunky for now:
|
||||||
# if len(self.currentTargets) > 0:
|
# if len(self.currentTargets) > 0:
|
||||||
# c = ImageDraw.Draw(image)
|
# c = ImageDraw.Draw(image)
|
||||||
|
@ -264,7 +300,7 @@ class Heatmap:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main(openface_exec, coordinates_filename, device=0):
|
def main(openface_exec, coordinates_filename, tag, device=0):
|
||||||
|
|
||||||
logging.basicConfig( format='%(asctime)-15s %(name)s %(levelname)s: %(message)s' )
|
logging.basicConfig( format='%(asctime)-15s %(name)s %(levelname)s: %(message)s' )
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -285,7 +321,7 @@ def main(openface_exec, coordinates_filename, device=0):
|
||||||
metricsSize = [1920/2,1080/2]
|
metricsSize = [1920/2,1080/2]
|
||||||
metricsSize = [800,600]
|
metricsSize = [800,600]
|
||||||
|
|
||||||
heatmap = Heatmap(metricsSize, logger, coordinates_filename)
|
heatmap = Heatmap(metricsSize, logger, coordinates_filename, tag)
|
||||||
# heatmap.runCam(openface_exec, device)
|
# heatmap.runCam(openface_exec, device)
|
||||||
thread = Thread(target=heatmap.runCam, args=(openface_exec, device))
|
thread = Thread(target=heatmap.runCam, args=(openface_exec, device))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
@ -416,7 +452,8 @@ if __name__ == '__main__':
|
||||||
parser.add_argument('--of', default="../build/bin/FaceLandmarkVidMulti", help='The modified version of OpenFace\'s FaceLandmarkVidMulti')
|
parser.add_argument('--of', default="../build/bin/FaceLandmarkVidMulti", help='The modified version of OpenFace\'s FaceLandmarkVidMulti')
|
||||||
parser.add_argument('--coordinates', default="coordinates.p", help='Use a specific coordinates.p file')
|
parser.add_argument('--coordinates', default="coordinates.p", help='Use a specific coordinates.p file')
|
||||||
parser.add_argument('--device', type=int, default=0, help='Webcam device nr. to use')
|
parser.add_argument('--device', type=int, default=0, help='Webcam device nr. to use')
|
||||||
|
parser.add_argument('--tag', type=str, default="default", help='Heatmap instance. Determines the name of saved (& thus loaded) files')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
main(openface_exec=args.of, coordinates_filename=args.coordinates, device=args.device)
|
main(openface_exec=args.of, coordinates_filename=args.coordinates, device=args.device, tag=args.tag)
|
||||||
|
|
Loading…
Reference in a new issue