909ahmed commited on
Commit
be9fb11
·
1 Parent(s): 85ffef1
FacePass.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from yolo.yoloFace import YOLO_FACE
2
+ from vgg.vgg_face import MODEL_FACE
3
+ from database.retriever import BruteForceStore
4
+ import cv2
5
+
6
+
7
+ DB = BruteForceStore()
8
+
9
+ def pipeline(img):
10
+
11
+ images = YOLO_FACE(img)
12
+ for patch in images:
13
+ embeddings = MODEL_FACE(patch)
14
+ if DB(embeddings): return "Welcome!"
15
+
16
+ return "Buzz off!!! petrichor me chor"
17
+
18
+ if __name__ == "__main__":
19
+
20
+ import cv2
21
+
22
+ img = cv2.imread('temp.jpg', cv2.IMREAD_UNCHANGED)
23
+ print(pipeline(img))
ReadMe.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## How to run:
2
+ Be in root directory: FacePass/
3
+ 1. pip install -r requirements.txt to install all requirements. Python 3.12 recommended
4
+ 2. Create a folder named models and add your images into it
5
+ 3. Download the models from the links given in refs.txt and add them in models
6
+ 4. To run the program: python3 FacePass.py
7
+
8
+ ## Additional Instruction:
9
+ When taking images to store in database please remove your glasses. Similarly when unlocking the facelock remove your glasses
10
+
11
+ ## Future work:
12
+ 1. Make a better database or use existing ones like FAISS
13
+ 2. Make a user interface so that the adminstrator can registor new users into the database
14
+ 3. For now the threshold value seems to be working fine but further tweaking and fine tuning is required
app.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from yolo.yoloFace import YOLO_FACE
3
+ from vgg.vgg_face import MODEL_FACE
4
+ from database.retriever import BruteForceStore
5
+ import cv2
6
+
7
+ # Initialize the database
8
+ DB = BruteForceStore()
9
+
10
+ def pipeline(img):
11
+ images = YOLO_FACE(img)
12
+ for patch in images:
13
+ embeddings = MODEL_FACE(patch)
14
+ if DB(embeddings):
15
+ return "Welcome!"
16
+ return "Unauthorised"
17
+
18
+ # Define a Gradio interface
19
+ def process_image(image):
20
+ if image is None:
21
+ return "Please upload an image."
22
+ result = pipeline(image)
23
+ return result
24
+
25
+ # Gradio App
26
+ with gr.Blocks() as demo:
27
+ gr.Markdown("""
28
+ <div style="background: url('/home/asad/temp/app/FacePass/logo.png') no-repeat center center fixed; background-size: cover; height: 100%; padding: 20px; display: flex; flex-direction: column; justify-content: center; align-items: center;">
29
+ <h1 style="text-align: center; color: white;">
30
+ Face Verification App
31
+ </h1>
32
+ <h3 style="text-align: center; color: lightgrey;">
33
+ Upload your photo and let the app verify your identity!
34
+ </h3>
35
+ </div>
36
+ """)
37
+
38
+ with gr.Row():
39
+ with gr.Column(scale=1):
40
+ image_input = gr.Image(type="numpy", label="Upload Your Image")
41
+ with gr.Column(scale=1):
42
+ output_text = gr.Textbox(label="Verification Result", interactive=False)
43
+
44
+ with gr.Row():
45
+ submit_button = gr.Button("Verify")
46
+ submit_button.click(process_image, inputs=[image_input], outputs=[output_text])
47
+
48
+ if __name__ == "__main__":
49
+ demo.launch()
coco.names ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ person
2
+ bicycle
3
+ car
4
+ motorbike
5
+ aeroplane
6
+ bus
7
+ train
8
+ truck
9
+ boat
10
+ traffic light
11
+ fire hydrant
12
+ stop sign
13
+ parking meter
14
+ bench
15
+ bird
16
+ cat
17
+ dog
18
+ horse
19
+ sheep
20
+ cow
21
+ elephant
22
+ bear
23
+ zebra
24
+ giraffe
25
+ backpack
26
+ umbrella
27
+ handbag
28
+ tie
29
+ suitcase
30
+ frisbee
31
+ skis
32
+ snowboard
33
+ sports ball
34
+ kite
35
+ baseball bat
36
+ baseball glove
37
+ skateboard
38
+ surfboard
39
+ tennis racket
40
+ bottle
41
+ wine glass
42
+ cup
43
+ fork
44
+ knife
45
+ spoon
46
+ bowl
47
+ banana
48
+ apple
49
+ sandwich
50
+ orange
51
+ broccoli
52
+ carrot
53
+ hot dog
54
+ pizza
55
+ donut
56
+ cake
57
+ chair
58
+ sofa
59
+ pottedplant
60
+ bed
61
+ diningtable
62
+ toilet
63
+ tvmonitor
64
+ laptop
65
+ mouse
66
+ remote
67
+ keyboard
68
+ cell phone
69
+ microwave
70
+ oven
71
+ toaster
72
+ sink
73
+ refrigerator
74
+ book
75
+ clock
76
+ vase
77
+ scissors
78
+ teddy bear
79
+ hair drier
80
+ toothbrush
configs/yolov3-tiny.cfg ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [net]
2
+ # Testing
3
+ batch=1
4
+ subdivisions=1
5
+ # Training
6
+ # batch=64
7
+ # subdivisions=2
8
+ width=416
9
+ height=416
10
+ channels=3
11
+ momentum=0.9
12
+ decay=0.0005
13
+ angle=0
14
+ saturation = 1.5
15
+ exposure = 1.5
16
+ hue=.1
17
+
18
+ learning_rate=0.001
19
+ burn_in=1000
20
+ max_batches = 500200
21
+ policy=steps
22
+ steps=400000,450000
23
+ scales=.1,.1
24
+
25
+ [convolutional]
26
+ batch_normalize=1
27
+ filters=16
28
+ size=3
29
+ stride=1
30
+ pad=1
31
+ activation=leaky
32
+
33
+ [maxpool]
34
+ size=2
35
+ stride=2
36
+
37
+ [convolutional]
38
+ batch_normalize=1
39
+ filters=32
40
+ size=3
41
+ stride=1
42
+ pad=1
43
+ activation=leaky
44
+
45
+ [maxpool]
46
+ size=2
47
+ stride=2
48
+
49
+ [convolutional]
50
+ batch_normalize=1
51
+ filters=64
52
+ size=3
53
+ stride=1
54
+ pad=1
55
+ activation=leaky
56
+
57
+ [maxpool]
58
+ size=2
59
+ stride=2
60
+
61
+ [convolutional]
62
+ batch_normalize=1
63
+ filters=128
64
+ size=3
65
+ stride=1
66
+ pad=1
67
+ activation=leaky
68
+
69
+ [maxpool]
70
+ size=2
71
+ stride=2
72
+
73
+ [convolutional]
74
+ batch_normalize=1
75
+ filters=256
76
+ size=3
77
+ stride=1
78
+ pad=1
79
+ activation=leaky
80
+
81
+ [maxpool]
82
+ size=2
83
+ stride=2
84
+
85
+ [convolutional]
86
+ batch_normalize=1
87
+ filters=512
88
+ size=3
89
+ stride=1
90
+ pad=1
91
+ activation=leaky
92
+
93
+ [maxpool]
94
+ size=2
95
+ stride=1
96
+
97
+ [convolutional]
98
+ batch_normalize=1
99
+ filters=1024
100
+ size=3
101
+ stride=1
102
+ pad=1
103
+ activation=leaky
104
+
105
+ ###########
106
+
107
+ [convolutional]
108
+ batch_normalize=1
109
+ filters=256
110
+ size=1
111
+ stride=1
112
+ pad=1
113
+ activation=leaky
114
+
115
+ [convolutional]
116
+ batch_normalize=1
117
+ filters=512
118
+ size=3
119
+ stride=1
120
+ pad=1
121
+ activation=leaky
122
+
123
+ [convolutional]
124
+ size=1
125
+ stride=1
126
+ pad=1
127
+ filters=255
128
+ activation=linear
129
+
130
+
131
+
132
+ [yolo]
133
+ mask = 3,4,5
134
+ anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
135
+ classes=80
136
+ num=6
137
+ jitter=.3
138
+ ignore_thresh = .7
139
+ truth_thresh = 1
140
+ random=1
141
+
142
+ [route]
143
+ layers = -4
144
+
145
+ [convolutional]
146
+ batch_normalize=1
147
+ filters=128
148
+ size=1
149
+ stride=1
150
+ pad=1
151
+ activation=leaky
152
+
153
+ [upsample]
154
+ stride=2
155
+
156
+ [route]
157
+ layers = -1, 8
158
+
159
+ [convolutional]
160
+ batch_normalize=1
161
+ filters=256
162
+ size=3
163
+ stride=1
164
+ pad=1
165
+ activation=leaky
166
+
167
+ [convolutional]
168
+ size=1
169
+ stride=1
170
+ pad=1
171
+ filters=255
172
+ activation=linear
173
+
174
+ [yolo]
175
+ mask = 0,1,2
176
+ anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
177
+ classes=80
178
+ num=6
179
+ jitter=.3
180
+ ignore_thresh = .7
181
+ truth_thresh = 1
182
+ random=1
database/__pycache__/retriever.cpython-312.pyc ADDED
Binary file (3.47 kB). View file
 
