hasnanmr commited on
Commit
e0006de
1 Parent(s): 82191d9

fixing verification algorithm

Browse files
Files changed (3) hide show
  1. .gitattributes +1 -0
  2. app.py +40 -47
  3. faceNet6.pth +3 -0
.gitattributes CHANGED
@@ -34,3 +34,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  faceViT4.pth filter=lfs diff=lfs merge=lfs -text
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  faceViT4.pth filter=lfs diff=lfs merge=lfs -text
37
+ faceNet6.pth filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -1,49 +1,30 @@
1
  import torch
2
- from torch import nn
3
  import torchvision.transforms as transforms
4
  import numpy as np
5
  import gradio as gr
6
- from PIL import Image
7
- from facenet_pytorch import MTCNN
8
- from transformers import ViTImageProcessor, ViTModel
9
  import time
10
 
11
- # Define the ViT class
12
- class ViT(nn.Module):
13
- def __init__(self, base_model):
14
- super(ViT, self).__init__()
15
- self.base_model = base_model
16
-
17
- def forward(self, x):
18
- x = self.base_model(x).pooler_output
19
- return x
20
-
21
- # Load the model and processor
22
- model_name = "google/vit-base-patch16-224"
23
- processor = ViTImageProcessor.from_pretrained(model_name)
24
- base_model = ViTModel.from_pretrained("WinKawaks/vit-small-patch16-224")
25
- model = ViT(base_model)
26
- model.load_state_dict(torch.load('faceViT4.pth'))
27
-
28
- # Set the model to evaluation mode
29
- model.eval()
30
-
31
- # Check if CUDA is available and move the model to GPU if it is
32
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
33
- model.to(device)
34
 
35
- # Initialize MTCNN for face detection
36
- mtcnn = MTCNN(keep_all=True, device=device)
 
 
 
 
37
 
38
  # Define the transformation with normalization
39
- val_test_transform_vit = transforms.Compose([
40
- transforms.Resize((224, 224)),
41
  transforms.ToTensor(),
42
- transforms.Normalize(mean=processor.image_mean, std=processor.image_std)
43
  ])
44
 
45
- def compare_faces(embedding1, embedding2, threshold=0.6): # Adjusted threshold
46
- dist = np.linalg.norm(embedding1.cpu().numpy() - embedding2.cpu().numpy())
47
  return dist, dist < threshold
48
 
49
  def align_face(frame):
@@ -57,11 +38,16 @@ def align_face(frame):
57
  face = faces[0]
58
  # Convert the face tensor to PIL Image
59
  face = transforms.ToPILImage()(face)
60
- return face
61
- return None
 
 
 
 
 
62
 
63
  def l2_normalize(tensor):
64
- norm = torch.norm(tensor, p=2, dim=1, keepdim=True)
65
  return tensor / norm
66
 
67
  def process_images(image1, image2):
@@ -70,37 +56,44 @@ def process_images(image1, image2):
70
  frame1 = np.array(image1)
71
  frame2 = np.array(image2)
72
 
73
- face1 = align_face(frame1)
74
- face2 = align_face(frame2)
75
 
76
  if face1 is None or face2 is None:
77
  return None, "Face not detected in one or both images."
78
 
79
- face1 = val_test_transform_vit(face1).unsqueeze(0).to(device)
80
- face2 = val_test_transform_vit(face2).unsqueeze(0).to(device)
81
 
82
  with torch.no_grad():
83
- embedding1 = model(face1)
84
- embedding2 = model(face2)
85
 
86
  embedding1 = l2_normalize(embedding1)
87
  embedding2 = l2_normalize(embedding2)
88
 
89
- distance, is_match = compare_faces(embedding1, embedding2, threshold=0.88)
 
 
 
90
 
91
  end_time = time.time()
92
  inference_time = end_time - start_time
93
 
94
- result = f"Distance: {distance:.2f}\nMatch: {is_match}\nInference time: {inference_time:.2f} seconds"
 
 
 
 
95
 
96
- return (image1, image2), result
97
 
98
  # Create the Gradio interface
99
  iface = gr.Interface(
100
  fn=process_images,
101
  inputs=[gr.Image(type="pil"), gr.Image(type="pil")],
102
  outputs=[gr.Gallery(), gr.Textbox()],
103
- title="Face Verification with MTCNN and ViT",
104
  description="Upload two images and the model will verify if the faces in both images are of the same person."
105
  )
