mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-11-04 14:39:42 +08:00
Merge pull request #85 from EtheriVR/Etheri-Improvements-And-Fixes
Etheri improvements and fixes
This commit is contained in:
commit
a00823b154
@ -45,6 +45,9 @@ class AlgoSettingsWidget:
|
|||||||
self.gui_threshold_slider = f"-BLOBTHRESHOLD{widget_id}-"
|
self.gui_threshold_slider = f"-BLOBTHRESHOLD{widget_id}-"
|
||||||
self.gui_HSF_radius_left = f"-HSFRADIUSLEFT{widget_id}-"
|
self.gui_HSF_radius_left = f"-HSFRADIUSLEFT{widget_id}-"
|
||||||
self.gui_HSF_radius_right = f"-HSFRADIUSRIGHT{widget_id}-"
|
self.gui_HSF_radius_right = f"-HSFRADIUSRIGHT{widget_id}-"
|
||||||
|
self.ibo_filter_samples = f"-IBOFILTERSAMPLE{widget_id}-"
|
||||||
|
self.calibration_samples = f"-CALIBRATIONSAMPLES{widget_id}-"
|
||||||
|
self.ibo_fully_close_eye_threshold = f"-CLOSETHRESH{widget_id}-"
|
||||||
self.main_config = main_config
|
self.main_config = main_config
|
||||||
self.config = main_config.settings
|
self.config = main_config.settings
|
||||||
self.osc_queue = osc_queue
|
self.osc_queue = osc_queue
|
||||||
@ -146,6 +149,9 @@ class AlgoSettingsWidget:
|
|||||||
),
|
),
|
||||||
sg.Text("Blob", background_color='#424042'),
|
sg.Text("Blob", background_color='#424042'),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
sg.Text("Blink Algo Settings:", background_color='#242224')
|
||||||
|
],
|
||||||
[
|
[
|
||||||
sg.Checkbox(
|
sg.Checkbox(
|
||||||
"Intensity Based Openness",
|
"Intensity Based Openness",
|
||||||
@ -159,6 +165,29 @@ class AlgoSettingsWidget:
|
|||||||
key=self.gui_BLINK,
|
key=self.gui_BLINK,
|
||||||
background_color='#424042',
|
background_color='#424042',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
sg.Text("IBO Filter Sample Size", background_color='#424042'),
|
||||||
|
sg.InputText(
|
||||||
|
self.config.ibo_filter_samples,
|
||||||
|
key=self.ibo_filter_samples,
|
||||||
|
size=(0,10),
|
||||||
|
),
|
||||||
|
sg.Text("Calibration Samples", background_color='#424042'),
|
||||||
|
sg.InputText(
|
||||||
|
self.config.calibration_samples,
|
||||||
|
key=self.calibration_samples,
|
||||||
|
size=(0,10),
|
||||||
|
),
|
||||||
|
|
||||||
|
sg.Text("IBO Close Threshold", background_color='#424042'),
|
||||||
|
sg.InputText(
|
||||||
|
self.config.ibo_fully_close_eye_threshold,
|
||||||
|
key=self.ibo_fully_close_eye_threshold,
|
||||||
|
size=(0,10),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
sg.Checkbox(
|
sg.Checkbox(
|
||||||
@ -174,7 +203,9 @@ class AlgoSettingsWidget:
|
|||||||
background_color='#424042',
|
background_color='#424042',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
sg.Text("Advanced Tracking Algorithim Settings:", background_color='#242224')
|
||||||
|
],
|
||||||
[sg.Checkbox(
|
[sg.Checkbox(
|
||||||
"HSF: Skip Auto Radius",
|
"HSF: Skip Auto Radius",
|
||||||
default=self.config.gui_skip_autoradius,
|
default=self.config.gui_skip_autoradius,
|
||||||
@ -255,7 +286,7 @@ class AlgoSettingsWidget:
|
|||||||
|
|
||||||
self.widget_layout = [
|
self.widget_layout = [
|
||||||
[
|
[
|
||||||
sg.Text("Tracking Algorithm Settings:", background_color='#242224'),
|
sg.Text("Tracking Algorithm Order Settings:", background_color='#242224'),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
sg.Column(self.general_settings_layout, key=self.gui_general_settings_layout, background_color='#424042' ),
|
sg.Column(self.general_settings_layout, key=self.gui_general_settings_layout, background_color='#424042' ),
|
||||||
@ -366,6 +397,18 @@ class AlgoSettingsWidget:
|
|||||||
self.config.gui_blob_maxsize = values[self.gui_blob_maxsize]
|
self.config.gui_blob_maxsize = values[self.gui_blob_maxsize]
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
if self.config.ibo_filter_samples != int(values[self.ibo_filter_samples]):
|
||||||
|
self.config.ibo_filter_samples = int(values[self.ibo_filter_samples])
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if self.config.ibo_fully_close_eye_threshold != float(values[self.ibo_fully_close_eye_threshold]):
|
||||||
|
self.config.ibo_fully_close_eye_threshold = float(values[self.ibo_fully_close_eye_threshold])
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if self.config.calibration_samples != int(values[self.calibration_samples]):
|
||||||
|
self.config.calibration_samples = int(values[self.calibration_samples])
|
||||||
|
changed = True
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
self.main_config.save()
|
self.main_config.save()
|
||||||
#print(self.main_config)
|
#print(self.main_config)
|
||||||
|
|||||||
@ -82,7 +82,7 @@ class Camera:
|
|||||||
self.config.capture_source != None and self.config.capture_source != ""
|
self.config.capture_source != None and self.config.capture_source != ""
|
||||||
):
|
):
|
||||||
|
|
||||||
if (self.config.capture_source[:3] == "COM"):
|
if "COM" in str(self.current_capture_source):
|
||||||
if (
|
if (
|
||||||
self.serial_connection is None
|
self.serial_connection is None
|
||||||
or self.camera_status == CameraState.DISCONNECTED
|
or self.camera_status == CameraState.DISCONNECTED
|
||||||
@ -117,7 +117,7 @@ class Camera:
|
|||||||
if should_push and not self.capture_event.wait(timeout=0.02):
|
if should_push and not self.capture_event.wait(timeout=0.02):
|
||||||
continue
|
continue
|
||||||
if self.config.capture_source != None:
|
if self.config.capture_source != None:
|
||||||
if (self.current_capture_source[:3] == "COM"):
|
if "COM" in str(self.current_capture_source):
|
||||||
self.get_serial_camera_picture(should_push)
|
self.get_serial_camera_picture(should_push)
|
||||||
else:
|
else:
|
||||||
self.get_cv2_camera_picture(should_push)
|
self.get_cv2_camera_picture(should_push)
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class CameraWidget:
|
|||||||
self.gui_mode_readout = f"-APPMODE{widget_id}-"
|
self.gui_mode_readout = f"-APPMODE{widget_id}-"
|
||||||
self.gui_roi_message = f"-ROIMESSAGE{widget_id}-"
|
self.gui_roi_message = f"-ROIMESSAGE{widget_id}-"
|
||||||
|
|
||||||
|
self.last_eye_info = None
|
||||||
self.osc_queue = osc_queue
|
self.osc_queue = osc_queue
|
||||||
self.main_config = main_config
|
self.main_config = main_config
|
||||||
self.eye_id = widget_id
|
self.eye_id = widget_id
|
||||||
@ -266,7 +267,8 @@ class CameraWidget:
|
|||||||
self.x1, self.y1 = values[self.gui_roi_selection]
|
self.x1, self.y1 = values[self.gui_roi_selection]
|
||||||
|
|
||||||
if event == self.gui_restart_calibration:
|
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)
|
PlaySound('Audio/start.wav', SND_FILENAME | SND_ASYNC)
|
||||||
|
|
||||||
if event == self.gui_stop_calibration:
|
if event == self.gui_stop_calibration:
|
||||||
|
|||||||
@ -65,6 +65,13 @@ class EyeTrackSettingsConfig(BaseModel):
|
|||||||
gui_vrc_native: bool = True
|
gui_vrc_native: bool = True
|
||||||
gui_circular_crop_right: bool = False
|
gui_circular_crop_right: bool = False
|
||||||
gui_circular_crop_left: 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
|
||||||
|
osc_right_eye_close_address: str = "/avatar/parameters/RightEyeLidExpandedSqueeze"
|
||||||
|
osc_left_eye_close_address: str = "/avatar/parameters/LeftEyeLidExpandedSqueeze"
|
||||||
|
osc_invert_eye_close: bool = False
|
||||||
|
|
||||||
|
|
||||||
class EyeTrackConfig(BaseModel):
|
class EyeTrackConfig(BaseModel):
|
||||||
|
|||||||
@ -247,20 +247,18 @@ class EyeProcessor:
|
|||||||
|
|
||||||
|
|
||||||
def UPDATE(self):
|
def UPDATE(self):
|
||||||
# print(self.blink_clear)
|
|
||||||
if self.settings.gui_BLINK:
|
if self.settings.gui_BLINK:
|
||||||
self.eyeopen = BLINK(self)
|
self.eyeopen = BLINK(self)
|
||||||
|
|
||||||
if self.settings.gui_IBO:
|
if self.settings.gui_IBO:
|
||||||
self.eyeopen = self.ibo.intense(self.rawx, self.rawy, self.current_image_white)
|
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 < 0.35: #threshold so the eye fully closes #todo: make this a setting?
|
if self.eyeopen < self.settings.ibo_fully_close_eye_threshold: #threshold so the eye fully closes
|
||||||
self.eyeopen = 0.0
|
self.eyeopen = 0.0
|
||||||
if self.bd_blink == True:
|
if self.bd_blink == True:
|
||||||
pass
|
pass
|
||||||
# self.eyeopen = 0.0
|
|
||||||
|
|
||||||
if self.settings.gui_IBO and self.settings.gui_BLINK:
|
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)
|
blink = BLINK(self)
|
||||||
if blink == 0.0:
|
if blink == 0.0:
|
||||||
|
|||||||
@ -241,7 +241,6 @@ def main():
|
|||||||
elif values[BOTH_EYE_RADIO_NAME] and config.eye_display_id != EyeId.BOTH:
|
elif values[BOTH_EYE_RADIO_NAME] and config.eye_display_id != EyeId.BOTH:
|
||||||
settings[0].stop()
|
settings[0].stop()
|
||||||
settings[1].stop()
|
settings[1].stop()
|
||||||
eyes[0].stop()
|
|
||||||
eyes[1].start()
|
eyes[1].start()
|
||||||
eyes[0].start()
|
eyes[0].start()
|
||||||
window[LEFT_EYE_NAME].update(visible=True)
|
window[LEFT_EYE_NAME].update(visible=True)
|
||||||
@ -277,15 +276,15 @@ def main():
|
|||||||
config.eye_display_id = EyeId.ALGOSETTINGS
|
config.eye_display_id = EyeId.ALGOSETTINGS
|
||||||
config.save()
|
config.save()
|
||||||
|
|
||||||
# Otherwise, render all
|
else:
|
||||||
for eye in eyes:
|
# Otherwise, render all
|
||||||
if eye.started():
|
for eye in eyes:
|
||||||
eye.render(window, event, values)
|
if eye.started():
|
||||||
for setting in settings:
|
eye.render(window, event, values)
|
||||||
if setting.started():
|
for setting in settings:
|
||||||
setting.render(window, event, values)
|
if setting.started():
|
||||||
# settings[0].render(window, event, values)
|
setting.render(window, event, values)
|
||||||
# settings[1].render(window, event, values)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@ -130,13 +130,16 @@ class IntensityBasedOpeness:
|
|||||||
self.img_roi = np.zeros(3, dtype=np.int32)
|
self.img_roi = np.zeros(3, dtype=np.int32)
|
||||||
self.now_roi = np.zeros(3, dtype=np.int32)
|
self.now_roi = np.zeros(3, dtype=np.int32)
|
||||||
self.prev_val = 0.5
|
self.prev_val = 0.5
|
||||||
|
self.avg_intensity = 0.0
|
||||||
|
|
||||||
self.old = []
|
self.old = []
|
||||||
self.color = []
|
self.color = []
|
||||||
self.x = []
|
self.x = []
|
||||||
self.fc = 0
|
self.fc = 0
|
||||||
self.filterlist = []
|
self.filterlist = []
|
||||||
|
self.averageList = []
|
||||||
|
self.eye_id = eye_id
|
||||||
|
|
||||||
|
|
||||||
self.maxinten = 0
|
self.maxinten = 0
|
||||||
|
|
||||||
@ -213,7 +216,14 @@ class IntensityBasedOpeness:
|
|||||||
def change_roi(self, roiinfo: dict):
|
def change_roi(self, roiinfo: dict):
|
||||||
self.now_roi[:] = [v for v in roiinfo.values()]
|
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
|
# x,y = 0~(frame.shape[1 or 0]-1), frame = 1-channel frame cropped by ROI
|
||||||
self.check(frame.shape)
|
self.check(frame.shape)
|
||||||
int_x, int_y = int(x), int(y)
|
int_x, int_y = int(x), int(y)
|
||||||
@ -237,10 +247,10 @@ class IntensityBasedOpeness:
|
|||||||
#cv2.imshow('e', frame)
|
#cv2.imshow('e', frame)
|
||||||
# if cv2.waitKey(10) == 27:
|
# if cv2.waitKey(10) == 27:
|
||||||
# exit()
|
# exit()
|
||||||
if len(self.filterlist) < 800:
|
if len(self.filterlist) < filterSamples:
|
||||||
self.filterlist.append(intensity)
|
self.filterlist.append(intensity)
|
||||||
else:
|
else:
|
||||||
self.filterlist.pop()
|
self.filterlist.pop(0)
|
||||||
self.filterlist.append(intensity)
|
self.filterlist.append(intensity)
|
||||||
|
|
||||||
if intensity >= np.percentile(self.filterlist, 99): # filter abnormally high values
|
if intensity >= np.percentile(self.filterlist, 99): # filter abnormally high values
|
||||||
@ -287,7 +297,7 @@ class IntensityBasedOpeness:
|
|||||||
oob = True
|
oob = True
|
||||||
# print('CAUGHT Y UNDER BOUNDS')
|
# print('CAUGHT Y UNDER BOUNDS')
|
||||||
|
|
||||||
if oob != True:
|
if oob != True and self.data.any():
|
||||||
data_val = self.data[int_y, int_x]
|
data_val = self.data[int_y, int_x]
|
||||||
else:
|
else:
|
||||||
data_val = 0
|
data_val = 0
|
||||||
@ -325,18 +335,22 @@ class IntensityBasedOpeness:
|
|||||||
maxp = self.data[int_y, int_x]
|
maxp = self.data[int_y, int_x]
|
||||||
minp = self.maxval
|
minp = self.maxval
|
||||||
|
|
||||||
|
|
||||||
eyeopen = ((intensity - maxp) / (minp - maxp)) #for whatever reason when input and maxp are too close it outputs high
|
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
|
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
|
if changed and ((time.time() - self.lct) > 5): # save every 5 seconds if something changed to save disk usage
|
||||||
self.save()
|
self.save()
|
||||||
self.lct = time.time()
|
self.lct = time.time()
|
||||||
# print(self.prev_val, eyeopen, intensity, self.maxval)
|
|
||||||
#@filter_eyeopen = (eyeopen + self.prev_val) / 2
|
|
||||||
|
|
||||||
self.prev_val = eyeopen
|
self.prev_val = eyeopen
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -20,7 +20,7 @@ class OneEuroFilter:
|
|||||||
self.beta = np.full(x0.shape, beta)
|
self.beta = np.full(x0.shape, beta)
|
||||||
self.d_cutoff = np.full(x0.shape, d_cutoff)
|
self.d_cutoff = np.full(x0.shape, d_cutoff)
|
||||||
# Previous values.
|
# Previous values.
|
||||||
self.x_prev = x0.astype(np.float)
|
self.x_prev = x0
|
||||||
self.dx_prev = np.full(x0.shape, dx0)
|
self.dx_prev = np.full(x0.shape, dx0)
|
||||||
self.t_prev = time()
|
self.t_prev = time()
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,13 @@ class EyeId(IntEnum):
|
|||||||
ALGOSETTINGS = 4
|
ALGOSETTINGS = 4
|
||||||
from config import EyeTrackConfig
|
from config import EyeTrackConfig
|
||||||
|
|
||||||
|
def eyelid_transformer(self,eye_blink):
|
||||||
|
if self.config.osc_invert_eye_close:
|
||||||
|
return float(1 - eye_blink)
|
||||||
|
else:
|
||||||
|
return float(eye_blink)
|
||||||
|
|
||||||
|
|
||||||
se = False
|
se = False
|
||||||
def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
||||||
global se
|
global se
|
||||||
@ -28,9 +35,11 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
|||||||
self.client.send_message("/avatar/parameters/LeftEyeX", eye_x)
|
self.client.send_message("/avatar/parameters/LeftEyeX", eye_x)
|
||||||
self.client.send_message("/avatar/parameters/RightEyeX", eye_x)
|
self.client.send_message("/avatar/parameters/RightEyeX", eye_x)
|
||||||
self.client.send_message("/avatar/parameters/EyesY", eye_y)
|
self.client.send_message("/avatar/parameters/EyesY", eye_y)
|
||||||
|
|
||||||
self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(eye_blink))
|
self.config.osc_left_eye_close_address
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(eye_blink))
|
|
||||||
|
self.client.send_message(self.config.osc_right_eye_close_address, eyelid_transformer(self,eye_blink))
|
||||||
|
self.client.send_message(self.config.osc_left_eye_close_address, eyelid_transformer(self,eye_blink))
|
||||||
else:
|
else:
|
||||||
se = False
|
se = False
|
||||||
|
|
||||||
@ -41,18 +50,18 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
|||||||
if self.l_eye_blink == 0.0:
|
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.
|
if last_blink > 0.7: #when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink))
|
self.client.send_message(self.config.osc_left_eye_close_address, eyelid_transformer(self,self.l_eye_blink))
|
||||||
last_blink = time.time() - last_blink
|
last_blink = time.time() - last_blink
|
||||||
if self.config.gui_eye_falloff:
|
if self.config.gui_eye_falloff:
|
||||||
if self.r_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink
|
if self.r_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink))
|
self.client.send_message(self.config.osc_left_eye_close_address, eyelid_transformer(self,self.l_eye_blink))
|
||||||
self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.l_eye_blink))
|
self.client.send_message(self.config.osc_right_eye_close_address, eyelid_transformer(self,self.l_eye_blink))
|
||||||
self.l_eye_x = self.r_eye_x
|
self.l_eye_x = self.r_eye_x
|
||||||
|
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeX", self.l_eye_x)
|
self.client.send_message("/avatar/parameters/LeftEyeX", self.l_eye_x)
|
||||||
self.left_y = eye_y
|
self.left_y = eye_y
|
||||||
|
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink))
|
self.client.send_message(self.config.osc_left_eye_close_address, eyelid_transformer(self,self.l_eye_blink))
|
||||||
|
|
||||||
|
|
||||||
elif self.eye_id in [EyeId.RIGHT] and not se: #Right eye, send data to right
|
elif self.eye_id in [EyeId.RIGHT] and not se: #Right eye, send data to right
|
||||||
@ -62,19 +71,19 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
|||||||
if self.r_eye_blink == 0.0:
|
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.
|
if last_blink > 0.7: #when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.r_eye_blink))
|
self.client.send_message(self.config.osc_right_eye_close_address, eyelid_transformer(self,self.r_eye_blink))
|
||||||
last_blink = time.time() - last_blink
|
last_blink = time.time() - last_blink
|
||||||
if self.config.gui_eye_falloff:
|
if self.config.gui_eye_falloff:
|
||||||
if self.l_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink
|
if self.l_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink
|
||||||
self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.r_eye_blink))
|
self.client.send_message(self.config.osc_left_eye_close_address, eyelid_transformer(self,self.r_eye_blink))
|
||||||
self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.r_eye_blink))
|
self.client.send_message(self.config.osc_right_eye_close_address, eyelid_transformer(self,self.r_eye_blink))
|
||||||
|
|
||||||
self.r_eye_x = self.l_eye_x
|
self.r_eye_x = self.l_eye_x
|
||||||
|
|
||||||
self.client.send_message("/avatar/parameters/RightEyeX", eye_x)
|
self.client.send_message("/avatar/parameters/RightEyeX", eye_x)
|
||||||
self.right_y = eye_y
|
self.right_y = eye_y
|
||||||
|
|
||||||
self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.r_eye_blink))
|
self.client.send_message(self.config.osc_right_eye_close_address, eyelid_transformer(self,self.r_eye_blink))
|
||||||
|
|
||||||
if self.main_config.eye_display_id in [EyeId.BOTH] and self.right_y != 621 and self.left_y != 621:
|
if self.main_config.eye_display_id in [EyeId.BOTH] and self.right_y != 621 and self.left_y != 621:
|
||||||
y = (self.right_y + self.left_y) / 2
|
y = (self.right_y + self.left_y) / 2
|
||||||
@ -97,6 +106,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
|||||||
self.l_eye_x = eye_x
|
self.l_eye_x = eye_x
|
||||||
self.l_eye_blink = eye_blink
|
self.l_eye_blink = eye_blink
|
||||||
self.left_y = eye_y
|
self.left_y = eye_y
|
||||||
|
self.client.send_message(self.config.osc_left_eye_close_address,eyelid_transformer(self,eye_blink))
|
||||||
|
|
||||||
if self.l_eye_blink == 0.0:
|
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.
|
if last_blink > 0.7: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||||
@ -118,6 +128,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
|||||||
self.r_eye_x = eye_x
|
self.r_eye_x = eye_x
|
||||||
self.r_eye_blink = eye_blink
|
self.r_eye_blink = eye_blink
|
||||||
self.right_y = eye_y
|
self.right_y = eye_y
|
||||||
|
self.client.send_message(self.config.osc_right_eye_close_address,eyelid_transformer(self,eye_blink))
|
||||||
|
|
||||||
if self.r_eye_blink == 0.0:
|
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.
|
if last_blink > 0.7: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||||
@ -149,7 +160,6 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, self):
|
|||||||
eye_y = (self.right_y + self.left_y) / 2
|
eye_y = (self.right_y + self.left_y) / 2
|
||||||
|
|
||||||
if not se:
|
if not se:
|
||||||
|
|
||||||
self.client.send_message("/tracking/eye/LeftRightVec",
|
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),
|
[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)
|
0.8]) # vrc native ET (z values may need tweaking, they act like a scalar)
|
||||||
@ -215,7 +225,8 @@ class VRChatOSCReceiver:
|
|||||||
if type(osc_value) != bool: return # just incase we get anything other than bool
|
if type(osc_value) != bool: return # just incase we get anything other than bool
|
||||||
if osc_value:
|
if osc_value:
|
||||||
for eye in self.eyes:
|
for eye in self.eyes:
|
||||||
eye.ransac.calibration_frame_counter = 300
|
eye.ransac.ibo.clear_filter()
|
||||||
|
eye.ransac.calibration_frame_counter = self.config.calibration_samples
|
||||||
PlaySound('Audio/start.wav', SND_FILENAME | SND_ASYNC)
|
PlaySound('Audio/start.wav', SND_FILENAME | SND_ASYNC)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|||||||
@ -21,7 +21,7 @@ class cal():
|
|||||||
self.config.calib_XOFF = cx
|
self.config.calib_XOFF = cx
|
||||||
self.config.calib_YOFF = cy
|
self.config.calib_YOFF = cy
|
||||||
PlaySound('Audio/completed.wav', SND_FILENAME | SND_ASYNC)
|
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_XMAX = -69420
|
||||||
self.config.calib_XMIN = 69420
|
self.config.calib_XMIN = 69420
|
||||||
self.config.calib_YMAX = -69420
|
self.config.calib_YMAX = -69420
|
||||||
|
|||||||
@ -160,17 +160,10 @@ def get_center_noclamp(center_xy, radius):
|
|||||||
|
|
||||||
|
|
||||||
cct = 300
|
cct = 300
|
||||||
ransac_lower_x = 100
|
|
||||||
ransac_lower_y = 100
|
|
||||||
cx = 0
|
|
||||||
cy = 0
|
|
||||||
|
|
||||||
|
|
||||||
def RANSAC3D(self, hsrac_en):
|
def RANSAC3D(self, hsrac_en):
|
||||||
f = False
|
f = False
|
||||||
ranf = False
|
ranf = False
|
||||||
global cct, ransac_lower_y, ransac_lower_x, cx, cy
|
|
||||||
|
|
||||||
|
|
||||||
if hsrac_en:
|
if hsrac_en:
|
||||||
center_x, center_y, upper_x, lower_x, upper_y, lower_y, ransac_lower_x, ransac_lower_y, ransac_upper_x, ransac_upper_y, ransac_xy_offset = get_center_noclamp(
|
center_x, center_y, upper_x, lower_x, upper_y, lower_y, ransac_lower_x, ransac_lower_y, ransac_upper_x, ransac_upper_y, ransac_xy_offset = get_center_noclamp(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user