Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FaceDetectorYNとaceRecognizerSFによる顔認証の実装 #25

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ git clone https://github.com/nitic-pbl-p4/sensor-server.git
cd sensor-server
```

そして、顔認証用ライブラリ`face_recognition`のために、`dlib`をインストールしましょう。
詳しく (MacOS or Ubuntu): https://gist.github.com/ageitgey/629d75c1baac34dfa5ca2a1928a7aeaf
詳しく (他の環境): https://github.com/ageitgey/face_recognition#installation

最後に、`poetry`でこのプロジェクト用の Python の仮想環境を作成して、その後必要な依存関係をインストールします。

Expand Down Expand Up @@ -53,31 +50,64 @@ poetry config virtualenvs.path # /Users/ReoHakase/Library/Caches/pypoetry/virtua
}
```

## 訓練用の顔画像の置き方
## 訓練の方法

プロジェクトルート以下に、`assets/<個人のId>/<任意の名前>.(png|jpg|jpeg)`の形式で配置して下さい。
sensor-server/face/images以下に、`<任意の名前>.(png|jpg|jpeg)`の形式で配置して下さい。

```bash
.
├── assets
│ ├── aung
│ │ └── IMG_6B07A8732E02-1.jpeg
│ ├── maririhakuta
│ │ └── IMG_1314.jpg
│ ├── reohakuta
│ │ └── IMG_1311.jpg
│ └── yutoinoue
│ └── IMG_1317.jpg
├── sensor-server
│ └── face
│ ├── images
│ │ ├── aung.jpeg
│ │ ├── maririhakuta.jpg
│ │ ├── reohakuta.jpg
│ │ └── yutoinoue.jpg
│ ├── feature
│ ├── images_aligned
│ ├── __init__.py
│ └── main.py
├── poetry.lock
├── pyproject.toml
├── README.md
├── sensor-server
│ ├── __init__.py
│ └── main.py
└── tests
└── __init__.py
```

画像を配置したら、以下のコマンドでfaceディレクトリに移動する。
```bash
cd sensor-server/face
```
#### 手順1:顔画像の切り取り
以下のコマンドで、sensor-server/faceは以下のimagesディレクトリに保存されている画像から顔部分のみを切り取って、images_alignedに同じ名前で保存する。
```bash
python gen_aligned.py <任意の名前>.(png|jpg|jpeg)
```
また、上記のコマンドで画像名のみを引数として与えるものとする。

例)

```bash
python gen_aligned.py aung.jpeg
```

#### 手順2:切り取った顔画像から特徴を抽出する
以下のコマンドで、sensor-server/faceは以下のimages_alignedディレクトリに保存されている画像からから特徴量を抽出し、第2引数にはユーザのIDを指定する。

```bash
python gen_feature.py <任意の名前>.(png|jpg|jpeg) ID
```

上記のようにすることで、sensor-server/face/feature配下に特徴量を保存したファイルが生成されまた、sensor-server/face/data配下のid.jsonにユーザー名とIDが紐づけられて保存される。

例)

```bash
python gen_feature.py aung.jpeg IMG_6B07A8732E02-1
```


## HTTP GET /

```json
Expand Down
398 changes: 139 additions & 259 deletions poetry.lock

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ packages = [{include = "sensor-server"}]

[tool.poetry.dependencies]
python = "^3.11"
face-recognition = "1.3.0"
opencv-python = "4.7.0.72"
opencv-python = "4.8.0.76"
rich = "^13.4.1"
pydantic = "^1.10.9"
pendulum = "^2.1.2"
Expand Down
222 changes: 0 additions & 222 deletions sensor-server/face.py

This file was deleted.

3 changes: 3 additions & 0 deletions sensor-server/face/data/id.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{

}
Binary file not shown.
Binary file not shown.
52 changes: 52 additions & 0 deletions sensor-server/face/gen_aligned.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import os
import argparse
import numpy as np
import cv2

def main():
# 引数をパースする
parser = argparse.ArgumentParser("generate aligned face images from an image")
parser.add_argument("image", help="input image file path (./image.jpg)")
args = parser.parse_args()

# 引数から画像ファイルのパスを取得
path = "images/{}".format(args.image)

# 画像を開く
image = cv2.imread(path)
if image is None:
exit()

gamma22LUT = np.array([pow(x/255.0 , 2.2) for x in range(256)],
dtype='float32')
image = cv2.LUT(image, gamma22LUT)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = pow(image, 1.0/2.2) * 255

# 画像が3チャンネル以外の場合は3チャンネルに変換する
channels = 1 if len(image.shape) == 2 else image.shape[2]
if channels == 1:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
if channels == 4:
image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)

# モデルを読み込む
face_detector = cv2.FaceDetectorYN_create("face_detection_yunet_2023mar.onnx", "", (0, 0))
face_recognizer = cv2.FaceRecognizerSF_create("face_recognition_sface_2021dec.onnx", "")

# 入力サイズを指定する
height, width, _ = image.shape
face_detector.setInputSize((width, height))

# 顔を検出する
_, faces = face_detector.detect(image)
# 検出された顔を切り抜く
if type(faces) != type(None):
aligned_face = face_recognizer.alignCrop(image, faces[0])
else:
aligned_face = image
# 画像を表示、保存する
cv2.imwrite("images_aligned/{}".format(args.image),aligned_face)

if __name__ == '__main__':
main()
Loading