database/__pycache__/utils.cpython-312.pyc ADDED
Binary file (666 Bytes). View file
 
database/retriever.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from database.utils import similarity
3
+ import cv2
4
+ from vgg.vgg_face import MODEL_FACE
5
+ from yolo.yoloFace import YOLO_FACE
6
+
7
+ class Retriever:
8
+ """Base Retriever class"""
9
+ def __init__(self, thres=0.7, folder_loc="database/images", *args, **kwargs):
10
+ self.thres = thres
11
+ self.folder_loc = folder_loc
12
+ def unlock_lock(self, *args, **kwargs): ...
13
+ def __call__(self, *args, **kwargs):
14
+ return self.unlock_lock(*args, **kwargs)
15
+
16
+ class Naive(Retriever):
17
+ def unlock_lock(self, emb):
18
+ "Kind of Dynamic but very slow"
19
+ for root, dirs, files in os.walk(self.folder_loc):
20
+ for file in files:
21
+ file_path = os.path.join(root, file)
22
+ image = cv2.imread(file_path)
23
+ for patch in YOLO_FACE(image):
24
+ embedding = MODEL_FACE(patch)
25
+ if similarity(emb, embedding) > self.thres:
26
+ return True
27
+ return False
28
+
29
+ class BruteForceStore(Retriever):
30
+ def __init__(self, *args, **kwargs):
31
+ """
32
+ Watch dog integration required later
33
+ Only Use when the number of images are less
34
+ """
35
+ super().__init__(*args, **kwargs)
36
+ self.embeddings = []
37
+ for root, dirs, files in os.walk(self.folder_loc):
38
+ for file in files:
39
+ file_path = os.path.join(root, file)
40
+ image = cv2.imread(file_path)
41
+ for patch in YOLO_FACE(image):
42
+ embedding = MODEL_FACE(patch)
43
+ self.embeddings.append(embedding)
44
+
45
+ def unlock_lock(self, emb):
46
+ """Only Use when the number of images are less"""
47
+ for embedding in self.embeddings:
48
+ print(f"similarity : {similarity(emb, embedding)}")
49
+ if similarity(emb, embedding) > self.thres:
50
+ return True
51
+ return False
database/utils.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ def similarity(v1:np.ndarray, v2:np.ndarray):
4
+ num = (v1 @ v2.T).item()
5
+ denom = np.linalg.norm(v1) * np.linalg.norm(v2)
6
+ print(num/denom)
7
+ return num/denom
logo.png ADDED
main.py ADDED
File without changes
models/best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ca9fa06b00e315bcebddff31c899cbed65b44fe548da08ad87d67d629fa760e4
3
+ size 6197752
models/vgg_face_dag.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f070b241e3faf17a08c78f8700d334413230bac5de7fbcfd01b3cf05ce10de1a
3
+ size 580015466
refs.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ references:
2
+ https://github.com/noorkhokhar99/face-detection-yolov8/blob/main/test_web.py
3
+ https://www.robots.ox.ac.uk/~albanie/pytorch-models.html
4
+
5
+
6
+ download links:
7
+ vgg_face: http://www.robots.ox.ac.uk/~albanie/models/pytorch-mcn/vgg_face_dag.pth
8
+ yolo_face: https://github.com/noorkhokhar99/face-detection-yolov8/blob/main/best.pt
requirements.txt ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ certifi==2024.12.14
2
+ charset-normalizer==3.4.0
3
+ contourpy==1.3.1
4
+ cycler==0.12.1
5
+ filelock==3.16.1
6
+ fonttools==4.55.3
7
+ fsspec==2024.10.0
8
+ idna==3.10
9
+ Jinja2==3.1.4
10
+ kiwisolver==1.4.7
11
+ MarkupSafe==3.0.2
12
+ matplotlib==3.10.0
13
+ mpmath==1.3.0
14
+ networkx==3.4.2
15
+ numpy==2.2.0
16
+ nvidia-cublas-cu12==12.4.5.8
17
+ nvidia-cuda-cupti-cu12==12.4.127
18
+ nvidia-cuda-nvrtc-cu12==12.4.127
19
+ nvidia-cuda-runtime-cu12==12.4.127
20
+ nvidia-cudnn-cu12==9.1.0.70
21
+ nvidia-cufft-cu12==11.2.1.3
22
+ nvidia-curand-cu12==10.3.5.147
23
+ nvidia-cusolver-cu12==11.6.1.9
24
+ nvidia-cusparse-cu12==12.3.1.170
25
+ nvidia-nccl-cu12==2.21.5
26
+ nvidia-nvjitlink-cu12==12.4.127
27
+ nvidia-nvtx-cu12==12.4.127
28
+ opencv-python==4.10.0.84
29
+ packaging==24.2
30
+ pandas==2.2.3
31
+ pillow==11.0.0
32
+ psutil==6.1.0
33
+ py-cpuinfo==9.0.0
34
+ pyparsing==3.2.0
35
+ python-dateutil==2.9.0.post0
36
+ pytz==2024.2
37
+ PyYAML==6.0.2
38
+ requests==2.32.3
39
+ scipy==1.14.1
40
+ seaborn==0.13.2
41
+ setuptools==75.6.0
42
+ six==1.17.0
43
+ sympy==1.13.1
44
+ torch==2.5.1
45
+ torchvision==0.20.1
46
+ tqdm==4.67.1
47
+ triton==3.1.0
48
+ typing_extensions==4.12.2
49
+ tzdata==2024.2
50
+ ultralytics==8.3.51
51
+ ultralytics-thop==2.0.13
52
+ urllib3==2.2.3
53
+ gradio
temp.jpg ADDED
vgg/__pycache__/vgg_face.cpython-312.pyc ADDED
Binary file (7.76 kB). View file
 
