def process_frame(frame, params, crop=True, preproc=True): if preproc: if crop: frame = imops.preprocess_image(frame, params['roi'], sig_cutoff=params['sig_cutoff'], sig_gain=params['sig_gain']) else: frame = imops.preprocess_image(frame, sig_cutoff=params['sig_cutoff'], sig_gain=params['sig_gain']) # get gradients grad_x, grad_y, edge_mag = imops.edge_vectors(frame, sigma=params['canny_sig'], return_angles=False) edges = imops.scharr_canny(frame, sigma=params['canny_sig'], high_threshold=params['canny_high'], low_threshold=params['canny_low'], grads={ 'grad_x': grad_x, 'grad_y': grad_y, 'edge_mag': edge_mag }) edges_rep = imops.repair_edges(edges, frame, grads={ 'grad_x': grad_x, 'grad_y': grad_y, 'edge_mag': edge_mag }) # return [(ellipse, n_pts)] try: return [(imops.fit_ellipse(e), len(e)) for e in edges_rep], frame, edge_mag except TypeError: return None
def run_new_shitty(): vid_file = '/home/lab/pupil_vids/nick3.avi' vid = cv2.VideoCapture(vid_file) roi = (725, 529, 523, 334) sig_cutoff = 0.7 sig_gain = 10 canny_sig = 4.07 canny_high = 1.17 canny_low = 0.3 for i in range(200): ret, frame_orig = vid.read() frame = imops.preprocess_image(frame_orig, roi, sig_cutoff=sig_cutoff, sig_gain=sig_gain) # canny edge detection & reshaping coords edges_params = imops.scharr_canny(frame, sigma=canny_sig, high_threshold=canny_high, low_threshold=canny_low)
def run_shitty(): vid_file = '/home/lab/pupil_vids/nick3.avi' # run once we get good params # remake video object to restart from frame 0 vid = cv2.VideoCapture(vid_file) total_frames = vid.get(cv2.CAP_PROP_FRAME_COUNT) roi = (725, 529, 523, 334) sig_cutoff = 0.7 sig_gain = 10 canny_sig = 4.07 canny_high = 1.17 canny_low = 0.3 # pmod = model.Pupil_Model(ix, iy, rad) # cv2.namedWindow('run', flags=cv2.WINDOW_NORMAL) # fig, ax = plt.subplots(4,1) thetas = np.linspace(0, np.pi * 2, num=100, endpoint=False) frame_counter = count() # frame_params = np.ndarray(shape=(0, 7)) x_list = [] y_list = [] a_list = [] b_list = [] t_list = [] n_list = [] v_list = [] starttime = time() for i in range(100): k = cv2.waitKey(1) & 0xFF if k == ord('\r'): break ret, frame_orig = vid.read() if ret == False: break n_frame = frame_counter.next() frame_orig = cv2.cvtColor(frame_orig, cv2.COLOR_BGR2GRAY) frame_orig = imops.crop(frame_orig, roi) frame = imops.preprocess_image(frame_orig, params['roi'], sig_cutoff=params['sig_cutoff'], sig_gain=params['sig_gain']) edges = scharr_canny(frame, sigma=params['canny_sig'], high_threshold=params['canny_high'], low_threshold=params['canny_low']) edges_rep = repair_edges(edges, frame) ellipses = [imops.fit_ellipse(e) for e in edges_rep] # ell_pts = np.ndarray(shape=(0, 2)) for e in ellipses: if not e: continue x_list.append(e.params[0]) y_list.append(e.params[1]) a_list.append(e.params[2]) b_list.append(e.params[3]) t_list.append(e.params[4]) n_list.append(n_frame) # get mean darkness ell_mask_y, ell_mask_x = draw.ellipse(e.params[0], e.params[1], e.params[2], e.params[3], shape=(frame.shape[1], frame.shape[0]), rotation=e.params[4]) v_list.append(np.mean(frame[ell_mask_x, ell_mask_y]))
draw.set_color(frame_orig, (e_points[:, 0], e_points[:, 1]), (1, 0, 0)) cv2.imshow('run', frame_orig) #frame_orig = frame_orig*255 #frame_orig = frame_orig.astype(np.uint8) #writer.writeFrame(frame_orig) #writer.close() cv2.destroyAllWindows() ret, frame_orig = vid.read() frame = imops.preprocess_image(frame_orig, roi, sig_cutoff=sig_cutoff, sig_gain=sig_gain) edges_params = imops.scharr_canny(frame, sigma=canny_sig, high_threshold=canny_high, low_threshold=canny_low) ax.imshow(edges_params) from PIL import ImageFilter, Image frame_8 = frame.copy() frame_8 = filters.gaussian(frame_8, sigma=2) frame_8 = frame_8 * 255 frame_8 = frame_8.astype(np.uint8) im = Image.fromarray(frame_8) im1 = im.filter(ImageFilter.EDGE_ENHANCE) im.show() im1.show()
def set_params(files): # cycle through files.. filecyc = cycle(files) # start with the first video vid = cv2.VideoCapture(filecyc.next()) # crop roi (x, y, width, height) roi, frame = get_crop_roi(vid) # draw pupil (sry its circular) ix, iy, rad = draw_pupil(frame) # initial values, empirically set. # have to use ints with cv2's windows, we'll convert later sig_cutoff = 50 sig_gain = 5 canny_sig = 200 canny_high = 50 canny_low = 10 closing_rad = 3 cv2.namedWindow('params', flags=cv2.WINDOW_NORMAL) cv2.createTrackbar('Sigmoid Cutoff', 'params', sig_cutoff, 100, imops.nothing) cv2.createTrackbar('Sigmoid Gain', 'params', sig_gain, 20, imops.nothing) cv2.createTrackbar('Gaussian Blur', 'params', canny_sig, 700, imops.nothing) cv2.createTrackbar('Canny High Threshold', 'params', canny_high, 300, imops.nothing) cv2.createTrackbar('Canny Low Threshold', 'params', canny_low, 300, imops.nothing) cv2.createTrackbar('Closing Radius', 'params', closing_rad, 10, imops.nothing) while True: k = cv2.waitKey(1) & 0xFF if k == ord('\r'): break ret, frame_orig = vid.read() if ret == False: # cycle to the next video (or restart) and skip this iter of param setting vid = cv2.VideoCapture(filecyc.next()) continue frame = frame_orig.copy() sig_cutoff = cv2.getTrackbarPos('Sigmoid Cutoff', 'params') sig_gain = cv2.getTrackbarPos('Sigmoid Gain', 'params') canny_sig = cv2.getTrackbarPos('Gaussian Blur', 'params') canny_high = cv2.getTrackbarPos('Canny High Threshold', 'params') canny_low = cv2.getTrackbarPos('Canny Low Threshold', 'params') closing_rad = cv2.getTrackbarPos('Closing Radius', 'params') # see i toldya it would be fine to have ints... sig_cutoff = sig_cutoff / 100. canny_sig = canny_sig / 100. canny_high = canny_high / 100. canny_low = canny_low / 100. frame = imops.preprocess_image(frame, roi, sig_cutoff=sig_cutoff, sig_gain=sig_gain, closing=closing_rad) edges_params = imops.scharr_canny(frame, sigma=canny_sig, high_threshold=canny_high, low_threshold=canny_low) # TODO: Also respect grayscale param here frame_orig = cv2.cvtColor(frame_orig, cv2.COLOR_BGR2GRAY) frame_orig = imops.crop(frame_orig, roi) frame_orig = img_as_float(frame_orig) cv2.imshow('params', np.vstack([frame_orig, frame, edges_params])) cv2.destroyAllWindows() # collect parameters params = { "sig_cutoff": sig_cutoff, "sig_gain": sig_gain, "canny_sig": canny_sig, "canny_high": canny_high, "canny_low": canny_low, "mask": { 'x': ix, 'y': iy, 'r': rad }, "files": files, "roi": roi, "shape": (roi[3], roi[2]), } return params
def process_frame_all(frame, params, n): frame = imops.preprocess_image(frame, sig_cutoff=params['sig_cutoff'], sig_gain=params['sig_gain']) # get gradients grad_x, grad_y, edge_mag = imops.edge_vectors(frame, sigma=params['canny_sig'], return_angles=False) edges = imops.scharr_canny(frame, sigma=params['canny_sig'], high_threshold=params['canny_high'], low_threshold=params['canny_low'], grads={ 'grad_x': grad_x, 'grad_y': grad_y, 'edge_mag': edge_mag }) edges_rep = imops.repair_edges(edges, frame, grads={ 'grad_x': grad_x, 'grad_y': grad_y, 'edge_mag': edge_mag }) if edges_rep is None: return {} ellipses = [(imops.fit_ellipse(e), len(e)) for e in edges_rep] # appending to lists is actually pretty fast in python when dealing w/ uncertain quantities # store ellipse parameters here, rejoin into a pandas dataframe at the end ret = { 'x': [], # x position of ellipse center 'y': [], # y position of ellipse center 'a': [], # major axis (enforced when lists are combined - fitutils.clean_lists) 'b': [], # minor axis ("") 't': [], # theta, angle of a from x axis, radians, increasing counterclockwise 'n': [], # frame number #'v': [], # mean value of points contained within ellipse 'c': [], # coverage - n_points/perimeter 'g': [] # gradient magnitude of edge points } for e, n_pts in ellipses: if not e: continue ret['x'].append(e.params[0]) ret['y'].append(e.params[1]) ret['a'].append(e.params[2]) ret['b'].append(e.params[3]) ret['t'].append(e.params[4]) ret['n'].append(n) # ell_mask_y, ell_mask_x = draw.ellipse(e.params[0], e.params[1], e.params[2], e.params[3], # shape=(frame.shape[1], frame.shape[0]), # rotation=e.params[4]) # v_list.append(np.mean(frame[ell_mask_x, ell_mask_y])) # coverage - number of points vs. circumference # perim: https://stackoverflow.com/a/42311034 perimeter = np.pi * (3 * (e.params[2] + e.params[3]) - np.sqrt( (3 * e.params[2] + e.params[3]) * (e.params[2] + 3 * e.params[3]))) ret['c'].append(float(n_pts) / perimeter) # get the mean edge mag for predicted points on the ellipse, # off-target ellipses often go through the pupil aka through areas with low gradients... e_points = np.round(e.predict_xy(np.linspace(0, np.pi * 2, 200))).astype(np.int) e_points[:, 0] = np.clip(e_points[:, 0], 0, frame.shape[0] - 1) e_points[:, 1] = np.clip(e_points[:, 1], 0, frame.shape[1] - 1) ret['g'].append(np.mean(edge_mag[e_points[:, 0], e_points[:, 1]])) return ret