Adds new config vars fixes filter pop error

In additon resets caibration data for IBO on recalibrate
This commit is contained in:
Etheri 2023-06-16 13:06:36 +02:00
parent 8569009fb1
commit 9284f97b09
7 changed files with 50 additions and 30 deletions

View File

@ -34,6 +34,7 @@ class CameraWidget:
self.gui_mode_readout = f"-APPMODE{widget_id}-"
self.gui_roi_message = f"-ROIMESSAGE{widget_id}-"
self.last_eye_info = None
self.osc_queue = osc_queue
self.main_config = main_config
self.eye_id = widget_id
@ -266,7 +267,8 @@ class CameraWidget:
self.x1, self.y1 = values[self.gui_roi_selection]
if event == self.gui_restart_calibration:
self.ransac.calibration_frame_counter = 300
self.ransac.calibration_frame_counter = self.settings.calibration_samples
self.ransac.ibo.clear_filter()
PlaySound('Audio/start.wav', SND_FILENAME | SND_ASYNC)
if event == self.gui_stop_calibration:

View File

@ -65,6 +65,11 @@ class EyeTrackSettingsConfig(BaseModel):
gui_vrc_native: bool = True
gui_circular_crop_right: bool = False
gui_circular_crop_left: bool = False
ibo_filter_samples: int = 400
ibo_average_output_samples: int = 0
ibo_fully_close_eye_threshold: float = 0.3
calibration_samples: int = 600
class EyeTrackConfig(BaseModel):

View File

@ -247,20 +247,18 @@ class EyeProcessor:
def UPDATE(self):
# print(self.blink_clear)
if self.settings.gui_BLINK:
self.eyeopen = BLINK(self)
if self.settings.gui_IBO:
self.eyeopen = self.ibo.intense(self.rawx, self.rawy, self.current_image_white)
if self.eyeopen < 0.35: #threshold so the eye fully closes #todo: make this a setting?
self.eyeopen = self.ibo.intense(self.rawx, self.rawy, self.current_image_white,self.settings.ibo_filter_samples,self.settings.ibo_average_output_samples)
if self.eyeopen < self.settings.ibo_fully_close_eye_threshold: #threshold so the eye fully closes
self.eyeopen = 0.0
if self.bd_blink == True:
pass
# self.eyeopen = 0.0
if self.settings.gui_IBO and self.settings.gui_BLINK:
ibo = self.ibo.intense(self.rawx, self.rawy, self.current_image_white)
ibo = self.ibo.intense(self.rawx, self.rawy, self.current_image_white,self.settings.ibo_filter_samples,self.settings.ibo_average_output_samples)
blink = BLINK(self)
if blink == 0.0:

View File

@ -241,7 +241,6 @@ def main():
elif values[BOTH_EYE_RADIO_NAME] and config.eye_display_id != EyeId.BOTH:
settings[0].stop()
settings[1].stop()
eyes[0].stop()
eyes[1].start()
eyes[0].start()
window[LEFT_EYE_NAME].update(visible=True)
@ -277,15 +276,15 @@ def main():
config.eye_display_id = EyeId.ALGOSETTINGS
config.save()
# Otherwise, render all
for eye in eyes:
if eye.started():
eye.render(window, event, values)
for setting in settings:
if setting.started():
setting.render(window, event, values)
# settings[0].render(window, event, values)
# settings[1].render(window, event, values)
else:
# Otherwise, render all
for eye in eyes:
if eye.started():
eye.render(window, event, values)
for setting in settings:
if setting.started():
setting.render(window, event, values)
if __name__ == "__main__":

View File

