Advertisement
dan-masek

Face Recognition Test - r2

Mar 27th, 2016
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.91 KB | None | 0 0
  1. import logging
  2. import logging.handlers
  3. import os
  4. import time
  5. import sys
  6.  
  7. import cv2
  8. import numpy as np
  9.  
  10. # ============================================================================
  11.  
  12. CASCADE_FILENAME = 'data/haarcascade_frontalface_alt.xml'
  13. MASK_FILENAME = 'data/mask.png'
  14.  
  15. IMAGE_DIR = "images"
  16. IMAGE_FILENAME_FORMAT = IMAGE_DIR + "/frame_%04d.png"
  17.  
  18. # Support either live acquisition or replay of saved frames
  19. CAPTURE_FROM_CAMERA = True
  20. if CAPTURE_FROM_CAMERA:
  21.     IMAGE_SOURCE = 0 # Default camera
  22. else:
  23.     IMAGE_SOURCE = IMAGE_FILENAME_FORMAT # Image sequence
  24.  
  25. # Time to wait between frames, 0=forever
  26. WAIT_TIME = 250 # ms
  27.  
  28. SCALING_FACTOR = 0.5
  29.  
  30. LOG_TO_FILE = False
  31.  
  32. # ============================================================================
  33.  
  34. def init_logging():
  35.     main_logger = logging.getLogger()
  36.  
  37.     formatter = logging.Formatter(
  38.         fmt='%(asctime)s.%(msecs)03d %(levelname)-8s [%(name)s] %(message)s'
  39.         , datefmt='%Y-%m-%d %H:%M:%S')
  40.    
  41.     handler_stream = logging.StreamHandler(sys.stdout)
  42.     handler_stream.setFormatter(formatter)
  43.     main_logger.addHandler(handler_stream)
  44.    
  45.     if LOG_TO_FILE:
  46.         handler_file = logging.handlers.RotatingFileHandler("debug.log"
  47.             , maxBytes = 2**24
  48.             , backupCount = 10)
  49.         handler_file.setFormatter(formatter)
  50.         main_logger.addHandler(handler_file)
  51.    
  52.     main_logger.setLevel(logging.DEBUG)
  53.    
  54.     return main_logger
  55.  
  56. # ============================================================================
  57.  
  58. def process_frame(frame_number, frame, face_cascade, face_mask, scaling_factor):
  59.     log = logging.getLogger("process_frame")
  60.    
  61.     resized_frame = cv2.resize(frame
  62.         , None
  63.         , fx=scaling_factor
  64.         , fy=scaling_factor
  65.         , interpolation=cv2.INTER_AREA)
  66.     log.debug("Resized frame: shape=%s", resized_frame.shape)
  67.    
  68.     # Let's make a copy to draw into
  69.     processed_frame = resized_frame.copy()
  70.     frame_height, frame_width = processed_frame.shape[:2]
  71.    
  72.     grayscale_frame = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2GRAY)
  73.  
  74.     CASCADE_SCALE_FACTOR = 1.3
  75.     CASCADE_MIN_NEIGHBORS = 5
  76.    
  77.     log.debug("Detecting faces...")
  78.     face_rects = face_cascade.detectMultiScale(grayscale_frame
  79.         , scaleFactor=CASCADE_SCALE_FACTOR
  80.         , minNeighbors=CASCADE_MIN_NEIGHBORS)
  81.     log.debug("Got %d matches.", len(face_rects))
  82.    
  83.     for (i, face_rect) in enumerate(face_rects):
  84.         (x,y,w,h) = face_rect
  85.         log.debug("Match #%d: pos=(x=%d, y=%d) size=(w=%d, h=%d)", i, x, y, w, h)
  86.        
  87.         if (h <= 0) or (w <= 0):
  88.             log.debug("Invalid match size, skipping.")
  89.             continue
  90.        
  91.         # Q: What's the reason for this?
  92.         h2 = int(1.4 * h)
  93.         w2 = int(1.0 * w)
  94.         y2 = y - 0.1 * h
  95.         x2 = x
  96.         log.debug("Scaled bounding box: pos=(x=%d, y=%d) size=(w=%d, h=%d)", x2, y2, w2, h2)
  97.        
  98.         frame_roi = processed_frame[y2:y2+h2, x2:x2+w2]
  99.         log.debug("Frame ROI: shape=%s", frame_roi.shape)
  100.        
  101.         resized_face_mask = cv2.resize(face_mask, (w2, h2), interpolation=cv2.INTER_AREA)
  102.         log.debug("Resized face mask: shape=%s", resized_face_mask.shape)
  103.        
  104.         # Trim the face mask, to handle bounding box bigger than frame...
  105.         trim_top, trim_bottom = 0, 0
  106.         if (y2 + h2 > frame_height):
  107.             trim_bottom = (y2 + h2) - frame_height
  108.         if (y2 < 0):
  109.             trim_top = -y2
  110.        
  111.         if (trim_top > 0) or (trim_bottom > 0):
  112.             log.debug("Trimming %d rows from top and %d rows from bottom of the mask.", trim_top, trim_bottom)
  113.             resized_face_mask = resized_face_mask[trim_top:(h2 - trim_bottom + 1),:]
  114.             log.debug("Trimmed face mask: shape=%s", resized_face_mask.shape)
  115.        
  116.         grayscale_face_mask = cv2.cvtColor(resized_face_mask, cv2.COLOR_BGR2GRAY)
  117.        
  118.         ret, mask = cv2.threshold(grayscale_face_mask, 180, 255, cv2.THRESH_BINARY_INV)
  119.         mask_inv = cv2.bitwise_not(mask)
  120.        
  121.         masked_face = cv2.bitwise_and(resized_face_mask, resized_face_mask, mask=mask)
  122.         masked_frame = cv2.bitwise_and(frame_roi, frame_roi, mask=mask_inv)
  123.        
  124.         processed_frame[y2:y2+h2, x2:x2+w2] = cv2.add(masked_face, masked_frame)
  125.        
  126.     return processed_frame
  127.  
  128. # ============================================================================
  129.  
  130. def main():
  131.     log = logging.getLogger("main")
  132.    
  133.     # Create the cascade classifier
  134.     log.debug("Loading cascade classifier `%s`...", CASCADE_FILENAME)
  135.     face_cascade = cv2.CascadeClassifier(CASCADE_FILENAME)
  136.     if face_cascade.empty():
  137.         raise IOError('Unable to load the face cascade classifier xml file')
  138.  
  139.     # Load and prepare the face mask
  140.     log.debug("Loading face mask `%s`...", MASK_FILENAME)
  141.     face_mask = cv2.imread(MASK_FILENAME)
  142.     if face_mask is None:
  143.         raise IOError('Unable to load the face mask image')
  144.     log.debug("Face mask loaded, shape=%s", face_mask.shape)
  145.  
  146.     # Set up image source
  147.     log.debug("Initializing video capture device #%s...", IMAGE_SOURCE)
  148.     cap = cv2.VideoCapture(IMAGE_SOURCE)
  149.    
  150.     frame_width = cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)
  151.     frame_height = cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
  152.     log.debug("Video capture frame size=(w=%d, h=%d)", frame_width, frame_height)
  153.        
  154.     log.debug("Starting capture loop...")
  155.     frame_number = -1
  156.     while True:
  157.         frame_number += 1
  158.         log.debug("Capturing frame #%d...", frame_number)
  159.         ret, frame = cap.read()
  160.         if not ret:
  161.             log.error("Frame capture failed, stopping...")
  162.             break
  163.  
  164.         log.debug("Got frame #%d: shape=%s", frame_number, frame.shape)
  165.        
  166.         # Archive raw frames from camera to disk, so we can play them back later
  167.         if CAPTURE_FROM_CAMERA:
  168.             file_name = IMAGE_FILENAME_FORMAT % frame_number
  169.             log.debug("Saving frame #%d as '%s'", frame_number, file_name)
  170.             cv2.imwrite(file_name, frame)
  171.            
  172.         log.debug("Processing frame #%d...", frame_number)
  173.         processed = process_frame(frame_number, frame, face_cascade, face_mask, SCALING_FACTOR)
  174.  
  175.         cv2.imshow('Source Image', frame)
  176.         cv2.imshow('Processed Image', processed)
  177.        
  178.         log.debug("Frame #%d processed.", frame_number)
  179.        
  180.         c = cv2.waitKey(WAIT_TIME)
  181.         if c == 27:
  182.             log.debug("ESC detected, stopping...")
  183.             break
  184.  
  185.     log.debug("Closing video capture device...")
  186.     cap.release()
  187.     cv2.destroyAllWindows()
  188.     log.debug("Done.")
  189.  
  190. # ============================================================================
  191.  
  192. if __name__ == "__main__":
  193.     log = init_logging()
  194.    
  195.     if not os.path.exists(IMAGE_DIR):
  196.         log.debug("Creating image directory `%s`...", IMAGE_DIR)
  197.         os.makedirs(IMAGE_DIR)
  198.    
  199.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement