fix: algo crashes, frame size issues

This commit is contained in:
Prohurtz 2024-08-18 14:27:51 -05:00
parent 8acaa1c643
commit dbda86d845
2 changed files with 30 additions and 78 deletions

View File

@ -180,23 +180,26 @@ class EyeProcessor:
self.one_euro_filter = OneEuroFilter(noisy_point, min_cutoff=min_cutoff, beta=beta) self.one_euro_filter = OneEuroFilter(noisy_point, min_cutoff=min_cutoff, beta=beta)
def output_images_and_update(self, threshold_image, output_information: EyeInfo): def output_images_and_update(self, threshold_image, output_information: EyeInfo):
try: # try: # I do not like this try.
image_stack = np.concatenate(
(
cv2.cvtColor(self.current_image_gray, cv2.COLOR_GRAY2BGR),
cv2.cvtColor(threshold_image, cv2.COLOR_GRAY2BGR),
),
axis=1,
)
self.image_queue_outgoing.put((image_stack, output_information))
if self.image_queue_outgoing.qsize() > 1:
self.image_queue_outgoing.get()
self.previous_image = self.current_image self.current_image_gray = cv2.resize(self.current_image_gray, (150, 150), interpolation=cv2.INTER_AREA)
self.previous_rotation = self.config.rotation_angle threshold_image = cv2.resize(threshold_image, (150, 150), interpolation=cv2.INTER_AREA)
image_stack = np.concatenate(
(
cv2.cvtColor(self.current_image_gray, cv2.COLOR_GRAY2BGR),
cv2.cvtColor(threshold_image, cv2.COLOR_GRAY2BGR),
),
axis=1,
)
self.image_queue_outgoing.put((image_stack, output_information))
if self.image_queue_outgoing.qsize() > 1:
self.image_queue_outgoing.get()
except: # If this fails it likely means that the images are not the same size for some reason. self.previous_image = self.current_image
print("\033[91m[ERROR] Size of frames to display are of unequal sizes.\033[0m") self.previous_rotation = self.config.rotation_angle
# except: # If this fails it likely means that the images are not the same size for some reason.
# print("\033[91m[ERROR] Size of frames to display are of unequal sizes.\033[0m")
def capture_crop_rotate_image(self): def capture_crop_rotate_image(self):
# Get our current frame # Get our current frame
@ -300,6 +303,7 @@ class EyeProcessor:
self.settings.ibo_filter_samples, self.settings.ibo_filter_samples,
self.settings.ibo_average_output_samples, self.settings.ibo_average_output_samples,
) )
print(self.eyeopen)
# threshold so the eye fully closes # threshold so the eye fully closes
if self.eyeopen < float(self.settings.ibo_fully_close_eye_threshold): if self.eyeopen < float(self.settings.ibo_fully_close_eye_threshold):
self.eyeopen = 0.0 self.eyeopen = 0.0
@ -308,15 +312,6 @@ class EyeProcessor:
print("blinks") print("blinks")
pass pass
if self.settings.gui_IBO and self.eyeopen != 0.0:
ibo = self.ibo.intense(
self.rawx,
self.rawy,
self.current_image_white,
self.settings.ibo_filter_samples,
self.settings.ibo_average_output_samples,
)
if self.settings.gui_LEAP_lid and self.eyeopen != 0.0 and not self.settings.gui_LEAP: if self.settings.gui_LEAP_lid and self.eyeopen != 0.0 and not self.settings.gui_LEAP:
( (
self.current_image_gray, self.current_image_gray,
@ -580,7 +575,7 @@ class EyeProcessor:
pass pass
self.rawx, self.rawy, self.thresh = BLOB(self) self.rawx, self.rawy, self.thresh = BLOB(self)
self.out_x, self.out_y = cal.cal_osc(self, self.rawx, self.rawy, self.angle) self.out_x, self.out_y, self.avg_velocity = cal.cal_osc(self, self.rawx, self.rawy, self.angle)
self.current_algorithm = EyeInfoOrigin.BLOB self.current_algorithm = EyeInfoOrigin.BLOB
def ALGOSELECT(self): def ALGOSELECT(self):

View File

@ -87,9 +87,7 @@ def data2csv(data_u32, filepath):
# For data checking # For data checking
nonzero_index = np.nonzero(data_u32) # (row,col) nonzero_index = np.nonzero(data_u32) # (row,col)
data_list = data_u32[nonzero_index].tolist() data_list = data_u32[nonzero_index].tolist()
datalines = [ datalines = ["{},{},{}\n".format(x, y, val) for y, x, val in zip(*nonzero_index, data_list)]
"{},{},{}\n".format(x, y, val) for y, x, val in zip(*nonzero_index, data_list)
]
with open(filepath, "w", encoding="utf-8") as out_f: with open(filepath, "w", encoding="utf-8") as out_f:
out_f.write("x,y,intensity\n") out_f.write("x,y,intensity\n")
out_f.writelines(datalines) out_f.writelines(datalines)
@ -109,9 +107,7 @@ def u32_1ch_to_u16_3ch(img):
def u16_3ch_to_u32_1ch(img): def u16_3ch_to_u32_1ch(img):
# The image format with the most bits that can be displayed on Windows without additional software and that opencv can handle is PNG's uint16 # The image format with the most bits that can be displayed on Windows without additional software and that opencv can handle is PNG's uint16
out = img[:, :, 0].astype(np.float64) # float64 = max 2^53 out = img[:, :, 0].astype(np.float64) # float64 = max 2^53
cv2.add( cv2.add(out, img[:, :, 1].astype(np.float64) * np.float64(65536), dst=out) # opencv did not have uint32 type
out, img[:, :, 1].astype(np.float64) * np.float64(65536), dst=out
) # opencv did not have uint32 type
return out.astype(np.uint32) # cast return out.astype(np.uint32) # cast
@ -159,9 +155,7 @@ class IntensityBasedOpeness:
min_cutoff = 0.0004 min_cutoff = 0.0004
beta = 0.9 beta = 0.9
noisy_point = np.array([1, 1]) noisy_point = np.array([1, 1])
self.one_euro_filter = OneEuroFilter( self.one_euro_filter = OneEuroFilter(noisy_point, min_cutoff=min_cutoff, beta=beta)
noisy_point, min_cutoff=min_cutoff, beta=beta
)
def check(self, frameshape): def check(self, frameshape):
# 0 in data is used as the initial value. # 0 in data is used as the initial value.
@ -199,9 +193,7 @@ class IntensityBasedOpeness:
print("\033[94m[INFO] File does not exist.\033[0m") print("\033[94m[INFO] File does not exist.\033[0m")
req_newdata = True req_newdata = True
else: else:
if self.data.shape != frameshape or not np.array_equal( if self.data.shape != frameshape or not np.array_equal(self.img_roi, self.now_roi):
self.img_roi, self.now_roi
):
# If the ROI recorded in the image file differs from the current ROI # If the ROI recorded in the image file differs from the current ROI
# todo: Using the previous and current frame sizes and centre positions from the original, etc., the data can be ported to some extent, but there may be many areas where code changes are required. # todo: Using the previous and current frame sizes and centre positions from the original, etc., the data can be ported to some extent, but there may be many areas where code changes are required.
print("[INFO] \033[94mFrame size changed.\033[0m") print("[INFO] \033[94mFrame size changed.\033[0m")
@ -258,31 +250,11 @@ class IntensityBasedOpeness:
self.filterlist.append(intensity) self.filterlist.append(intensity)
try: try:
if intensity >= np.percentile( if intensity >= np.percentile(self.filterlist, 99): # filter abnormally high values
self.filterlist, 99
): # filter abnormally high values
# print('filter, assume blink')
intensity = self.maxval intensity = self.maxval
# if intensity <= np.percentile( # TODO test this
# self.filterlist, 0.3
# ): # filter abnormally low values
# print('filter, assume blink')
# intensity = self.data[int_y, int_x]
except: except:
pass pass
# self.tri_filter.append(intensity)
# if len(self.tri_filter) > 3:
# self.tri_filter.pop(0)
# intensity = sum(self.tri_filter) / 3
# avg_color_per_row = np.average(frame_crop, axis=0)
# avg_color = np.average(avg_color_per_row, axis=0)
# ar, ag, ab = avg_color
# intensity = int(ar * 8) #higher = closed
# cv2.imshow("IBO", frame_crop)
# if cv2.waitKey(1) & 0xFF == ord("q"):
# pass
# numpy:np.sum(),ndarray.sum() # numpy:np.sum(),ndarray.sum()
# opencv:cv2.sumElems() # opencv:cv2.sumElems()
@ -323,9 +295,7 @@ class IntensityBasedOpeness:
changed = True changed = True
newval_flg = True newval_flg = True
else: else:
if ( if intensity < data_val: # if current intensity value is less (more pupil), save that
intensity < data_val
): # if current intensity value is less (more pupil), save that
self.data[int_y, int_x] = intensity # set value self.data[int_y, int_x] = intensity # set value
changed = True changed = True
else: else:
@ -339,9 +309,7 @@ class IntensityBasedOpeness:
if self.maxval == 0: # that value is not yet saved if self.maxval == 0: # that value is not yet saved
self.maxval = intensity # set value at 0 index self.maxval = intensity # set value at 0 index
else: else:
if ( if intensity > self.maxval: # if current intensity value is more (less pupil), save that NOTE: we have the
intensity > self.maxval
): # if current intensity value is more (less pupil), save that NOTE: we have the
self.maxval = intensity - 5 # set value at 0 index self.maxval = intensity - 5 # set value at 0 index
else: else:
intensityd = max( intensityd = max(
@ -369,15 +337,9 @@ class IntensityBasedOpeness:
self.averageList.append(eyeopen) self.averageList.append(eyeopen)
eyeopen = np.average(self.averageList) eyeopen = np.average(self.averageList)
if eyeopen > 1: # clamp values eyeopen = np.clip(eyeopen, 0.0, 1.0)
eyeopen = 1.0
if eyeopen < 0: if changed and ((time.time() - self.lct) > 11): # save every 5 seconds if something changed to save disk usage
eyeopen = 0.0
if changed and (
(time.time() - self.lct) > 11
): # save every 5 seconds if something changed to save disk usage
self.save() self.save()
self.lct = time.time() self.lct = time.time()
@ -387,13 +349,8 @@ class IntensityBasedOpeness:
eyeopenx = point_hat[0] eyeopenx = point_hat[0]
eyeopeny = point_hat[1] eyeopeny = point_hat[1]
eyeopen = (eyeopenx + eyeopeny) / 2 eyeopen = (eyeopenx + eyeopeny) / 2
# print(eyeopen, eyeopenx, eyeopeny) # print(eyeopen, eyeopenx, eyeopeny)
except: except:
pass pass
# eyevec = abs(self.prev_val - eyeopen)
# print(eyevec)
# if eyevec > 0.4:
# print("BLINK LCOK")
return eyeopen return eyeopen