mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-11-04 14:39:42 +08:00
83 lines
2.5 KiB
Python
83 lines
2.5 KiB
Python
import os
|
|
import typing
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Union
|
|
|
|
is_nt = True if os.name == "nt" else False
|
|
is_macos = True if os.uname().sysname == "Darwin" else False
|
|
|
|
|
|
def PlaySound(*args, **kwargs):
|
|
pass
|
|
|
|
|
|
SND_FILENAME = SND_ASYNC = 1
|
|
|
|
if is_nt:
|
|
import winsound
|
|
|
|
PlaySound = winsound.PlaySound
|
|
SND_FILENAME = winsound.SND_FILENAME
|
|
SND_ASYNC = winsound.SND_ASYNC
|
|
|
|
|
|
def clamp(x, low, high):
|
|
return max(low, min(x, high))
|
|
|
|
|
|
def lst_median(lst, ordered=False):
|
|
# https://github.com/emilianavt/OpenSeeFace/blob/6f24efc4f58eb7cca47ec2146d934eabcc207e46/remedian.py
|
|
assert lst, "median needs a non-empty list"
|
|
n = len(lst)
|
|
p = q = n // 2
|
|
if n < 3:
|
|
p, q = 0, n - 1
|
|
else:
|
|
lst = lst if ordered else sorted(lst)
|
|
if not n % 2: # for even-length lists, use mean of mid 2 nums
|
|
q = p - 1
|
|
return lst[p] if p == q else (lst[p] + lst[q]) / 2
|
|
|
|
|
|
class FastMedian:
|
|
# https://github.com/emilianavt/OpenSeeFace/blob/6f24efc4f58eb7cca47ec2146d934eabcc207e46/remedian.py
|
|
# Initialization
|
|
def __init__(self, inits: typing.Optional[typing.Sequence] = [], k=64): # after some experimentation, 64 works ok
|
|
self.all, self.k = [], k
|
|
self.more, self.__median = None, None
|
|
if inits is not None:
|
|
[self + x for x in inits]
|
|
|
|
# When full, push the median of current values to next list, then reset.
|
|
def __add__(self, x):
|
|
self.__median = None
|
|
self.all.append(x) # It would be faster to pre-allocate an array and assign it by index.
|
|
if len(self.all) == self.k:
|
|
self.more = self.more or FastMedian(k=self.k)
|
|
self.more + self.__medianPrim(self.all)
|
|
# It's going to be slower because of the re-allocation.
|
|
self.all = [] # reset
|
|
|
|
# If there is a next list, ask its median. Else, work it out locally.
|
|
def median(self):
|
|
return self.more.median() if self.more else self.__medianPrim(self.all)
|
|
|
|
# Only recompute median if we do not know it already.
|
|
def __medianPrim(self, all):
|
|
if self.__median is None:
|
|
self.__median = lst_median(all, ordered=False)
|
|
return self.__median
|
|
|
|
def resource_path(relative_path: Union[str, Path]) -> str:
|
|
"""
|
|
Get absolute path to resource, works for dev and for PyInstaller
|
|
"""
|
|
try:
|
|
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
base_path = Path(sys._MEIPASS)
|
|
except AttributeError:
|
|
base_path = Path(".")
|
|
|
|
return str(base_path / relative_path)
|