@ -130,13 +130,16 @@ class IntensityBasedOpeness:
self.img_roi = np.zeros(3, dtype=np.int32)
self.now_roi = np.zeros(3, dtype=np.int32)
self.prev_val = 0.5
self.avg_intensity = 0.0
self.old = []
self.color = []
self.x = []
self.fc = 0
self.filterlist = []
self.averageList = []
self.eye_id = eye_id
self.maxinten = 0
@ -213,7 +216,14 @@ class IntensityBasedOpeness:
def change_roi(self, roiinfo: dict):
self.now_roi[:] = [v for v in roiinfo.values()]
def intense(self, x, y, frame):
def clear_filter(self):
self.data = None
self.filterlist.clear()
self.averageList.clear()
if os.path.exists(self.imgfile):
os.remove(self.imgfile)
def intense(self, x, y, frame,filterSamples,outputSamples):
# x,y = 0~(frame.shape[1 or 0]-1), frame = 1-channel frame cropped by ROI
self.check(frame.shape)
int_x, int_y = int(x), int(y)
@ -237,10 +247,10 @@ class IntensityBasedOpeness:
#cv2.imshow('e', frame)
# if cv2.waitKey(10) == 27:
# exit()
if len(self.filterlist) < 800:
if len(self.filterlist) < filterSamples:
self.filterlist.append(intensity)
else:
self.filterlist.pop()
self.filterlist.pop(0)
self.filterlist.append(intensity)
if intensity >= np.percentile(self.filterlist, 99): # filter abnormally high values
@ -287,7 +297,7 @@ class IntensityBasedOpeness:
oob = True
# print('CAUGHT Y UNDER BOUNDS')
if oob != True:
if oob != True and self.data.any():
data_val = self.data[int_y, int_x]
else:
data_val = 0
@ -325,18 +335,22 @@ class IntensityBasedOpeness:
maxp = self.data[int_y, int_x]
minp = self.maxval
eyeopen = ((intensity - maxp) / (minp - maxp)) #for whatever reason when input and maxp are too close it outputs high
# print(eyeopen, maxp, minp)
# eyeopen = ((eyeopen - 0.3) / (1.0 - 0.3))
eyeopen = 1 - eyeopen
# print(eyeopen, intensity, maxp, minp, x, y)
if outputSamples > 0:
if len(self.averageList) < outputSamples:
self.averageList.append(eyeopen)
else:
self.averageList.pop(0)
self.averageList.append(eyeopen)
eyeopen=np.average(self.averageList)
if changed and ((time.time() - self.lct) > 5): # save every 5 seconds if something changed to save disk usage
self.save()
self.lct = time.time()
# print(self.prev_val, eyeopen, intensity, self.maxval)
#@filter_eyeopen = (eyeopen + self.prev_val) / 2
self.prev_val = eyeopen
try:

View File

@ -97,6 +97,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
self.l_eye_x = eye_x
self.l_eye_blink = eye_blink
self.left_y = eye_y
self.client.send_message("/avatar/parameters/RightClosed",float(1 - eye_blink))
if self.l_eye_blink == 0.0:
if last_blink > 0.7: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
@ -118,6 +119,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
self.r_eye_x = eye_x
self.r_eye_blink = eye_blink
self.right_y = eye_y
self.client.send_message("/avatar/parameters/RightClosed",float(1 - eye_blink))
if self.r_eye_blink == 0.0:
if last_blink > 0.7: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
@ -149,7 +151,6 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
eye_y = (self.right_y + self.left_y) / 2
if not se:
self.client.send_message("/tracking/eye/LeftRightVec",
[float(self.l_eye_x), float(eye_y), 0.8, float(self.r_eye_x), float(eye_y),
0.8]) # vrc native ET (z values may need tweaking, they act like a scalar)
@ -215,7 +216,8 @@ class VRChatOSCReceiver:
if type(osc_value) != bool: return # just incase we get anything other than bool
if osc_value:
for eye in self.eyes:
eye.ransac.calibration_frame_counter = 300
eye.ransac.ibo.clear_filter()
eye.ransac.calibration_frame_counter = self.settings.calibration_samples
PlaySound('Audio/start.wav', SND_FILENAME | SND_ASYNC)
def run(self):

View File

@ -21,7 +21,7 @@ class cal():
self.config.calib_XOFF = cx
self.config.calib_YOFF = cy
PlaySound('Audio/completed.wav', SND_FILENAME | SND_ASYNC)
if self.calibration_frame_counter == 300:
if self.calibration_frame_counter == self.settings.calibration_samples:
self.config.calib_XMAX = -69420
self.config.calib_XMIN = 69420
self.config.calib_YMAX = -69420