sam749 commited on
Commit
b03e0d7
·
verified ·
1 Parent(s): ba69432

Upload folder using huggingface_hub

Browse files
app.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import cv2 as cv
4
+ import numpy as np
5
+ import gradio as gr
6
+ from yunet import YuNet
7
+
8
+
9
+ # Valid combinations of backends and targets
10
+ backend_target_pairs = [
11
+ [cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_CPU],
12
+ [cv.dnn.DNN_BACKEND_CUDA, cv.dnn.DNN_TARGET_CUDA],
13
+ [cv.dnn.DNN_BACKEND_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16],
14
+ [cv.dnn.DNN_BACKEND_TIMVX, cv.dnn.DNN_TARGET_NPU],
15
+ [cv.dnn.DNN_BACKEND_CANN, cv.dnn.DNN_TARGET_NPU],
16
+ ]
17
+
18
+
19
+ class ImageResizer:
20
+ def __init__(
21
+ self,
22
+ modelPath,
23
+ input_size=(320, 320),
24
+ conf_threshold=0.6,
25
+ nms_threshold=0.3,
26
+ top_k=5000,
27
+ backend_id=0,
28
+ target_id=0,
29
+ ):
30
+ self.model = YuNet(
31
+ modelPath=modelPath,
32
+ inputSize=input_size,
33
+ confThreshold=conf_threshold,
34
+ nmsThreshold=nms_threshold,
35
+ topK=top_k,
36
+ backendId=backend_id,
37
+ targetId=target_id,
38
+ )
39
+
40
+ def detect(self, image, num_faces=None):
41
+ # If input is an image
42
+ if image is not None:
43
+ h, w, _ = image.shape
44
+
45
+ # Inference
46
+ self.model.setInputSize([w, h])
47
+ results = self.model.infer(image)
48
+
49
+ faces = results[:num_faces] if num_faces else results
50
+
51
+ bboxs = []
52
+
53
+ for face in faces:
54
+ bbox = face[0:4].astype(np.int32) # x,y,w,h
55
+ x, y, w, h = bbox
56
+ # draw
57
+ cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
58
+ bboxs.append(bbox)
59
+
60
+ return image, bboxs
61
+
62
+ def resize(self, image, target_size=512, above_head_ratio=0.5):
63
+ height, width, _c = image.shape
64
+ ar = width / height
65
+ # downscale the image
66
+ if not target_size:
67
+ target_size = 512
68
+ if ar > 1:
69
+ # Landscape
70
+ new_height = target_size
71
+ new_width = int(target_size * ar)
72
+ elif ar < 1:
73
+ # Portrait
74
+ new_width = target_size
75
+ new_height = int(target_size / ar)
76
+ else:
77
+ # Square
78
+ new_width = target_size
79
+ new_height = target_size
80
+
81
+ resized = cv2.resize(
82
+ image, (new_width, new_height), interpolation=cv2.INTER_LINEAR
83
+ )
84
+
85
+ # Perform object detection on the resized image
86
+ dt_image, bboxes = self.detect(resized.copy())
87
+
88
+ # crop around face
89
+ if len(bboxes) >= 1:
90
+ x, y, w, h = bboxes[0]
91
+ else:
92
+ x, y, w, h = 0, 0, target_size, target_size
93
+ # 20% of image height
94
+ above_head_max = int(target_size * above_head_ratio)
95
+ x_center = int((x + (x + w)) / 2)
96
+ y_center = int((y + (y + h)) / 2)
97
+ # Calculate cropping box
98
+ left = int(max(0, x_center - target_size // 2))
99
+ top = int(max(0, y_center - above_head_max))
100
+ right = min(left + target_size, resized.shape[1])
101
+ bottom = min(top + target_size, resized.shape[0])
102
+
103
+ cropped_image = resized[top:bottom, left:right]
104
+ return dt_image, cropped_image
105
+
106
+
107
+ model_path = "face_detection_yunet_2023mar.onnx"
108
+ image_resizer = ImageResizer(modelPath=model_path)
109
+
110
+
111
+ def face_detector(input_image, target_size=512):
112
+ return image_resizer.resize(input_image, target_size)
113
+
114
+
115
+ inputs = [
116
+ gr.Image(sources=["upload", "clipboard"], type="numpy"),
117
+ gr.Dropdown(
118
+ choices=[512, 768, 1024],
119
+ value=512,
120
+ allow_custom_value=True,
121
+ info="Target size of images",
122
+ ),
123
+ ]
124
+ outputs = [
125
+ gr.Image(label="face detection", format="JPEG"),
126
+ gr.Image(label="focused resized", format="JPEG"),
127
+ ]
128
+ demo = gr.Interface(
129
+ fn=face_detector,
130
+ inputs=inputs,
131
+ outputs=outputs,
132
+ title="Image Resizer",
133
+ theme="gradio/monochrome",
134
+ api_name="resize",
135
+ submit_btn=gr.Button("Resize", variant="primary"),
136
+ allow_flagging="never",
137
+ )
138
+ demo.queue(
139
+ max_size=10,
140
+ )
141
+
142
+ if __name__ == "__main__":
143
+ demo.launch()
face_detection_yunet_2023mar.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8f2383e4dd3cfbb4553ea8718107fc0423210dc964f9f4280604804ed2552fa4
3
+ size 232589
face_detection_yunet_2023mar_int8.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:321aa5a6afabf7ecc46a3d06bfab2b579dc96eb5c3be7edd365fa04502ad9294
3
+ size 100416
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ opencv-python >= 4.9.0
2
+ gradio
3
+ numpy
yunet.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is part of OpenCV Zoo project.
2
+ # It is subject to the license terms in the LICENSE file found in the same directory.
3
+ #
4
+ # Copyright (C) 2021, Shenzhen Institute of Artificial Intelligence and Robotics for Society, all rights reserved.
5
+ # Third party copyrights are property of their respective owners.
6
+
7
+ from itertools import product
8
+
9
+ import numpy as np
10
+ import cv2 as cv
11
+
12
+ class YuNet:
13
+ def __init__(self, modelPath, inputSize=[320, 320], confThreshold=0.6, nmsThreshold=0.3, topK=5000, backendId=0, targetId=0):
14
+ self._modelPath = modelPath
15
+ self._inputSize = tuple(inputSize) # [w, h]
16
+ self._confThreshold = confThreshold
17
+ self._nmsThreshold = nmsThreshold
18
+ self._topK = topK
19
+ self._backendId = backendId
20
+ self._targetId = targetId
21
+
22
+ self._model = cv.FaceDetectorYN.create(
23
+ model=self._modelPath,
24
+ config="",
25
+ input_size=self._inputSize,
26
+ score_threshold=self._confThreshold,
27
+ nms_threshold=self._nmsThreshold,
28
+ top_k=self._topK,
29
+ backend_id=self._backendId,
30
+ target_id=self._targetId)
31
+
32
+ @property
33
+ def name(self):
34
+ return self.__class__.__name__
35
+
36
+ def setBackendAndTarget(self, backendId, targetId):
37
+ self._backendId = backendId
38
+ self._targetId = targetId
39
+ self._model = cv.FaceDetectorYN.create(
40
+ model=self._modelPath,
41
+ config="",
42
+ input_size=self._inputSize,
43
+ score_threshold=self._confThreshold,
44
+ nms_threshold=self._nmsThreshold,
45
+ top_k=self._topK,
46
+ backend_id=self._backendId,
47
+ target_id=self._targetId)
48
+
49
+ def setInputSize(self, input_size):
50
+ self._model.setInputSize(tuple(input_size))
51
+
52
+ def infer(self, image):
53
+ # Forward
54
+ faces = self._model.detect(image)
55
+ return np.array([]) if faces[1] is None else faces[1]