def __init__(self, source=0): self.cap = Capture(source) # Input instance: # def. source == 0 (webcamera) self.out = Output() self.height = self.cap.height # Frame height self.width = self.cap.width # Frame width self.output_img_height = self.height * 2 self.output_img_width = self.output_img_height self.output_img_centre_x = self.height self.output_img_centre_y = self.height self.fps = self.cap.fps self.ORD_DICT = {'q':ord('q'), \ 'f':ord('f'), \ 'o':ord('o'), \ 'r':ord('r'), \ 'p':ord('p'), \ 'm':ord('m')} self.grab_cut = GrabCut(self.height, self.width) self.face_ex = None self.pos = {} # Dict with trackbars values self.pos['m_cntr'] = 0 # Centre of the mask in output_img self.pos['m_btm'] = 1 # Mask bottom corner position self.pos['m_side'] = 1.5 # Mask side corners pos self.pos['m_y_offset'] = 1 # Offset ratio of y mask coord. self.pos['i_x'] = int(self.width / 2) # frame x pos self.pos['i_y'] = int(self.height / 2) # frame y pos self.pos['scale'] = 1 # frame scale factor self.pos['loop_video'] = 1 # on/off self.pos['tracking_on'] = 0 # FaceTracking on/off self.pos['gc_iters'] = 0 # GrabCut iterations self.pos['contrast'] = 1 # contrast adj. self.pos['brightness'] = 0 # brightness adj. self.gui = Gui(self.height, self.width, self.pos) # GUI instance self.counter = 0 # Frame counter
class Ghost(object): """Pepper's Ghost video processor.""" def __init__(self, source=0): self.cap = Capture(source) # Input instance: # def. source == 0 (webcamera) self.out = Output() self.height = self.cap.height # Frame height self.width = self.cap.width # Frame width self.output_img_height = self.height * 2 self.output_img_width = self.output_img_height self.output_img_centre_x = self.height self.output_img_centre_y = self.height self.fps = self.cap.fps self.ORD_DICT = {'q':ord('q'), \ 'f':ord('f'), \ 'o':ord('o'), \ 'r':ord('r'), \ 'p':ord('p'), \ 'm':ord('m')} self.grab_cut = GrabCut(self.height, self.width) self.face_ex = None self.pos = {} # Dict with trackbars values self.pos['m_cntr'] = 0 # Centre of the mask in output_img self.pos['m_btm'] = 1 # Mask bottom corner position self.pos['m_side'] = 1.5 # Mask side corners pos self.pos['m_y_offset'] = 1 # Offset ratio of y mask coord. self.pos['i_x'] = int(self.width / 2) # frame x pos self.pos['i_y'] = int(self.height / 2) # frame y pos self.pos['scale'] = 1 # frame scale factor self.pos['loop_video'] = 1 # on/off self.pos['tracking_on'] = 0 # FaceTracking on/off self.pos['gc_iters'] = 0 # GrabCut iterations self.pos['contrast'] = 1 # contrast adj. self.pos['brightness'] = 0 # brightness adj. self.gui = Gui(self.height, self.width, self.pos) # GUI instance self.counter = 0 # Frame counter def run(self): """Video processing.""" self.start = time() while self.cap.is_opened(): frame = self.cap.next_frame() # Create output_img with all settings/segmentations applied to frame frame_mod = self._apply_settings(frame) output_img = self._create_output_img(frame=frame_mod, \ y_offset_ratio=self.pos['m_y_offset']) if self.out.is_opened: # Send output_img to output self.out.write(output_img) # Operation routines self.print_fps(self.gui.C_HDR) self.gui.preview(output_img) # Preview into Output window key_pressed = cv2.waitKey(1) & 0xFF if not self._process_key(key_pressed): break self.counter += 1 self.end = time() self.fps = self.get_fps() self.stop() def get_fps(self): fps = round(self.counter / (self.end - self.start), 2) if self.counter == 100: self.counter = 0 self.start = self.end return fps def print_fps(self, window_hrd='FPS'): canvas = np.zeros((70, 500, 3), np.uint8) cv2.putText(canvas, 'FPS: {0:.1f}'.format(self.fps), \ (10, 50), cv2.FONT_HERSHEY_PLAIN, 3, \ (255,255,255), 3, cv2.LINE_AA) cv2.imshow(window_hrd, canvas) def stop(self): """Release input/output if job is finished. And exit GUI.""" self.cap.release() self.out.release() self.gui.exit() def _apply_settings(self, frame): """Apply custom settings received from GUI (in self.pos). Args: frame -- original frame Returns: result -- modified frame according to users adjustments """ # Translate frame to (i_x, i_y) if (self.pos['i_x'] != 0) or (self.pos['i_y'] != 0): frame = translate(frame, int(self.pos['i_x']), \ int(self.pos['i_y'])) # Scale frame if self.pos['scale'] != 1: frame_scaled = scale(frame, self.pos['scale']) frame = fit_into(frame_scaled, self.height, self.width) # Adjust brightness/contrast result = frame.copy() result = brightness_contrast(result, self.pos['contrast'], \ self.pos['brightness']) # Apply face detection mask (if ON) if self.pos['tracking_on']: if self.face_ex == None: self.face_ex = FaceDetection(self.height, self.width) tr_mask = self.face_ex.track_faces(frame) result = apply_mask(result, tr_mask) # GrabCut face(fg) extraction if self.pos['gc_iters'] > 0: gc_mask = self.grab_cut.gc_mask( img=frame, \ iters=self.pos['gc_iters']) result = apply_mask(result, gc_mask) # Create triangle mask # Add decorator here self.mask = create_triangle_mask(height=self.height, \ width=self.width, \ side=self.pos['m_side'], \ centre=self.pos['m_cntr'], \ bottom=self.pos['m_btm']) self.cap.loop_video = self.pos['loop_video'] return result def _create_output_img(self, frame, y_offset_ratio=1): """Create projections rotated by 'angle' deg. CCW Args: frame -- processed frame y_offset_ratio -- mask y coord offset ratio Returns: output_img -- resulting img. """ # Create blank output_img output_img = np.zeros( (self.output_img_height, self.output_img_width, 3), np.uint8) # Calculate frame position in the output_img frame_x = self.output_img_centre_x - self.width // 2 frame_y = self.output_img_centre_y - self.height * y_offset_ratio # Apply triangle mask on projection projection = apply_mask(frame, self.mask) # Apply projection to Bottom Centre of output_img output_img[frame_y : frame_y + self.height, \ frame_x : frame_x + self.width] = projection # Add Top projection output_img = cv2.add(output_img, cv2.flip(output_img, -1)) # Add Left and Right projections output_img = cv2.add(output_img, cv2.flip(cv2.transpose(output_img), 1)) return output_img def _process_key(self, key_pressed): """Method called from while loop in run(). Porcesses the key pressed. returns 0 if EXIT button (def. 'q') is pressed. Else returns 1. Args: key_pressed -- ord value of key pressed Reurns: 1 -- take an action and go ahead in the loop 0 -- take an action and BREAK the loop """ if key_pressed == self.ORD_DICT['q']: # Wait for 'q' to exit return 0 elif key_pressed == self.ORD_DICT['f']: # Fullscreen on/off self.gui.toggle_fullscreen() elif key_pressed == self.ORD_DICT['o']: # Set output self.out.set_output(self.output_img_height, self.output_img_width) elif key_pressed == self.ORD_DICT['r']: # Release output self.out.release() elif key_pressed == self.ORD_DICT['p']: # Preview on/off self.gui.toggle_preview() elif key_pressed == self.ORD_DICT[ 'm']: # Change monitor (switch ratio) self.gui.change_monitor() return 1
class Ghost(object): """Pepper's Ghost video processor.""" def __init__(self, source=0): self.cap = Capture(source) # Input instance: # def. source == 0 (webcamera) self.out = Output() self.height = self.cap.height # Frame height self.width = self.cap.width # Frame width self.output_img_height = self.height * 2 self.output_img_width = self.output_img_height self.output_img_centre_x = self.height self.output_img_centre_y = self.height self.fps = self.cap.fps self.ORD_DICT = {'q':ord('q'), \ 'f':ord('f'), \ 'o':ord('o'), \ 'r':ord('r'), \ 'p':ord('p'), \ 'm':ord('m')} self.grab_cut = GrabCut(self.height, self.width) self.face_ex = None self.pos = {} # Dict with trackbars values self.pos['m_cntr'] = 0 # Centre of the mask in output_img self.pos['m_btm'] = 1 # Mask bottom corner position self.pos['m_side'] = 1.5 # Mask side corners pos self.pos['m_y_offset'] = 1 # Offset ratio of y mask coord. self.pos['i_x'] = int(self.width / 2) # frame x pos self.pos['i_y'] = int(self.height / 2) # frame y pos self.pos['scale'] = 1 # frame scale factor self.pos['loop_video'] = 1 # on/off self.pos['tracking_on'] = 0 # FaceTracking on/off self.pos['gc_iters'] = 0 # GrabCut iterations self.pos['contrast'] = 1 # contrast adj. self.pos['brightness'] = 0 # brightness adj. self.gui = Gui(self.height, self.width, self.pos) # GUI instance self.counter = 0 # Frame counter def run(self): """Video processing.""" self.start = time() while self.cap.is_opened(): frame = self.cap.next_frame() # Create output_img with all settings/segmentations applied to frame frame_mod = self._apply_settings(frame) output_img = self._create_output_img(frame=frame_mod, \ y_offset_ratio=self.pos['m_y_offset']) if self.out.is_opened: # Send output_img to output self.out.write(output_img) # Operation routines self.print_fps(self.gui.C_HDR) self.gui.preview(output_img) # Preview into Output window key_pressed = cv2.waitKey(1) & 0xFF if not self._process_key(key_pressed): break self.counter += 1 self.end = time() self.fps = self.get_fps() self.stop() def get_fps(self): fps = round(self.counter / (self.end - self.start), 2) if self.counter == 100: self.counter = 0 self.start = self.end return fps def print_fps(self, window_hrd='FPS'): canvas = np.zeros((70, 500, 3), np.uint8) cv2.putText(canvas, 'FPS: {0:.1f}'.format(self.fps), \ (10, 50), cv2.FONT_HERSHEY_PLAIN, 3, \ (255,255,255), 3, cv2.LINE_AA) cv2.imshow(window_hrd, canvas) def stop(self): """Release input/output if job is finished. And exit GUI.""" self.cap.release() self.out.release() self.gui.exit() def _apply_settings(self, frame): """Apply custom settings received from GUI (in self.pos). Args: frame -- original frame Returns: result -- modified frame according to users adjustments """ # Translate frame to (i_x, i_y) if (self.pos['i_x'] != 0)or(self.pos['i_y'] != 0): frame = translate(frame, int(self.pos['i_x']), \ int(self.pos['i_y'])) # Scale frame if self.pos['scale'] != 1: frame_scaled = scale(frame, self.pos['scale']) frame = fit_into(frame_scaled, self.height, self.width) # Adjust brightness/contrast result = frame.copy() result = brightness_contrast(result, self.pos['contrast'], \ self.pos['brightness']) # Apply face detection mask (if ON) if self.pos['tracking_on']: if self.face_ex == None: self.face_ex = FaceDetection(self.height, self.width) tr_mask = self.face_ex.track_faces(frame) result = apply_mask(result, tr_mask) # GrabCut face(fg) extraction if self.pos['gc_iters'] > 0: gc_mask = self.grab_cut.gc_mask( img=frame, \ iters=self.pos['gc_iters']) result = apply_mask(result, gc_mask) # Create triangle mask # Add decorator here self.mask = create_triangle_mask(height=self.height, \ width=self.width, \ side=self.pos['m_side'], \ centre=self.pos['m_cntr'], \ bottom=self.pos['m_btm']) self.cap.loop_video = self.pos['loop_video'] return result def _create_output_img(self, frame, y_offset_ratio=1): """Create projections rotated by 'angle' deg. CCW Args: frame -- processed frame y_offset_ratio -- mask y coord offset ratio Returns: output_img -- resulting img. """ # Create blank output_img output_img = np.zeros((self.output_img_height, self.output_img_width, 3), np.uint8) # Calculate frame position in the output_img frame_x = self.output_img_centre_x - self.width // 2 frame_y = self.output_img_centre_y - self.height * y_offset_ratio # Apply triangle mask on projection projection = apply_mask(frame, self.mask) # Apply projection to Bottom Centre of output_img output_img[frame_y : frame_y + self.height, \ frame_x : frame_x + self.width] = projection # Add Top projection output_img = cv2.add(output_img, cv2.flip(output_img, -1)) # Add Left and Right projections output_img = cv2.add(output_img, cv2.flip(cv2.transpose(output_img), 1)) return output_img def _process_key(self, key_pressed): """Method called from while loop in run(). Porcesses the key pressed. returns 0 if EXIT button (def. 'q') is pressed. Else returns 1. Args: key_pressed -- ord value of key pressed Reurns: 1 -- take an action and go ahead in the loop 0 -- take an action and BREAK the loop """ if key_pressed == self.ORD_DICT['q']: # Wait for 'q' to exit return 0 elif key_pressed == self.ORD_DICT['f']: # Fullscreen on/off self.gui.toggle_fullscreen() elif key_pressed == self.ORD_DICT['o']: # Set output self.out.set_output(self.output_img_height, self.output_img_width) elif key_pressed == self.ORD_DICT['r']: # Release output self.out.release() elif key_pressed == self.ORD_DICT['p']: # Preview on/off self.gui.toggle_preview() elif key_pressed == self.ORD_DICT['m']: # Change monitor (switch ratio) self.gui.change_monitor() return 1