change readmeW.md to readme.md
This commit is contained in:
parent
93c597dd94
commit
b1a4a892b4
|
|
@ -0,0 +1,54 @@
|
|||
ref: https://github.com/serengil/deepface
|
||||
|
||||
# model store
|
||||
model checkpoint 放在了 `C:\Users\User\.deepface\weights`
|
||||
|
||||
# installation
|
||||
```
|
||||
$ pip install deepface
|
||||
```
|
||||
|
||||
# Usage:
|
||||
```
|
||||
(deepface_v2) PS path/to/workspace> python
|
||||
Python 3.7.16 (default, Jan 17 2023, 16:06:28) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> from deepface import DeepFace
|
||||
```
|
||||
|
||||
# Model introduce
|
||||
```
|
||||
Deepface is a hybrid face recognition package. It currently wraps many state-of-the-art face recognition models:
|
||||
model_name Declared LFW Score
|
||||
VGG-Face 98.9%
|
||||
Facenet 99.2%
|
||||
Facenet512 99.6% drop
|
||||
OpenFace 92.9%
|
||||
DeepID 97.4%
|
||||
Dlib 99.3%
|
||||
SFace 99.5%
|
||||
ArcFace 99.5% 阈值调整为1.00 **
|
||||
GhostFaceNet 99.7% **
|
||||
Human-beings 97.5%
|
||||
|
||||
The default configuration uses VGG-Face model.
|
||||
```
|
||||
|
||||
```
|
||||
backends = {
|
||||
"opencv": OpenCv.OpenCvClient,
|
||||
"mtcnn": MtCnn.MtCnnClient,
|
||||
"ssd": Ssd.SsdClient,
|
||||
"dlib": Dlib.DlibClient,
|
||||
"retinaface": RetinaFace.RetinaFaceClient,
|
||||
"mediapipe": MediaPipe.MediaPipeClient,
|
||||
"yolov8": Yolo.YoloClient,
|
||||
"yunet": YuNet.YuNetClient,
|
||||
"fastmtcnn": FastMtCnn.FastMtCnnClient,
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
distance_metric = ['euclidean_l2','cosine','euclidean']
|
||||
author: Euclidean L2 form seems to be more stable than cosine and regular Euclidean distance based on experiments.
|
||||
```
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
ref: https://github.com/serengil/deepface
|
||||
|
||||
# store
|
||||
model checkpoint 放在了 `C:\Users\JIALE\.deepface\weights`
|
||||
|
||||
# installation
|
||||
|
||||
|
||||
# Usage:
|
||||
(deepface_v2) PS C:\Users\JIALE\Desktop\bns_proj\proj_deepface> python
|
||||
Python 3.7.16 (default, Jan 17 2023, 16:06:28) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> from deepface import DeepFace
|
||||
|
||||
|
|
@ -51,6 +51,7 @@ class Status(Enum):
|
|||
BASE64_EMPTY = "base64 is empty"
|
||||
NotImplementedError = "Not Implemented Error"
|
||||
ADD_HAS_EXISTED = "when adding, file has existed"
|
||||
DB_NO_FACE = "face_db has no face"
|
||||
|
||||
GLOBAL_DICT = {
|
||||
"ADD": Opt.ADD,
|
||||
|
|
@ -65,6 +66,7 @@ GLOBAL_DICT = {
|
|||
}
|
||||
|
||||
class FaceHelper:
|
||||
|
||||
def __init__(self, db_path: str, detector_backend: str, distance_metric: str, model_name: str):
|
||||
self.db_path = "C:/Users/JIALE/Desktop/bns_proj/proj_deepface/face"
|
||||
self.detector_backend = "opencv"
|
||||
|
|
@ -74,7 +76,11 @@ class FaceHelper:
|
|||
self.target_size = self.model.input_shape
|
||||
self.threshold = verification.find_threshold(model_name, distance_metric)
|
||||
self.pkl_name = f"ds_{self.model_name}_{self.detector_backend}_v2.pkl".replace("-", "").lower()
|
||||
|
||||
|
||||
self.dirty = True
|
||||
self.db_representations = None
|
||||
self.keepDBLive()
|
||||
|
||||
def get_facial_areas(self, img: np.ndarray):
|
||||
"""
|
||||
Find facial area coordinates in the given image
|
||||
|
|
@ -88,8 +94,6 @@ class FaceHelper:
|
|||
detected_face
|
||||
descriptions
|
||||
"""
|
||||
# print("get facial areas, img.shape: ", img.shape)
|
||||
# beg = time.time()
|
||||
try:
|
||||
face_objs = detection.extract_faces(
|
||||
img_path = img,
|
||||
|
|
@ -202,8 +206,7 @@ class FaceHelper:
|
|||
|
||||
if retjson['status'] == 0:
|
||||
return retjson
|
||||
|
||||
# db_imgs = os.listdir(self.db_path)
|
||||
|
||||
db_imgs = [db_img.split(".")[0] for db_img in os.listdir(self.db_path) if db_img.endswith(".jpg")]
|
||||
if opt_mode == Opt.ADD: # add
|
||||
if img_name in db_imgs:
|
||||
|
|
@ -215,35 +218,19 @@ class FaceHelper:
|
|||
return Status.NotImplementedError
|
||||
|
||||
# update the face_db to keep latest
|
||||
search_identity( # 保证database是最新的
|
||||
detected_face=np.zeros([224, 224, 3]),
|
||||
db_path=self.db_path,
|
||||
detector_backend=self.detector_backend,
|
||||
distance_metric=self.distance_metric,
|
||||
model_name=self.model_name,
|
||||
)
|
||||
|
||||
self.dirty = True
|
||||
self.keepDBLive()
|
||||
|
||||
return retjson
|
||||
|
||||
|
||||
#interface 2: face recognition using embeddings on face_db
|
||||
def faceRecog(self, img: Union[str,np.ndarray], img_mode: Ftype):
|
||||
# keep the database is the newest
|
||||
search_identity(
|
||||
detected_face=np.zeros([224, 224, 3]),
|
||||
db_path=self.db_path,
|
||||
detector_backend=self.detector_backend,
|
||||
distance_metric=self.distance_metric,
|
||||
model_name=self.model_name,
|
||||
)
|
||||
if self.dirty:
|
||||
self.keepDBLive()
|
||||
if len(self.db_representations) <= 0:
|
||||
return Status.DB_NO_FACE
|
||||
|
||||
# open and read face db
|
||||
datastore_path = os.path.join(self.db_path, self.pkl_name)
|
||||
with open(datastore_path, "rb") as f:
|
||||
db_representations = pickle.load(f)
|
||||
assert len(db_representations) > 0, 'no face in database'
|
||||
print(f"{len(db_representations)} faces representataion in {self.pkl_name}.")
|
||||
|
||||
# process the img
|
||||
ret = FaceHelper.process_img(img, img_mode)
|
||||
if isinstance(ret, Status):
|
||||
|
|
@ -251,7 +238,7 @@ class FaceHelper:
|
|||
target_img = ret
|
||||
|
||||
# begin face recognition
|
||||
df = pd.DataFrame(db_representations)
|
||||
df = pd.DataFrame(self.db_representations)
|
||||
labels = []
|
||||
|
||||
face_coors, detected_faces, descriptions = self.get_facial_areas(target_img)
|
||||
|
|
@ -292,8 +279,27 @@ class FaceHelper:
|
|||
success, encoded_target_img = cv2.imencode('.png', target_img)
|
||||
if success:
|
||||
target_img_base64 = base64.b64encode(encoded_target_img).decode("utf-8")
|
||||
|
||||
return labels, face_coors, target_img_base64
|
||||
|
||||
def keepDBLive(self):
|
||||
# keep the database is the newest
|
||||
search_identity(
|
||||
detected_face=np.zeros([224, 224, 3]),
|
||||
db_path=self.db_path,
|
||||
detector_backend=self.detector_backend,
|
||||
distance_metric=self.distance_metric,
|
||||
model_name=self.model_name,
|
||||
)
|
||||
self.dirty = False
|
||||
|
||||
# load the representations from face_db
|
||||
datestore_path = os.path.join(self.db_path, self.pkl_name)
|
||||
with open(datestore_path, "rb") as f:
|
||||
self.db_representations = pickle.load(f)
|
||||
|
||||
return len(self.db_representations)
|
||||
|
||||
|
||||
facehelper = FaceHelper(
|
||||
db_path = "C:/Users/JIALE/Desktop/bns_proj/proj_deepface/face",
|
||||
|
|
@ -305,22 +311,47 @@ facehelper = FaceHelper(
|
|||
app = FastAPI()
|
||||
|
||||
class item(BaseModel):
|
||||
type: str
|
||||
TYPE: str
|
||||
img: str
|
||||
img_name: str
|
||||
|
||||
class config(BaseModel):
|
||||
db_path: str # default: "C:/Users/JIALE/Desktop/bns_proj/proj_deepface/face"
|
||||
detector_backend: str #default:
|
||||
distance_metric: str
|
||||
model_name: str
|
||||
|
||||
# @app.post("/master/")
|
||||
# def master(input: item ):
|
||||
# return {"type": item["type"], "img":"fdasfsdf"}
|
||||
@app.post("/init/")
|
||||
def init(input: config):
|
||||
facehelper = FaceHelper(
|
||||
db_path = input.db_path,
|
||||
detector_backend = input.detector_backend,
|
||||
distance_metric = input.distance_metric,
|
||||
model_name = input.model_name,
|
||||
)
|
||||
|
||||
@app.get("/keepDBLastest")
|
||||
def keepDBLastest():
|
||||
ret = facehelper.keepDBLive()
|
||||
return {"status":"the faceDB is lastest", "description": f"db has {ret} faces"}
|
||||
|
||||
|
||||
@app.post("/interface/")
|
||||
def main(input: item):
|
||||
interface_type, img_mode, opt_mode = input.type.split("_")
|
||||
img_mode = GLOBAL_DICT[img_mode]
|
||||
if interface_type == "UPDATEDB":
|
||||
vars = input.TYPE.split("_")
|
||||
if len(vars) != 3:
|
||||
return {"status": 0, "description":"wrong TYPE"}
|
||||
interface_type, img_mode, opt_mode = vars
|
||||
try:
|
||||
img_mode = GLOBAL_DICT[img_mode]
|
||||
except KeyError:
|
||||
return {"status": 0, "description": "wrong img_mode"}
|
||||
try:
|
||||
opt_mode = GLOBAL_DICT[opt_mode]
|
||||
except KeyError:
|
||||
return {"status": 0, "description": "wrong opt_mode"}
|
||||
|
||||
if interface_type == "UPDATEDB":
|
||||
# call updateFaceDB for handling the picture
|
||||
ret = facehelper.updateFaceDB(img = input.img,
|
||||
img_name = input.img_name,
|
||||
|
|
|
|||
Loading…
Reference in New Issue