106
 
 
1
  import torch
 
2
  import torchvision.transforms as transforms
3
  import numpy as np
4
  import gradio as gr
5
+ from PIL import Image, ImageDraw
6
+ from facenet_pytorch import MTCNN, InceptionResnetV1
 
7
  import time
8
 
9
+ # Initialize MTCNN for face detection with smaller face size detection
10
+ mtcnn = MTCNN(keep_all=True, device='cuda' if torch.cuda.is_available() else 'cpu', min_face_size=12)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ # Load the pre-trained FaceNet model
13
+ facenet = InceptionResnetV1(pretrained='vggface2').eval().to('cuda' if torch.cuda.is_available() else 'cpu')
14
+ model_path = r'D:\BRI BRAIN\faceNet6.pth'
15
+ model_state_dict = torch.load(model_path)
16
+ facenet.load_state_dict(model_state_dict)
17
+ facenet.eval() # Set the model to evaluation mode
18
 
19
  # Define the transformation with normalization
20
+ val_test_transform = transforms.Compose([
21
+ transforms.Resize((160, 160)), # FaceNet expects 160x160 input
22
  transforms.ToTensor(),
23
+ transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
24
  ])
25
 
26
+ def compare_faces(embedding1, embedding2, threshold=0.5): # Adjusted threshold
27
+ dist = np.linalg.norm(embedding1 - embedding2)
28
  return dist, dist < threshold
29
 
30
  def align_face(frame):
 
38
  face = faces[0]
39
  # Convert the face tensor to PIL Image
40
  face = transforms.ToPILImage()(face)
41
+ return face, boxes[0]
42
+ return None, None
43
+
44
+ def draw_bounding_box(image, box):
45
+ draw = ImageDraw.Draw(image)
46
+ draw.rectangle(box.tolist(), outline="red", width=3)
47
+ return image
48
 
49
  def l2_normalize(tensor):
50
+ norm = np.linalg.norm(tensor, ord=2, axis=1, keepdims=True)
51
  return tensor / norm
52
 
53
  def process_images(image1, image2):
 
56
  frame1 = np.array(image1)
57
  frame2 = np.array(image2)
58
 
59
+ face1, box1 = align_face(frame1)
60
+ face2, box2 = align_face(frame2)
61
 
62
  if face1 is None or face2 is None:
63
  return None, "Face not detected in one or both images."
64
 
65
+ face1 = val_test_transform(face1).unsqueeze(0).to('cuda' if torch.cuda.is_available() else 'cpu')
66
+ face2 = val_test_transform(face2).unsqueeze(0).to('cuda' if torch.cuda.is_available() else 'cpu')
67
 
68
  with torch.no_grad():
69
+ embedding1 = facenet(face1).cpu().numpy()
70
+ embedding2 = facenet(face2).cpu().numpy()
71
 
72
  embedding1 = l2_normalize(embedding1)
73
  embedding2 = l2_normalize(embedding2)
74
 
75
+ distance, is_match = compare_faces(embedding1, embedding2, threshold=0.2)
76
+
77
+ # Calculate confidence
78
+ confidence = max(0.0, 1.0 - distance / 1.0) # Ensure confidence is between 0 and 1
79
 
80
  end_time = time.time()
81
  inference_time = end_time - start_time
82
 
83
+ # Draw bounding boxes on the original images
84
+ image1_with_box = draw_bounding_box(image1, box1)
85
+ image2_with_box = draw_bounding_box(image2, box2)
86
+
87
+ result = f"Distance: {distance:.2f}\nMatch: {is_match}\nConfidence: {confidence:.2f}\nInference time: {inference_time:.2f} seconds"
88
 
89
+ return [image1_with_box, image2_with_box], result
90
 
91
  # Create the Gradio interface
92
  iface = gr.Interface(
93
  fn=process_images,
94
  inputs=[gr.Image(type="pil"), gr.Image(type="pil")],
95
  outputs=[gr.Gallery(), gr.Textbox()],
96
+ title="Face Verification with FaceNet",
97
  description="Upload two images and the model will verify if the faces in both images are of the same person."
98
  )
99
 
faceNet6.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fc80c77dda898bfdb928a761bdd91522482160f7fc5d341573ce79de80b38d56
3
+ size 112013482