From 8c961a148b5e0fccb899702ad21de322cea28409 Mon Sep 17 00:00:00 2001 From: PeterWaIIace Date: Wed, 23 Oct 2024 18:06:21 +0200 Subject: [PATCH 1/5] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d689314..f63cbe2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ exclude = [ [project] name = "eyeGestures" -version = "2.5.4" +version = "2.7.4" authors = [ { name="Piotr Walas", email="piotr.walas@eyegestures.com" }, ] From 346aa87ea4e1ae04731e6873fb0005f47d6b5636 Mon Sep 17 00:00:00 2001 From: PeterWaIIace Date: Mon, 28 Oct 2024 22:48:23 +0100 Subject: [PATCH 2/5] adding post_fit with crossvalidated lasso --- eyeGestures/calibration_v2.py | 22 ++++++++++++++++++++-- eyeGestures/eyegestures.py | 5 +++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/eyeGestures/calibration_v2.py b/eyeGestures/calibration_v2.py index 733bbff..d7f5107 100644 --- a/eyeGestures/calibration_v2.py +++ b/eyeGestures/calibration_v2.py @@ -17,9 +17,10 @@ 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.fitted = False + self.cv_not_set = True self.matrix = CalibrationMatrix() @@ -41,7 +42,24 @@ def add(self,x,y): self.reg_y.fit(__tmp_X,__tmp_Y_y) self.fitted = True + def post_fit(self): + if self.cv_not_set: + self.reg_x = scireg.LassoCV(cv=50) + self.reg_y = scireg.LassoCV(cv=50) + + __tmp_X = np.array(self.X) + __tmp_Y_y = np.array(self.Y_y) + __tmp_Y_x = np.array(self.Y_x) + + self.reg_x.fit(__tmp_X,__tmp_Y_x) + self.reg_y.fit(__tmp_X,__tmp_Y_y) + self.fitted = True + + self.cv_not_set = False + + def predict(self,x): + if self.fitted: x = x.flatten() x = x.reshape(1, -1) diff --git a/eyeGestures/eyegestures.py b/eyeGestures/eyegestures.py index 0b9f4df..10be02b 100644 --- a/eyeGestures/eyegestures.py +++ b/eyeGestures/eyegestures.py @@ -136,18 +136,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) From fb47ff5e49c346d8efd08572054660c3ddbbbd78 Mon Sep 17 00:00:00 2001 From: PeterWaIIace Date: Tue, 5 Nov 2024 01:16:48 +0100 Subject: [PATCH 3/5] adding async coroutine --- examples/simple_example_v2.py | 6 +++- eyeGestures/calibration_v2.py | 53 ++++++++++++++++++++++++----------- eyeGestures/eyegestures.py | 14 ++++++++- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/examples/simple_example_v2.py b/examples/simple_example_v2.py index f8cdd2c..752cf9e 100644 --- a/examples/simple_example_v2.py +++ b/examples/simple_example_v2.py @@ -67,7 +67,7 @@ ret, frame = cap.read() frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - calibrate = (iterator <= 25) # calibrate 25 points + calibrate = (iterator <= 10) # calibrate 25 points event, calibration = gestures.step(frame, calibrate, screen_width, screen_height, context="my_context") @@ -95,6 +95,10 @@ else: pass pygame.draw.circle(screen, RED, 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 diff --git a/eyeGestures/calibration_v2.py b/eyeGestures/calibration_v2.py index d7f5107..b41a85c 100644 --- a/eyeGestures/calibration_v2.py +++ b/eyeGestures/calibration_v2.py @@ -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) @@ -19,6 +21,7 @@ def __init__(self,CALIBRATION_RADIUS=1000): self.reg = None 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 @@ -29,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]) @@ -42,32 +48,47 @@ def add(self,x,y): self.reg_y.fit(__tmp_X,__tmp_Y_y) self.fitted = True - def post_fit(self): - if self.cv_not_set: - self.reg_x = scireg.LassoCV(cv=50) - self.reg_y = scireg.LassoCV(cv=50) + # 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) - self.reg_x.fit(__tmp_X,__tmp_Y_x) - self.reg_y.fit(__tmp_X,__tmp_Y_y) - self.fitted = True + 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() diff --git a/eyeGestures/eyegestures.py b/eyeGestures/eyegestures.py index 10be02b..76a2d70 100644 --- a/eyeGestures/eyegestures.py +++ b/eyeGestures/eyegestures.py @@ -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 @@ -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 @@ -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 @@ -137,7 +149,7 @@ 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: From b45361260eb2d02f648a047a95692e70d7d460e7 Mon Sep 17 00:00:00 2001 From: PeterWaIIace Date: Tue, 5 Nov 2024 01:17:17 +0100 Subject: [PATCH 4/5] fixing v2 demo --- examples/simple_example_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple_example_v2.py b/examples/simple_example_v2.py index 752cf9e..06130e9 100644 --- a/examples/simple_example_v2.py +++ b/examples/simple_example_v2.py @@ -67,7 +67,7 @@ ret, frame = cap.read() frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - calibrate = (iterator <= 10) # calibrate 25 points + calibrate = (iterator <= 25) # calibrate 25 points event, calibration = gestures.step(frame, calibrate, screen_width, screen_height, context="my_context") From ad6c5a7c582735e72e3079fedd06c0c7f006a697 Mon Sep 17 00:00:00 2001 From: PeterWaIIace Date: Tue, 5 Nov 2024 01:28:07 +0100 Subject: [PATCH 5/5] updating example --- examples/simple_example_v2.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/simple_example_v2.py b/examples/simple_example_v2.py index 06130e9..89eda71 100644 --- a/examples/simple_example_v2.py +++ b/examples/simple_example_v2.py @@ -94,7 +94,10 @@ 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)