def __init__(self): self.dataset_path = r'C:\Projects\Datasets\eye_test\movies' self.dataset_out = r'C:\Projects\Datasets\eye_test\out' self.dataset_label = r'C:\Projects\Datasets\eye_test\label' self.title = '' self.dataset_out_exam = '' self.eye_tracker = deepeye.DeepEye() self.pupil = Pupil() self.reflections = Reflections()
def __init__(self): try: with open("pupils.json") as f: pupils_list = json.load(f) self.pupils = [] for pupils_dict in pupils_list: p = Pupil() p.from_dict(pupils_dict) self.pupils += [p] except FileNotFoundError: self.pupils = []
def pupil_Simulation(self): # simulate a pupil function using given parameters; update the list. Everything is included. print(self.NA) self.PF = Pupil(self.nx, self.dx, self.l, self.nfrac, self.NA, self.cf, wavelengths=self.n_wave, wave_step=self.d_wave) # initialize the pupil function in_pupil = self.PF.k <= self.PF.k_max self.NK = in_pupil.sum()
def _analyze(self, original_frame, landmarks, side, calibration): """Detects and isolates the eye in a new frame, sends data to the calibration and initializes Pupil object. Arguments: original_frame (numpy.ndarray): Frame passed by the user landmarks (dlib.full_object_detection): Facial landmarks for the face region side: Indicates whether it's the left eye (0) or the right eye (1) calibration (calibration.Calibration): Manages the binarization threshold value """ if side == 0: points = self.LEFT_EYE_POINTS elif side == 1: points = self.RIGHT_EYE_POINTS else: return self.blinking = self._blinking_ratio(landmarks, points) self._isolate(original_frame, landmarks, points) if not calibration.is_complete(): calibration.evaluate(self.frame, side) threshold = calibration.threshold(side) self.pupil = Pupil(self.frame, threshold)
def create_pupil(self): first_name = input("Give name: ") last_name = input("Give surname: ") fathers_name = input("Give father's name: ") for p in self.pupils: if first_name == p.first_name and last_name == p.last_name and fathers_name == p.fathers_name: print("This pupil already exists.") ch = input("Do you want to continue? (y-yes, n-no): ") if ch == "n": return None age = int(input("Give age: ")) class_name = int(input("Give class: ")) id_card = input("Does he/she has an id card: (y-true, n-false): ") if id_card == "y": id_number = input("Give id card number: ") else: id_number = None pupil = Pupil(first_name, last_name, fathers_name, age, class_name, id_number, self.next_id()) self.pupils.append(pupil) return pupil
def __init__(self): # Global variables for executions self._title_exam = '' self._path_dataset_out = '' # Dependences self._process = ProcessImage() self._pupil = Pupil() self._eye = Eye() # Limit cash dependences self._max_execution_with_cash = 20 # Directoris self._projects_path = '/media/marcos/Dados/Projects' self._dataset_path = '{}/Datasets/exams'.format(self._projects_path) self._dataset_out = '{}/Results/PupilDeep/Frames'.format( self._projects_path) self._dataset_label = '{}/Results/PupilDeep/Labels'.format( self._projects_path) # Stops and executions self._frame_stop = 150 self._frame_start = 100 self._movie_stop = 0 self._list_not_available = [] self._list_available = [ '25080325_08_2019_08_48_58', '25080425_08_2019_08_53_48' ] # self._list_available = ['25080325_08_2019_08_48_58', '25080425_08_2019_08_53_48', '25080425_08_2019_08_55_59', '25080425_08_2019_09_05_40', '25080425_08_2019_09_08_25'] # self._list_available = ['new_benchmark'] # Params color self._white_color = (255, 255, 0) self._gray_color = (170, 170, 0) # Params text and circle print image self._position_text = (30, 30) self._font_text = cv2.FONT_HERSHEY_DUPLEX self._size_point_pupil = 5 # Params dataset labels out self._title_label = 'frame,center_x,center_y,radius,flash,eye_size,img_mean,img_std,img_median'
def processImage(self): x, y, a, b, fangle = 0, 0, 0, 0, 0 if self.img_path != "": processed_path = os.path.join(self.dir.name, 'processed.png') print(processed_path) pupil = Pupil(self.img_path, processed_path) if self.method == "parallelogram": x, y, a, b, fangle = pupil.parallelogram() text = f"Pupil center:\nX = {x}\nY = {y}\n\nPupil elipse:\na = {a}\nb = {b}\nfangle = {fangle}" self.textbox.setText(text) img = cv.imread(processed_path, 1) # cv.imshow("Pieknie", img) img = cv.resize(img, dsize=(200, 200), interpolation=cv.INTER_AREA) resized_path = os.path.join(self.dir.name, 'resized.png') cv.imwrite(resized_path, img) pix_map = QPixmap(resized_path) self.img_processed.setPixmap(QPixmap(pix_map))
def find_best_threshold(eye_frame): average_iris_size = 0.48 trials = {} for threshold in range(5, 100, 5): iris_frame = Pupil.image_processing(eye_frame, threshold) trials[threshold] = Calibration.iris_size(iris_frame) best_threshold, iris_size = min( trials.items(), key=(lambda p: abs(p[1] - average_iris_size))) return best_threshold
def find_best_threshold(eye_frame): """Calculates the optimal threshold to binarize the frame for the given eye. Argument: eye_frame (numpy.ndarray): Frame of the eye to be analyzed """ average_iris_size = 0.48 trials = {} for threshold in range(5, 100, 5): iris_frame = Pupil.image_processing(eye_frame, threshold) trials[threshold] = Calibration.iris_size(iris_frame) best_threshold, iris_size = min(trials.items(), key=(lambda p: abs(p[1] - average_iris_size))) return best_threshold
def _analyze(self, original_frame, landmarks, side, calibration): if side == 0: points = self.LEFT_EYE_POINTS elif side == 1: points = self.RIGHT_EYE_POINTS else: return self.blinking = self._blinking_ratio(landmarks, points) self._isolate(original_frame, landmarks, points) if not calibration.is_complete(): calibration.evaluate(self.frame, side) threshold = calibration.threshold(side) self.pupil = Pupil(self.frame, threshold)
def create_pupil(self): first_name = input("Type Pupil's Name: ") last_name = input("Type Pupil's Lastname: ") fathers_name = input("Type Pupil's Father's Name: ") for pupil in self.pupils: if first_name == pupil.first_name and last_name == pupil.last_name and fathers_name == pupil.last_name: print("this pupil already exists") ch = input("Do you want to continue? (y-yes, n-no): ") if ch == "n": return None age = int(input("Type the pupils age: ")) class_name = input("Type the class name: ") id_card = input("does the pupil have an id card? (y-yes, n-no): ") if id_card == "y": id_number = input("Type pupil's id number: ") else: id_number = None pupil = Pupil(first_name, last_name, first_name, age, class_name, id_number, self.next_id()) self.pupils.append(pupil) return pupil
def _analyze(self, original_frame, landmarks, side, calibration): """ Detects and isolates the eye in a new frame, sends data to the calibration and initializes Pupil object. """ if side == 0: points = self.LEFT_EYE_POINTS self.inner = (landmarks.part(39).x, landmarks.part(39).y) elif side == 1: points = self.RIGHT_EYE_POINTS self.inner = (landmarks.part(42).x, landmarks.part(42).y) else: return self.blinking = self._blinking_ratio(landmarks, points) self._isolate(original_frame, landmarks, points) if not calibration.is_complete(): calibration.evaluate(self.frame, side) threshold = calibration.threshold(side) self.pupil = Pupil(self.frame, threshold)
################################################################################# # AUTHOR : Suyeon Choi # DATE : August 1, 2018 # # Command line interface for pypupil ################################################################################# import time, datetime import sys import numpy as np from pupil import Pupil if __name__ == "__main__": print("start eye tracker") tracker = Pupil('9289') while True: time.sleep(1) command = input('=' * 60 + '\nPossible commands \n' + '\t\t c (calibrate) \n' + '\t\t g (get_data, deprecated) \n' + '\t\t r (record, you should use this) \n' + '\t\t t (test) \n' + '\t\t exit \n' + '=' * 60 + '\nInput command : ') print('\n') if command == "c" or command == "calibrate": eyes = [] cmd_eye = input('=' * 60 + '\nSelect eyes to calibrate \n' + '\t\t l (left) \n' + '\t\t r (right) \n' + '\t\t b (binocular) \n' + '=' * 60 +
from deatheater import DeathEater from ghost import Ghost from hogwarts_member import HogwartsMember from house import House from professor import Professor from pupil import Pupil from spell import (Spell, Charm, Transfiguration, Jinx, Hex, Curse, CounterSpell, HealingSpell) if __name__ == '__main__': hagrid = HogwartsMember('Hagrid', 1952, 'male') dumby = HogwartsMember.dumbledore() harry = Pupil.harry() ron = Pupil.ron() hermione = Pupil.hermione() malfoy = Pupil.malfoy() snape = Professor.snape() mcgonagall = Professor.mcgonagall() nick = Ghost.nearly_headless_nick() bloody_baron = Ghost("Bloody Baron's", 1409, 'male', 1468, 'Slytherin') lumos = Charm.lumos() wingardium_leviosa = Charm.wingardium_leviosa() ron.add_trait('kind') ron.add_trait('tidy-minded') ron.add_trait('impatient', value=False)
class Core(object): def __init__(self, PSF=None): self._PSF = PSF self.PF = None self.dx = None self.l = None self._NA = None self._nfrac = None self.cf = None self.nw = 1 self.dw = 0.005 print("Initialized!") # -----------------------Below is a couple of setting functions --------------- @property def nfrac(self): return self._nfrac @nfrac.setter def nfrac(self, new_nfrac): self._nfrac = new_nfrac @property def NA(self): return self._NA @NA.setter def NA(self, new_NA): self._NA = new_NA @property def lcenter(self): return self.l @lcenter.setter def lcenter(self, new_lcenter): # set the central wavelength self.l = new_lcenter @property def pxl(self): return self.dx @pxl.setter def pxl(self, new_pxl): self.dx = new_pxl @property def objf(self): return self.cf @objf.setter def objf(self, new_cf): self.cf = new_cf @property def n_wave(self): return self.nw @n_wave.setter def n_wave(self, new_nw): self.nw = new_nw @property def d_wave(self): return self.dw @d_wave.setter def d_wave(self, new_dw): self.dw = new_dw @property def PSF(self): return self._PSF @PSF.setter def PSF(self, new_PSF): self._PSF = new_PSF def load_psf(self, psf_path): ''' load a psf function ''' ext = os.path.basename(psf_path).split('.')[-1] if ext == 'npy': PSF = np.load(psf_path) elif ext == 'tif': PSF = tf.imread(psf_path) try: nz, ny, nx = PSF.shape print(nz, ny, nx) self.PSF = PSF self.nx = np.min([ny, nx]) self.nz = nz return True except UnboundLocalError: print("wrong PSF format. Please reload the psf.") return False def set_zrange(self): z_offset, zz = psf_zplane(self.PSF, self.dz, self.l / 3.2) # This should be the reason!!!! >_< print(" z_offset = ", z_offset) zs = zz - z_offset self.cz = int(-zs[0] // self.dz) self.zs = zs print("psf loaded!") def updateNA(self, new_NA): self._NA = new_NA self.PF.update(NA=new_NA) def pupil_Simulation(self): # simulate a pupil function using given parameters; update the list. Everything is included. print(self.NA) self.PF = Pupil(self.nx, self.dx, self.l, self.nfrac, self.NA, self.cf, wavelengths=self.n_wave, wave_step=self.d_wave) # initialize the pupil function in_pupil = self.PF.k <= self.PF.k_max self.NK = in_pupil.sum() def background_reset(self, mask, psf_diam): ''' reset the background of the PSF mask is the outer diameter psf_diam is the inner diameter ''' Mx, My = np.meshgrid( np.arange(self.nx) - self.nx / 2., np.arange(self.nx) - self.nx / 2.) r_pxl = _msqrt(Mx**2 + My**2) bk_inner = psf_diam bk_outer = mask hcyl = np.array( self.nz * [np.logical_and(r_pxl >= bk_inner, r_pxl < bk_outer + 1)]) incyl = np.array(self.nz * [r_pxl < bk_outer]) background = np.mean(self.PSF[hcyl]) self.PSF[np.logical_not(incyl)] = background return background def retrievePF(self, p_diam, p_mask, nIt): A = self.PF.plane # initial pupil function:plane background = self.background_reset(mask=p_mask, psf_diam=p_diam) print(" background = ", background) PSF_sample = self.PSF complex_PF = self.PF.psf2pf(PSF_sample, self.zs, background, A, nIt) print(self.zs) Pupil_final = _PupilFunction(complex_PF) self.pf_complex = Pupil_final.complex self.pf_phase = unwrap_phase(Pupil_final.phase) self.pf_ampli = Pupil_final.amplitude def get_phase(self, crop=True): ''' return the (unwrapped pupil phase) ''' if crop: hx = int(self.nx // 2) #cropped_phase = self.pf_phase[hx - self.PF.k_pxl-1:hx+self.PF.k_pxl+1, hx-self.PF.k_pxl-1:hx+self.PF.k_pxl+1] cropped_phase = self.pf_phase[hx - self.PF.k_pxl:hx + self.PF.k_pxl, hx - self.PF.k_pxl:hx + self.PF.k_pxl] return cropped_phase else: return self.pf_phase def get_ampli(self, crop=True): if crop: hx = int(self.nx // 2) #cropped_ampli= self.pf_ampli[hx - self.PF.k_pxl-1:hx+self.PF.k_pxl+1, hx-self.PF.k_pxl-1:hx+self.PF.k_pxl+1] cropped_ampli = self.pf_ampli[hx - self.PF.k_pxl:hx + self.PF.k_pxl, hx - self.PF.k_pxl:hx + self.PF.k_pxl] return cropped_ampli else: return self.pf_ampli def get_config(self): # return the configuration of the class. conf_dict = { 'NA': self.NA, 'nfrac': self.nfrac, 'objf': self.objf / 1000, 'wavelength': self.lcenter * 1000, 'pxl': self.pxl * 1000, 'nwave': self.n_wave, 'wstep': self.d_wave * 1000, 'zstep': self.dz } return conf_dict def strehl_ratio(self): # this is very raw. Should save the indices for pixels inside the pupil. # by definition: phase = self.get_phase() ampli = self.get_ampli() ephase = np.exp(1j * phase) * np.sign(ampli) avg_ephase = ephase.sum() / self.NK strehl = np.abs(avg_ephase)**2 # by approximation: avg_phase = phase.sum() / self.NK var_phase = (np.sign(ampli) * (phase - avg_phase)**2).sum() / self.NK strehl_appro = np.exp(-var_phase) # count in amplitude effect: strehl_ampli = np.abs((ampli * ephase).sum() / ampli.sum())**2 return strehl, strehl_appro, strehl_ampli def shutDown(self): ''' what should I fill here? ''' pass
class Main: def __init__(self): # Global variables for executions self._title_exam = '' self._path_dataset_out = '' # Dependences self._process = ProcessImage() self._pupil = Pupil() self._eye = Eye() # Limit cash dependences self._max_execution_with_cash = 20 # Directoris self._projects_path = '/media/marcos/Dados/Projects' self._dataset_path = '{}/Datasets/exams'.format(self._projects_path) self._dataset_out = '{}/Results/PupilDeep/Frames'.format( self._projects_path) self._dataset_label = '{}/Results/PupilDeep/Labels'.format( self._projects_path) # Stops and executions self._frame_stop = 150 self._frame_start = 100 self._movie_stop = 0 self._list_not_available = [] self._list_available = [ '25080325_08_2019_08_48_58', '25080425_08_2019_08_53_48' ] # self._list_available = ['25080325_08_2019_08_48_58', '25080425_08_2019_08_53_48', '25080425_08_2019_08_55_59', '25080425_08_2019_09_05_40', '25080425_08_2019_09_08_25'] # self._list_available = ['new_benchmark'] # Params color self._white_color = (255, 255, 0) self._gray_color = (170, 170, 0) # Params text and circle print image self._position_text = (30, 30) self._font_text = cv2.FONT_HERSHEY_DUPLEX self._size_point_pupil = 5 # Params dataset labels out self._title_label = 'frame,center_x,center_y,radius,flash,eye_size,img_mean,img_std,img_median' def _add_label(self, information): with open('{}/{}_label.csv'.format(self._dataset_label, self._title_exam), 'a', newline='') as file: file.write('{}\n'.format(information)) file.close() def _make_path(self, path=''): try: if path == '': os.mkdir(self._path_dataset_out) else: os.mkdir(path) except FileExistsError: pass def _show_image(self, image, label, number_frame, color=None): system_continue = True paint = self._white_color if color is None else color cv2.putText(image, label, self._position_text, self._font_text, 0.9, paint) # cv2.namedWindow('Analysis', cv2.WINDOW_NORMAL) # cv2.imshow('Analysis', image) # order = cv2.waitKey(1) # # if order == 32: # time.sleep(2) # elif order == ord('q'): # system_continue = False self._save_images({'final': image}, number_frame) return system_continue def _save_images(self, images, number_frame, center=(0, 0)): for key, value in images.items(): if 'binary' in key: image = self._mark_center(value, center) else: image = value out = '{}/{}_{}.png'.format(self._path_dataset_out, key, number_frame) cv2.imwrite(out, image) def _save_histogram(self, histogram, number_frame): pl.hist(histogram, bins='auto') pl.title('Histogram Frame: {}'.format(number_frame)) pl.xlabel("Value") pl.ylabel("Frequency") pl.savefig("{}/histogram_{}.png".format(self._path_dataset_out, number_frame)) def _mark_eye(self, image, right, left): cv2.line(image, (right[0], right[1]), (left[0], left[1]), self._white_color, 1) return image def _mark_center(self, image, center): color = self._white_color cv2.line(image, (center[0] - 10, center[1]), (center[0] + 10, center[1]), color, 1) cv2.line(image, (center[0], center[1] - 10), (center[0], center[1] + 10), color, 1) return image def _draw_circles(self, image, points, radius=0, color=None): for point in points: rad = radius if radius > 0 else self._size_point_pupil paint = self._gray_color if color is None else color cv2.circle(image, (point[0], point[1]), rad, paint, 2) return image def _pupil_process(self, path_exam): number_frame = 0 system_continue = True exam = cv2.VideoCapture(path_exam) while system_continue: _, frame = exam.read() if (frame is None) or ((self._frame_stop > 0) and (number_frame >= self._frame_stop)): break if (self._frame_start > 0) and (number_frame < self._frame_start): number_frame += 1 continue original = np.copy(frame) img_orig_gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) self._save_images({'original': original}, number_frame) img_process, flash = self._process.process_image(original) self._save_images({'process': img_process}, number_frame) img_mean, img_std, img_median = img_process.mean( ), img_process.std(), np.median(img_process) center, radius, points, images = self._pupil.pupil_detect( img_process) binary = images['binary_pre_process'] binary = self._mark_center(binary, center) binary = self._draw_circles(binary, points, 2, self._white_color) self._save_images({'binary': binary}, number_frame, center) img_process = self._mark_center(img_process, center) img_process = self._draw_circles(img_process, points, 2, self._white_color) img_process = self._draw_circles(img_process, [(center[0], center[1])], radius, self._white_color) self._save_images({'img_process': img_process}, number_frame) self._save_histogram(images['histogram'], number_frame) img_presentation = cv2.hconcat( [img_orig_gray, binary, img_process]) label = 'Frame=%d;Radius=%d;Center=(%d,%d);Eye=(%d);Flash=(%d)' % ( number_frame, radius, center[0], center[1], 0, flash) system_continue = self._show_image(img_presentation, label, number_frame) self._add_label("{},{},{},{},{},{},{},{},{}".format( number_frame, center[0], center[1], radius, flash, 0, img_mean, img_std, img_median)) number_frame += 1 cv2.destroyAllWindows() exam.release() def run(self): files = os.listdir(self._dataset_path) number_movie = 0 for file in files: if (self._movie_stop > 0) and (number_movie >= self._movie_stop): break self._title_exam = file.replace('.mp4', '') self._path_dataset_out = '{}/{}'.format(self._dataset_out, self._title_exam) if (len(self._list_available) > 0) and (self._title_exam not in self._list_available): continue if self._title_exam in self._list_not_available: continue self._add_label(self._title_label) self._make_path() start_time = time.time() path_exam = '{}/{}'.format(self._dataset_path, file) self._pupil_process(path_exam) end_time = time.time() self._add_label('Execition time: {} minuts'.format( (end_time - start_time) / 60)) number_movie += 1
def pupil_process(self, paths): pupil_deep = PupilDeep() process = ProcessImage() pupil = Pupil(pupil_deep) draw = DrawImages() # information = Information() self._path_label = paths['path_label'] self._add_label(self._title_label) exam = cv2.VideoCapture(paths['path_exam']) fps = exam.get(cv2.CAP_PROP_FPS) # patient_exam, param_exam = information.get_information_exam(paths['path_information'], fps) number_frame = 0 while True: _, frame = exam.read() if (frame is None) or ((self._frame_stop > 0) and (number_frame >= self._frame_stop)): break if (self._frame_start > 0) and (number_frame < self._frame_start): number_frame += 1 continue original = np.copy(frame) img_orig_gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) # self._save_images({'original': original}, number_frame, paths['path_out']) img_process, flash = process.process_image(original) # self._save_images({'process': img_process}, number_frame, paths['path_out']) img_mean, img_std, img_median = img_process.mean(), img_process.std(), np.median(img_process) center, radius, points, images, mean_binary = pupil.pupil_detect(img_process) # binary = images['binary_pre_process'] # binary = draw.mark_center(binary, center) # binary = draw.draw_circles(binary, points, 2, self._white_color) # self._save_images({'binary': binary}, number_frame, paths['path_out'], center) img_process = draw.mark_center(img_process, center) img_process = draw.draw_circles(img_process, points, 2, self._white_color) img_process = draw.draw_circles(img_process, [(center[0], center[1])], radius, self._white_color) self._save_images({'img_process': img_process}, number_frame, paths['path_out']) # self._save_histogram(images['histogram'], number_frame, paths['path_out']) # img_presentation = cv2.hconcat([img_orig_gray, binary, img_process]) # label = 'Frame=%d;Radius=%d;Center=(%d,%d);BinMean=(%f)' % ( # number_frame, radius, center[0], center[1], mean_binary) # self._show_image(img_presentation, label, number_frame, paths['path_out']) # flash_information, color_information = information.get_information_params(number_frame) params = ['patient_exam', 'param_exam', number_frame, center[0], center[1], radius, flash, 'flash_information', 'color_information', 0, img_mean, img_std, img_median] self._add_params_label(params) number_frame += 1 cv2.destroyAllWindows() exam.release()
class Main: def __init__(self): self.dataset_path = r'C:\Projects\Datasets\eye_test\movies' self.dataset_out = r'C:\Projects\Datasets\eye_test\out' self.dataset_label = r'C:\Projects\Datasets\eye_test\label' self.title = '' self.dataset_out_exam = '' self.eye_tracker = deepeye.DeepEye() self.pupil = Pupil() self.reflections = Reflections() def _add_label(self, information): with open(r'{}\{}_label.csv'.format(self.dataset_label, self.title), 'a', newline='') as file: file.write('{}\n'.format(information)) file.close() def _make_dir(self, dir): try: os.mkdir(dir) except FileExistsError: pass def _pupil_process(self, exam): number_frame = 0 while True: _, frame = exam.read() if frame is None: break original = np.copy(frame[:, :, 0]) yuv = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV) yuv[:, :, 0] = cv2.equalizeHist(yuv[:, :, 0]) bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR) gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY) gaussian = cv2.GaussianBlur(gray, (9, 9), 3) median = cv2.medianBlur(gaussian, 3) kernel = np.ones((5, 5), np.uint8) erode = cv2.erode(median, kernel=kernel, iterations=1) dilate = cv2.dilate(erode, kernel=kernel, iterations=1) threshold = cv2.threshold(dilate, 25, 255, cv2.THRESH_BINARY)[1] final = np.copy(dilate) center = self.eye_tracker.run(final) default = dilate[center[0], center[1]] img_filter = [] for line in dilate: img_filter.append( [x if x not in range(180, 255) else default for x in line]) final = np.copy(img_filter) edges = self.pupil.pupil_detect(final, center) lin, col = gray.shape if 0 < center[0] < lin and 0 < center[1] < col: cv2.circle(final, (int(center[0]), int(center[1])), 10, (255, 255, 0), 2) for i in range(len(edges) - 1): if 0 < edges[i][0] < lin and 0 < edges[i][1] < col: if 0 < edges[i + 1][0] < lin and 0 < edges[i + 1][1] < col: cv2.line(final, (edges[i][0], edges[i][1]), (edges[i + 1][0], edges[i + 1][1]), color=(255, 0, 0)) cv2.line(final, (edges[len(edges) - 1][0], edges[len(edges) - 1][1]), (edges[0][0], edges[0][1]), color=(255, 0, 0)) text = 'frame={}, x={}, y={}'.format(number_frame, center[0], center[1]) cv2.putText(final, text, (25, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2, cv2.LINE_AA) number_frame += 1 original_out = r'{}\original_{}.png'.format( self.dataset_out_exam, number_frame) final_out = r'{}\final_{}.png'.format(self.dataset_out_exam, number_frame) presentation = cv2.hconcat([original, final, threshold]) cv2.namedWindow('Analysis', cv2.WINDOW_NORMAL) cv2.imshow('Analysis', presentation) cv2.waitKey(1) cv2.imwrite(original_out, final) cv2.imwrite(final_out, final) self._add_label("{},{},{}".format(number_frame, center[0], center[1])) exam.release() cv2.destroyAllWindows def run(self): files = os.listdir(self.dataset_path) for file in files: self.title = file.replace('.mp4', '') self._add_label('frame,x,y') self.dataset_out_exam = r'{}\{}'.format(self.dataset_out, self.title) self._make_dir(self.dataset_out_exam) exam = cv2.VideoCapture('{}/{}'.format(self.dataset_path, file)) self._pupil_process(exam)