def test_iou(self): r1 = face_extraction.Rectangle(20, 20, centerX=30, centerY=30) r2 = face_extraction.Rectangle(20, 20, centerX=40, centerY=30) self.assertNotEqual(r1.IOU(r2), 1) self.assertNotEqual(r1.IOU(r2), 0) self.assertEqual(r1.IOU(r1), 1) self.assertEqual(r2.IOU(r2), 1) r1 = face_extraction.Rectangle(20, 20, centerX=10, centerY=10) r2 = face_extraction.Rectangle(20, 20, centerX=20, centerY=10) self.assertEqual(r1.IOU(r2), 1 / 3) r2 = face_extraction.Rectangle(20, 20, centerX=50, centerY=20) self.assertEqual(r1.IOU(r2), 0)
def decode_object(o): if '__Point__' in o: a = face_extraction.Point(0, 0) a.__dict__.update(o['__Point__']) return a elif '__Rectangle__' in o: a = face_extraction.Rectangle(10, 10, centerX=5, centerY=5) a.__dict__.update(o['__Rectangle__']) return a elif '__FaceRect__' in o: a = face_extraction.FaceRect(None, None, None, None) a.__dict__.update(o['__FaceRect__']) if a.encoding is not None: a.encoding = np.asarray(a.encoding) # if a.image is not None: # a.image = np.asarray(a.image) # else: # logger.critical("Returned face did not have a regular image.") # if a.square_face is not None: # a.square_face = np.asarray(a.square_face) # else: # logger.critical("Returned face did not have a regular image.") return a elif '__datetime__' in o: return datetime.strptime(o['__datetime__'], '%Y-%m-%dT%H:%M:%S') return o
def test_resizing(self): a = face_extraction.Rectangle(50, 43, leftEdge=10, topEdge=15) # print(a) a_size = 50 * 43 a.resize(2) self.assertEqual(4 * a_size, a.height * a.width) a.resize(0.5) self.assertEqual(a_size, a.height * a.width) with self.assertRaises(ValueError): a.resize(0)
def test_missing_args(self): with self.assertRaises(face_extraction.rectangleError): a = face_extraction.Rectangle(50, 40) with self.assertRaises(face_extraction.rectangleError): a = face_extraction.Rectangle(50, 40, centerX=5) with self.assertRaises(face_extraction.rectangleError): a = face_extraction.Rectangle(50, 40, centerX=5, centerY=5, leftEdge=3) with self.assertRaises(face_extraction.rectangleError): a = face_extraction.Rectangle(50, 40, centerX=5, centerY=5, leftEdge=3, topEdge=6) with self.assertRaises(face_extraction.rectangleError): a = face_extraction.Rectangle(50, 40, leftEdge=3)
def test_intersect(self): r1 = face_extraction.Rectangle(20, 20, centerX=30, centerY=30) r2 = face_extraction.Rectangle(20, 20, centerX=35, centerY=35) ovd = r1.intersect(r2) self.assertEqual(ovd, 225)
def test_make_rect(self): a = face_extraction.Rectangle(50, 40, centerX=5, centerY=5) b = face_extraction.Rectangle(50, 40, leftEdge=3, topEdge=6)
def associate_detections_and_tags(image, pristine_image, detected_faces, tagged_faces, disp_photo=False, test=False): # Top-level function that takes a list of face_recognition # image pyramid detections (from my detect_pyramid function) # as well as tags from the XMP metadata (i.e. Picasa tags) # and associates them based on geometry. # Make sure our detected faces are the appropriate type if len(detected_faces) > 0: for df in detected_faces: assert isinstance(df, face_extraction.FaceRect) # Make sure our tagged faces are appropriate types and # have the right keys. if len(tagged_faces) > 0: for tf in tagged_faces: assert isinstance(tf, dict) assert 'Name' in tf.keys() assert 'bounding_rectangle' in tf.keys() # # Load in the pixels of the image, then copy it to # # pristine_image (that won't get drawn on) # image = face_recognition.load_image_file( # image_path) # pristine_image = copy.deepface_recognition.load_image_file( # image_path) # A test case to see if we can reject super-huge # faces. if test: huge_face = { 'Name': "nada", 'bounding_rectangle': face_extraction.Rectangle(int(image.shape[0] * .95), int(image.shape[1] * .95), centerX=image.shape[1] // 2, centerY=image.shape[0] // 2) } tagged_faces.append(huge_face) if disp_photo: draw_image = image.copy() for df in detected_faces: df.rectangle.drawOnPhoto(draw_image) for tf in tagged_faces: tf['bounding_rectangle'].drawOnPhoto(draw_image, colorTriple=(0, 255, 0)) # Two steps -- we first need to merge the # detected faces. Since we have an image pyramid # approach to image detection, we want to first # de-duplicate these before we try and mess with # matching with Picasa images. merged_detections = _merge_detected_faces(detected_faces, pristine_image) if disp_photo: for d in merged_detections: d.rectangle.drawOnPhoto(draw_image, colorTriple=(0, 0, 255)) # After de-duplicating face_recognition tags, then # we can merge them with Picasa tags. fully_matched = _merge_detections_with_tags(merged_detections, tagged_faces, pristine_image) if disp_photo: # A routine to write the names with the # faces as well as make the tagged face boxes # larger for drawing. for df in fully_matched: rr = df.rectangle.copy() # Expand the rectangle +- 10 pixels in each direction rr.left = rr.left - 10 rr.top = rr.top - 10 rr.width = rr.width + 20 rr.height = rr.height + 20 df.rectangle.drawOnPhoto(draw_image, colorTriple=(235, 189, 52)) font = cv2.FONT_HERSHEY_SIMPLEX bottomLeftCornerOfText = (rr.left, rr.bottom) fontScale = 2 fontColor = (255, 255, 255) lineType = 4 if df.name is not None: name = df.name else: name = "None" cv2.putText(draw_image, name, bottomLeftCornerOfText, font, fontScale, fontColor, lineType) plt.figure() plt.imshow(draw_image) plt.show() # Cut out the fully-matched faces from the pristine # image and assign it to the image field of the # FaceRect structure. for df in fully_matched: r = df.rectangle cut_rectangle = pristine_image[r.top:r.bottom, r.left:r.right] assert (df.face_image_nonrect.shape == cut_rectangle.shape) df.face_image_nonrect = cut_rectangle return fully_matched