Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #33

Merged
merged 6 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion examples/simple_example_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,14 @@
screen.blit(text_surface, text_square)
else:
pass
pygame.draw.circle(screen, RED, event.point, 50)
if gestures.whichAlgorithm(context="my_context") == "Ridge":
pygame.draw.circle(screen, RED, event.point, 50)
if gestures.whichAlgorithm(context="my_context") == "LassoCV":
pygame.draw.circle(screen, BLUE, event.point, 50)
my_font = pygame.font.SysFont('Comic Sans MS', 30)
text_surface = my_font.render(f'{gestures.whichAlgorithm(context="my_context")}', False, (0, 0, 0))
screen.blit(text_surface, event.point)

pygame.display.flip()

# Cap the frame rate
Expand Down
59 changes: 49 additions & 10 deletions eyeGestures/calibration_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import sklearn.linear_model as scireg
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
import asyncio
import threading

def euclidean_distance(point1, point2):
return np.linalg.norm(point1 - point2)
Expand All @@ -17,9 +19,11 @@ def __init__(self,CALIBRATION_RADIUS=1000):
self.Y_y = []
self.Y_x = []
self.reg = None
self.reg_x = scireg.Lasso(alpha=0.5)
self.reg_y = scireg.Lasso(alpha=0.5)
self.reg_x = scireg.Ridge(alpha=0.5)
self.reg_y = scireg.Ridge(alpha=0.5)
self.current_algorithm = "Ridge"
self.fitted = False
self.cv_not_set = True

self.matrix = CalibrationMatrix()

Expand All @@ -28,6 +32,9 @@ def __init__(self,CALIBRATION_RADIUS=1000):
self.acceptance_radius = int(CALIBRATION_RADIUS/2)
self.calibration_radius = int(CALIBRATION_RADIUS)

self.lock = threading.Lock()
self.calcualtion_coroutine = threading.Thread(target=self.__async_fit)

def add(self,x,y):
self.X.append(x.flatten())
self.Y_y.append(y[1])
Expand All @@ -41,15 +48,47 @@ def add(self,x,y):
self.reg_y.fit(__tmp_X,__tmp_Y_y)
self.fitted = True

# This coroutine helps to asynchronously recalculate results
def __async_fit(self):
try:
tmp_fixations_x = scireg.LassoCV(cv=50,max_iter=5000)
tmp_fixations_y = scireg.LassoCV(cv=50,max_iter=5000)

__tmp_X = np.array(self.X)
__tmp_Y_y = np.array(self.Y_y)
__tmp_Y_x = np.array(self.Y_x)

tmp_fixations_x.fit(__tmp_X,__tmp_Y_x)
tmp_fixations_y.fit(__tmp_X,__tmp_Y_y)

with self.lock:
self.fixations_x = tmp_fixations_x
self.fixations_y = tmp_fixations_y
self.fitted = True
self.current_algorithm = "LassoCV"
except Exception as e:
print(f"Exception as {e}")
self.cv_not_set = True

def post_fit(self):
if self.cv_not_set:
self.calcualtion_coroutine.start()
self.cv_not_set = False

def whichAlgorithm(self):
with self.lock:
return self.current_algorithm

def predict(self,x):
if self.fitted:
x = x.flatten()
x = x.reshape(1, -1)
y_x = self.reg_x.predict(x)[0]
y_y = self.reg_y.predict(x)[0]
return np.array([y_x,y_y])
else:
return np.array([0.0,0.0])
with self.lock:
if self.fitted:
x = x.flatten()
x = x.reshape(1, -1)
y_x = self.reg_x.predict(x)[0]
y_y = self.reg_y.predict(x)[0]
return np.array([y_x,y_y])
else:
return np.array([0.0,0.0])

def movePoint(self):
self.matrix.movePoint()
Expand Down
19 changes: 16 additions & 3 deletions eyeGestures/eyegestures.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def __init__(self, calibration_radius = 1000):
self.CN = 5

self.average_points = dict()
self.average_points_saccades = dict()
self.average_points_fixations = dict()
self.iterator = dict()
self.filled_points= dict()
self.enable_CN = False
Expand Down Expand Up @@ -73,6 +75,12 @@ def getLandmarks(self, frame, calibrate = False, context="main"):
return np.array((cursor_x, cursor_y)), key_points, event.blink, event.fixation, cevent
return np.array((0.0, 0.0)), np.array([]), 0, 0, None

def whichAlgorithm(self,context="main"):
if context in self.clb:
return self.clb[context].whichAlgorithm()
else:
return "None"

def setClassicImpact(self,impact):
self.CN = impact

Expand All @@ -97,8 +105,12 @@ def addContext(self, context):
if context not in self.clb:
self.clb[context] = Calibrator_v2(self.calibration_radius)
self.average_points[context] = Buffor(20)
self.average_points_saccades[context] = Buffor(20)
self.average_points_fixations[context] = Buffor(20)
self.iterator[context] = 0
self.average_points[context] = np.zeros((20,2))
self.average_points_saccades[context] = np.zeros((20,2))
self.average_points_fixations[context] = np.zeros((20,2))
self.filled_points[context] = 0
self.calibration[context] = False

Expand Down Expand Up @@ -136,18 +148,19 @@ def step(self, frame, calibration, width, height, context="main"):

if self.filled_points[context] < self.average_points[context].shape[0] and (y_point != np.array([0.0,0.0])).any():
self.filled_points[context] += 1

averaged_point = (np.sum(self.average_points[context][:,:],axis=0) + (classic_point * self.CN))/(self.filled_points[context] + self.CN)

if self.calibration[context] and (self.clb[context].insideClbRadius(averaged_point,width,height) or self.filled_points[context] < self.average_points[context].shape[0] * 10):
self.clb[context].add(key_points,self.clb[context].getCurrentPoint(width,height))
else:
self.clb[context].post_fit()

if self.calibration[context] and self.clb[context].insideAcptcRadius(averaged_point,width,height):
self.iterator[context] += 1
if self.iterator[context] > 10:
self.iterator[context] = 0
self.clb[context].movePoint()
# self.clb[context].increase_precision()


gevent = Gevent(averaged_point,blink,fixation)
cevent = Cevent(self.clb[context].getCurrentPoint(width,height),self.clb[context].acceptance_radius, self.clb[context].calibration_radius)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ exclude = [

[project]
name = "eyeGestures"
version = "2.5.4"
version = "2.7.4"
authors = [
{ name="Piotr Walas", email="[email protected]" },
]
Expand Down