vgg/vgg19.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from torch import nn
3
+
4
+ KERNEL_SIZE = (3,3)
5
+
6
+ class VGG19(nn.Module):
7
+ def __init__(self, *args, **kwargs) -> None:
8
+ super().__init__(*args, **kwargs)
9
+ self.features = nn.Sequential(
10
+ nn.Conv2d(3, 64, KERNEL_SIZE, 1, 1),
11
+ nn.ReLU(),
12
+ nn.Conv2d(64, 64, KERNEL_SIZE, 1, 1),
13
+ nn.ReLU(),
14
+
15
+ nn.MaxPool2d(2),
16
+
17
+ nn.Conv2d(64, 128, KERNEL_SIZE, 1, 1),
18
+ nn.ReLU(),
19
+ nn.Conv2d(128, 128, KERNEL_SIZE, 1, 1),
20
+ nn.ReLU(),
21
+
22
+ nn.MaxPool2d(2),
23
+
24
+ nn.Conv2d(128, 256, KERNEL_SIZE, 1, 1),
25
+ nn.ReLU(),
26
+ nn.Conv2d(256, 256, KERNEL_SIZE, 1, 1),
27
+ nn.ReLU(),
28
+ nn.Conv2d(256, 256, KERNEL_SIZE, 1, 1),
29
+ nn.ReLU(),
30
+ nn.Conv2d(256, 256, KERNEL_SIZE, 1, 1),
31
+ nn.ReLU(),
32
+
33
+ nn.MaxPool2d(2),
34
+
35
+ nn.Conv2d(256, 512, KERNEL_SIZE, 1, 1),
36
+ nn.ReLU(),
37
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
38
+ nn.ReLU(),
39
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
40
+ nn.ReLU(),
41
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
42
+ nn.ReLU(),
43
+
44
+ nn.MaxPool2d(2),
45
+
46
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
47
+ nn.ReLU(),
48
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
49
+ nn.ReLU(),
50
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
51
+ nn.ReLU(),
52
+ nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1),
53
+ nn.ReLU(),
54
+
55
+ nn.MaxPool2d(2)
56
+ )
57
+ self.classifier = nn.Sequential(
58
+ nn.Linear(49*512, 4096),
59
+ nn.ReLU(),
60
+ nn.Dropout(),
61
+ nn.Linear(4096, 4096),
62
+ nn.ReLU(),
63
+ nn.Dropout(),
64
+ nn.Linear(4096, 1000),
65
+ )
66
+ def forward(self, x:torch.Tensor):
67
+ x = self.features(x)
68
+ return self.classifier(x)
69
+ def embeddings(self, x:torch.Tensor):
70
+ return self.features(x).flatten().detach().numpy()
71
+ __call__ = embeddings
72
+
73
+ MODEL_19 = VGG19()
74
+ MODEL_19.load_state_dict(torch.load("models/vgg19-dcbb9e9d.pth"), strict=True)
75
+ if __name__ == "__main__":
76
+ print(MODEL_19.state_dict().keys())
vgg/vgg_face.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from torch import nn
3
+ from warnings import filterwarnings
4
+ from torchvision.transforms import ToTensor, Resize, Normalize, Compose
5
+
6
+ filterwarnings("ignore")
7
+
8
+ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
9
+ KERNEL_SIZE = (3,3)
10
+
11
+ class VGGFACE(nn.Module):
12
+ def __init__(self, *args, **kwargs) -> None:
13
+ super().__init__(*args, **kwargs)
14
+ self.conv1_1 = nn.Conv2d(3, 64, KERNEL_SIZE, 1, 1)
15
+ self.conv1_2 = nn.Conv2d(64, 64, KERNEL_SIZE, 1, 1)
16
+
17
+ self.conv2_1 = nn.Conv2d(64, 128, KERNEL_SIZE, 1, 1)
18
+ self.conv2_2 = nn.Conv2d(128, 128, KERNEL_SIZE, 1, 1)
19
+
20
+ self.conv3_1 = nn.Conv2d(128, 256, KERNEL_SIZE, 1, 1)
21
+ self.conv3_2 = nn.Conv2d(256, 256, KERNEL_SIZE, 1, 1)
22
+ self.conv3_3 = nn.Conv2d(256, 256, KERNEL_SIZE, 1, 1)
23
+
24
+ self.conv4_1 = nn.Conv2d(256, 512, KERNEL_SIZE, 1, 1)
25
+ self.conv4_2 = nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1)
26
+ self.conv4_3 = nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1)
27
+
28
+ self.conv5_1 = nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1)
29
+ self.conv5_2 = nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1)
30
+ self.conv5_3 = nn.Conv2d(512, 512, KERNEL_SIZE, 1, 1)
31
+
32
+ self.fc6 = nn.Linear(49*512, 4096)
33
+ self.fc7 = nn.Linear(4096, 4096)
34
+ self.fc8 = nn.Linear(4096, 2622)
35
+ self.relu = nn.ReLU()
36
+ self.maxpool = nn.MaxPool2d(2)
37
+
38
+ self._features = [
39
+ self.conv1_1, self.relu,
40
+ self.conv1_2, self.relu,
41
+ self.maxpool,
42
+ self.conv2_1, self.relu,
43
+ self.conv2_2, self.relu,
44
+ self.maxpool,
45
+ self.conv3_1, self.relu,
46
+ self.conv3_2, self.relu,
47
+ self.conv3_3, self.relu,
48
+ self.maxpool,
49
+ self.conv4_1, self.relu,
50
+ self.conv4_2, self.relu,
51
+ self.conv4_3, self.relu,
52
+ self.maxpool,
53
+ self.conv5_1, self.relu,
54
+ self.conv5_2, self.relu,
55
+ self.conv5_3, self.relu,
56
+ self.maxpool,
57
+ nn.Flatten(start_dim=0)
58
+ ]
59
+
60
+ self._classifier = [
61
+ self.fc6, self.relu,
62
+ self.fc7, self.relu,
63
+ self.fc8
64
+ ]
65
+
66
+ self._embedder = [
67
+ self.conv1_1, self.relu,
68
+ self.conv1_2, self.relu,
69
+ self.maxpool,
70
+ self.conv2_1, self.relu,
71
+ self.conv2_2, self.relu,
72
+ self.maxpool,
73
+ self.conv3_1, self.relu,
74
+ self.conv3_2, self.relu,
75
+ self.conv3_3, self.relu,
76
+ self.maxpool,
77
+ self.conv4_1, self.relu,
78
+ self.conv4_2, self.relu,
79
+ self.conv4_3, self.relu,
80
+ self.maxpool,
81
+ self.conv5_1, self.relu,
82
+ self.conv5_2, self.relu,
83
+ self.conv5_3, self.relu,
84
+ self.maxpool,
85
+ nn.Flatten(start_dim=0),
86
+ self.fc6,
87
+ ]
88
+ self.transform = Compose([ToTensor() ,Resize((224, 224)), Normalize(mean=(93.59396362304688/255, 104.76238250732422/255, 129.186279296875/255), std=(1, 1, 1))])
89
+ def features(self, x):
90
+ x = self.transform(x)
91
+ x = x.to(DEVICE)
92
+ for layer in self._features:
93
+ x = layer(x)
94
+ return x
95
+ def classifier(self, x):
96
+ for layer in self._classifier:
97
+ x = layer(x)
98
+ return x
99
+ def embedder(self, x):
100
+ x = self.transform(x)
101
+ x = x.to(DEVICE)
102
+ for layer in self._embedder:
103
+ x = layer(x)
104
+ return x
105
+ def forward(self, x:torch.Tensor):
106
+ x = self.features(x)
107
+ return self.classifier(x)
108
+ def embeddings(self, x:torch.Tensor):
109
+ return self.embedder(x).cpu().flatten().detach().numpy()
110
+ __call__ = embeddings
111
+
112
+ MODEL_FACE = VGGFACE()
113
+ MODEL_FACE.load_state_dict(torch.load("models/vgg_face_dag.pth"), strict=True)
114
+ MODEL_FACE.to(DEVICE)
115
+
116
+ if __name__ == "__main__":
117
+ print(MODEL_FACE.state_dict().keys())
yolo/__pycache__/yoloFace.cpython-312.pyc ADDED
Binary file (2.18 kB). View file
 
