Thiago Hersan commited on
Commit
4e75693
1 Parent(s): 37faafa

initial commit

Browse files
.gitattributes CHANGED
@@ -1,35 +1,2 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip 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
 
1
+ models/haarcascade_frontalface_alt2.xml filter=lfs diff=lfs merge=lfs -text
2
+ models/lbfmodel.yaml filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .DS_S*
2
+ __pycache__/
3
+ gradio_cached_examples/
4
+ .ipynb_checkpoints/
README.md CHANGED
@@ -1,12 +1,10 @@
1
  ---
2
- title: 9103H 2024F Face Align
3
- emoji: 🦀
4
- colorFrom: red
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 4.44.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: 9103H 2024F face-align-gradio
3
+ emoji: 🤨📐
4
+ colorFrom: blue
5
+ colorTo: gray
6
  sdk: gradio
7
+ sdk_version: 4.42.0
8
  app_file: app.py
9
  pinned: false
10
  ---
 
 
align.ipynb ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "2c2df050-8d87-467a-bac4-db82196f9476",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import cv2\n",
11
+ "import numpy as np\n",
12
+ "import matplotlib.pyplot as plt\n",
13
+ "\n",
14
+ "from math import atan2\n",
15
+ "from os import listdir, path\n",
16
+ "from PIL import Image as PImage"
17
+ ]
18
+ },
19
+ {
20
+ "cell_type": "code",
21
+ "execution_count": null,
22
+ "id": "66f93746-7ea0-4856-ac86-24472166cf8c",
23
+ "metadata": {},
24
+ "outputs": [],
25
+ "source": [
26
+ "img_filename = \"MT.png\"\n",
27
+ "\n",
28
+ "pimg = PImage.open(f\"./{img_filename}\").convert(\"L\")\n",
29
+ "pimg.thumbnail((1000,1000))\n",
30
+ "imgg = np.array(pimg).copy()\n",
31
+ "\n",
32
+ "iw,ih = pimg.size"
33
+ ]
34
+ },
35
+ {
36
+ "cell_type": "code",
37
+ "execution_count": null,
38
+ "id": "86c17ae6-391b-474f-a157-71af179f29a0",
39
+ "metadata": {},
40
+ "outputs": [],
41
+ "source": [
42
+ "# https://medium.com/analytics-vidhya/facial-landmarks-and-face-detection-in-python-with-opencv-73979391f30e\n",
43
+ "# https://www.researchgate.net/figure/The-68-specific-human-face-landmarks_fig4_331769278\n",
44
+ "\n",
45
+ "haarcascade = \"./models/haarcascade_frontalface_alt2.xml\"\n",
46
+ "face_detector = cv2.CascadeClassifier(haarcascade)\n",
47
+ "\n",
48
+ "LBFmodel = \"./models/lbfmodel.yaml\"\n",
49
+ "landmark_detector = cv2.face.createFacemarkLBF()\n",
50
+ "landmark_detector.loadModel(LBFmodel)\n",
51
+ "\n",
52
+ "faces = face_detector.detectMultiScale(imgg)\n",
53
+ "\n",
54
+ "biggest_faces = faces[np.argsort(-faces[:,2])]\n",
55
+ "\n",
56
+ "_, landmarks = landmark_detector.fit(imgg, biggest_faces)"
57
+ ]
58
+ },
59
+ {
60
+ "cell_type": "code",
61
+ "execution_count": null,
62
+ "id": "7724f3dd-ee63-48a3-8761-a0ae065c480f",
63
+ "metadata": {},
64
+ "outputs": [],
65
+ "source": [
66
+ "OUT_W = 130\n",
67
+ "OUT_H = 170\n",
68
+ "OUT_EYE_SPACE = 60\n",
69
+ "OUT_NOSE_TOP = 70\n",
70
+ "\n",
71
+ "EYE_0_IDX = 36\n",
72
+ "EYE_1_IDX = 45\n",
73
+ "CHIN_IDX = 8\n",
74
+ "\n",
75
+ "for landmark in landmarks:\n",
76
+ " eye0 = np.array(landmark[0][EYE_0_IDX])\n",
77
+ " eye1 = np.array(landmark[0][EYE_1_IDX])\n",
78
+ " chin = np.array(landmark[0][CHIN_IDX])\n",
79
+ " mid = np.mean([eye0, eye1], axis=0)\n",
80
+ "\n",
81
+ " eye_line = eye1 - eye0\n",
82
+ " tilt = atan2(eye_line[1], eye_line[0])\n",
83
+ " tilt_deg = 180 * tilt / np.pi\n",
84
+ " print(tilt_deg)\n",
85
+ "\n",
86
+ " chin_line = chin - mid\n",
87
+ " tilt2 = atan2(chin_line[1], chin_line[0])\n",
88
+ " tilt2_deg = (180 * tilt2 / np.pi) - 90\n",
89
+ " print(tilt2_deg)\n",
90
+ "\n",
91
+ " scale = OUT_EYE_SPACE / abs(eye0[0] - eye1[0])\n",
92
+ "\n",
93
+ " # scale\n",
94
+ " pimgs = pimg.resize((int(iw * scale), int(ih * scale)), resample=PImage.Resampling.LANCZOS)\n",
95
+ "\n",
96
+ " # rotate around nose\n",
97
+ " new_mid = [int(c * scale) for c in mid]\n",
98
+ " crop_box = (new_mid[0] - (OUT_W // 2),\n",
99
+ " new_mid[1] - OUT_NOSE_TOP,\n",
100
+ " new_mid[0] + (OUT_W // 2),\n",
101
+ " new_mid[1] + (OUT_H - OUT_NOSE_TOP))\n",
102
+ "\n",
103
+ " pimgsrc0 = pimgs.rotate(0, center=new_mid, resample=PImage.Resampling.BICUBIC).crop(crop_box)\n",
104
+ " display(pimgsrc0)\n",
105
+ " pimgsrc = pimgs.rotate(tilt_deg, center=new_mid, resample=PImage.Resampling.BICUBIC).crop(crop_box)\n",
106
+ " display(pimgsrc)\n",
107
+ " pimgsrc2 = pimgs.rotate(tilt_deg, center=new_mid, resample=PImage.Resampling.BICUBIC).crop(crop_box)\n",
108
+ " display(pimgsrc2)\n"
109
+ ]
110
+ }
111
+ ],
112
+ "metadata": {
113
+ "kernelspec": {
114
+ "display_name": "Python 3 (ipykernel)",
115
+ "language": "python",
116
+ "name": "python3"
117
+ },
118
+ "language_info": {
119
+ "codemirror_mode": {
120
+ "name": "ipython",
121
+ "version": 3
122
+ },
123
+ "file_extension": ".py",
124
+ "mimetype": "text/x-python",
125
+ "name": "python",
126
+ "nbconvert_exporter": "python",
127
+ "pygments_lexer": "ipython3",
128
+ "version": "3.10.9"
129
+ }
130
+ },
131
+ "nbformat": 4,
132
+ "nbformat_minor": 5
133
+ }
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import gradio as gr
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+
6
+ from math import atan2
7
+ from os import listdir, path
8
+ from PIL import Image as PImage
9
+
10
+ OUT_W = 130
11
+ OUT_H = 170
12
+ OUT_EYE_SPACE = 64
13
+ OUT_NOSE_TOP = 72
14
+
15
+ EYE_0_IDX = 36
16
+ EYE_1_IDX = 45
17
+
18
+ haarcascade = "./models/haarcascade_frontalface_alt2.xml"
19
+ face_detector = cv2.CascadeClassifier(haarcascade)
20
+
21
+ LBFmodel = "./models/lbfmodel.yaml"
22
+ landmark_detector = cv2.face.createFacemarkLBF()
23
+ landmark_detector.loadModel(LBFmodel)
24
+
25
+ NUM_OUTS = 16
26
+ all_outputs = [gr.Image(format="jpeg") for _ in range(NUM_OUTS)]
27
+
28
+ def face(img_in):
29
+ out_pad = NUM_OUTS * [gr.Image(visible=False)]
30
+ if img_in is None:
31
+ return out_pad
32
+
33
+ pimg = img_in.convert("L")
34
+ pimg.thumbnail((1000,1000))
35
+ imgg = np.array(pimg).copy()
36
+
37
+ iw,ih = pimg.size
38
+
39
+ faces = face_detector.detectMultiScale(imgg)
40
+
41
+ if len(faces) < 1:
42
+ return out_pad
43
+
44
+ biggest_faces = faces[np.argsort(-faces[:,2])]
45
+ _, landmarks = landmark_detector.fit(imgg, biggest_faces)
46
+
47
+ if len(landmarks) < 1:
48
+ return out_pad
49
+
50
+ out_images = []
51
+ for landmark in landmarks:
52
+ eye0 = np.array(landmark[0][EYE_0_IDX])
53
+ eye1 = np.array(landmark[0][EYE_1_IDX])
54
+ mid = np.mean([eye0, eye1], axis=0)
55
+
56
+ eye_line = eye1 - eye0
57
+ tilt = atan2(eye_line[1], eye_line[0])
58
+ tilt_deg = 180 * tilt / np.pi
59
+
60
+ scale = OUT_EYE_SPACE / abs(eye0[0] - eye1[0])
61
+ pimgs = pimg.resize((int(iw * scale), int(ih * scale)), resample=PImage.Resampling.LANCZOS)
62
+
63
+ # rotate around nose
64
+ new_mid = [int(c * scale) for c in mid]
65
+ crop_box = (new_mid[0] - (OUT_W // 2),
66
+ new_mid[1] - OUT_NOSE_TOP,
67
+ new_mid[0] + (OUT_W // 2),
68
+ new_mid[1] + (OUT_H - OUT_NOSE_TOP))
69
+
70
+ img_out = pimgs.rotate(tilt_deg, center=new_mid, resample=PImage.Resampling.BICUBIC).crop(crop_box)
71
+ out_images.append(gr.Image(img_out, visible=True))
72
+
73
+ out_images += out_pad
74
+ return out_images[:NUM_OUTS]
75
+
76
+
77
+ with gr.Blocks() as demo:
78
+ gr.Markdown("""
79
+ # 9103H 2024F Face Alignment Tool.
80
+ ## Interface for face detection, alignment, cropping\
81
+ to help create dataset for [HWXX](https://github.com/DM-GY-9103-2024F-H/).
82
+ """)
83
+
84
+ gr.Interface(
85
+ face,
86
+ inputs=gr.Image(type="pil"),
87
+ outputs=all_outputs,
88
+ cache_examples=True,
89
+ examples=[["./imgs/03.webp"], ["./imgs/11.jpg"]]
90
+ )
91
+
92
+ if __name__ == "__main__":
93
+ demo.launch()
imgs/03.webp ADDED
imgs/11.jpg ADDED
models/haarcascade_frontalface_alt2.xml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7b0c967d9abbdfbde025eb9c786947d151b6426040d07a8f9562ed8fd90724b4
3
+ size 540616
models/lbfmodel.yaml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:70dd8b1657c42d1595d6bd13d97d932877b3bed54a95d3c4733a0f740d1fd66b
3
+ size 56375857
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ opencv-contrib-python
2
+ opencv-python