やったこと
顔認証で打刻できるシステムのプロトタイプのを作りました。
システム概要
画像キャプチャ
- MediaDevices APIのgetUserMediaでカメラの情報をvideo.srcObjectにストリームとして流す。
const canvas = this.canvasDom.nativeElement;
const context = canvas.getContext('2d');
let video;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
});
video = this.videoDom.nativeElement;
video.srcObject = stream;
} else { /* エラー処理 */ }
context.drawImage(video, 0, 0, 640, 480);
クライアント側で顔検出
face-api.js: Tensorflow.jsをベースとした顔認識・検出などのAPIを提供するライブラリ
await faceapi.loadTinyFaceDetectorModel('assets/models');
const data = canvas.toDataURL();
let result = await faceapi.detectAllFaces(
canvas,
new faceapi.TinyFaceDetectorOptions(),
);
登録済みの顔と比較
AWSのRekognitionというサービスを利用
class FaceSearchService:
...
def search(self, image: str) -> Tuple[str, bool]:
response = self.client.search_faces_by_image(
CollectionId=self.collectionId,
FaceMatchThreshold=self.faceMatchThreshold,
Image={"Bytes": image},
MaxFaces=self.maxFaces)
if len(response["FaceMatches"]) == 1:
return (response["FaceMatches"][0]["Face"]["FaceId"], True)
return ("", False)
FaceIdに対応するユーザーを検索
def find_by_face_id(self, face_id: str) -> Optional[User]:
face = Face.query.filter_by(face_id=face_id).first()
if face is None:
return None
return User.query.filter_by(id=face.user_id).first()
打刻
def submit(self,
user: UserAuthInfo,
mode: AttendanceMode = AttendanceMode.START) -> bool:
# ログインして打刻に必要なクッキーを取得
session = requests.Session()
session.get(
self.endpoint,
auth=HttpNtlmAuth(user.email, user.password),
verify=False)
# 上のリクエストで得られたクッキーを使って打刻
payload = {"SubmitMode": mode}
r = session.post(self.endpoint, data=payload, verify=False)
if r.status_code == requests.codes.ok:
return True
return False
まとめ
- 顔認証で打刻ができたらいいなと思ってプロトタイプ作りました。
- もっとこうした方がいいとかあれば、GitHubでPRお待ちしています!