yolo/yolo.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+
4
+ # need to change these offsets later
5
+ X1_OFFSET, X2_OFFSET = 0,0
6
+ Y1_OFFSET, Y2_OFFSET = 0,0
7
+
8
+ class YOLO:
9
+ def __init__(self):
10
+ self.net = cv2.dnn.readNet("models/yolov3-tiny.weights", "configs/yolov3-tiny.cfg")
11
+ self.layer_names = self.net.getLayerNames()
12
+ self.output_layers = [self.layer_names[i - 1] for i in self.net.getUnconnectedOutLayers()]
13
+ self.classes = []
14
+ with open("coco.names", "r") as f:
15
+ self.classes = [line.strip() for line in f.readlines()]
16
+ def get_patches(self, img):
17
+ patches = []
18
+ for (x1, y1), (x2, y2), color, confidence, label in self.forward(img):
19
+ if (x1 == x2 or y1 == y2):
20
+ continue
21
+ print((x1, y1), (x2, y2))
22
+ patches.append(img[y1:y2, x1:x2])
23
+ return patches
24
+ def forward(self, img):
25
+ height, width, channels = img.shape
26
+
27
+ # Prepare the image for YOLO
28
+ blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
29
+ self.net.setInput(blob)
30
+
31
+ # Run the forward pass
32
+ outs = self.net.forward(self.output_layers)
33
+
34
+ # Processing the output
35
+ class_ids = []
36
+ confidences = []
37
+ boxes = []
38
+ for out in outs:
39
+ for detection in out:
40
+ scores = detection[5:] # center x, center y, width, height, object confidence score, class confidence scores...
41
+ class_id = np.argmax(scores)
42
+ class_confidence = scores[class_id]
43
+ object_confidence = detection[4]
44
+ if object_confidence > 0.5:
45
+ # Get the coordinates for the bounding box
46
+ center_x = int(detection[0] * width)
47
+ center_y = int(detection[1] * height)
48
+ w = int(detection[2] * width)
49
+ h = int(detection[3] * height)
50
+
51
+ # Rectangle coordinates
52
+ x = int(center_x - w / 2)
53
+ y = int(center_y - h / 2)
54
+ if x < 0 or y < 0:
55
+ continue
56
+ boxes.append([x, y, w, h])
57
+ confidences.append(float(class_confidence))
58
+ class_ids.append(class_id)
59
+
60
+ # Apply non-max suppression to remove overlapping boxes
61
+ indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
62
+ for i in range(len(boxes)):
63
+ if i in indexes:
64
+ x, y, w, h = boxes[i]
65
+ label = str(self.classes[class_ids[i]])
66
+ confidence = confidences[i]
67
+ color = (0, 255, 0) # Green box
68
+ if label == "person":
69
+ yield (x + X1_OFFSET, y + Y1_OFFSET), (x + w + X2_OFFSET, y + h + Y2_OFFSET), color, confidence, label
70
+ __call__ = get_patches
71
+
72
+ def display(yolo_model:YOLO):
73
+ cam = cv2.VideoCapture(0)
74
+ while True:
75
+ ret, img = cam.read()
76
+ if not ret:
77
+ print("unable to record")
78
+ continue
79
+ for (x1, y1), (x2, y2), color, confidence, label in yolo_model.forward(img):
80
+ print(x1, y1, x2, y2)
81
+ cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
82
+ cv2.putText(img, f"{label} {confidence:.2f}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
83
+ cv2.imshow("Camera Feed", img)
84
+ if cv2.waitKey(1) & 0xFF == ord('q'):
85
+ break
86
+ # Show the image
87
+ cam.release()
88
+ cv2.destroyAllWindows()
89
+
90
+ if __name__ == "__main__":
91
+ yolo_model = YOLO()
92
+ display(yolo_model=yolo_model)
yolo/yoloFace.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ from ultralytics import YOLO
3
+
4
+ X1_OFFSET, Y1_OFFSET, X2_OFFSET, Y2_OFFSET = 0, 0, 0, 0 # need to tinker with later
5
+ COLOR = (0, 255, 0)
6
+
7
+ class YOLOFace:
8
+
9
+ def __init__(self):
10
+ self.net = YOLO("models/best.pt")
11
+ def get_patches(self, img):
12
+ patches = []
13
+ for (x1, y1), (x2, y2) in self.forward(img):
14
+ cv2.rectangle(img, (x1, y1), (x2, y2), COLOR, 2)
15
+ if (x1 == x2 or y1 == y2):
16
+ continue
17
+ patches.append(img[y1:y2, x1:x2])
18
+ return patches
19
+ def forward(self, img):
20
+ boxes = self.net.predict(img, verbose=False)[0].boxes.xyxy.cpu().detach().numpy()
21
+ for x1, y1, x2, y2 in boxes:
22
+ yield (int(x1.item()+X1_OFFSET), int(y1.item()+Y1_OFFSET)), (int(x2.item()+X2_OFFSET), int(y2.item()+Y2_OFFSET))
23
+ __call__ = get_patches
24
+
25
+ YOLO_FACE = YOLOFace()