Python 라이브러리 Streamlit을 사용하여 얼굴 감지 앱 만들기 2

개요



여기 의 기사로 작성한 앱의 Azure의 Face API의 사용법이 현재는 바뀌고 있는 것 같기 때문에, 현재의 사용법에 맞추어 변경했습니다.
공식 문서

출처



소스 전문입니다.
Github 에 UP하고 있습니다.

main.py
import io
import streamlit as st
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.face.models import TrainingStatusType, Person

st.title('顔認証アプリ')

subscription_key = '' # AzureのAPIキー
endpoint = ''         # AzureのAPIエンドポイント

# クライアントを認証する
face_client = FaceClient(endpoint, CognitiveServicesCredentials(subscription_key))


# 検出した顔に描く長方形の座標を取得
def get_rectangle(faceDictionary):
    rect = faceDictionary.face_rectangle
    left = rect.left
    top = rect.top
    right = left + rect.width
    bottom = top + rect.height

    return ((left, top), (right, bottom))


# 描画するテキストを取得
def get_draw_text(faceDictionary):
    rect = faceDictionary.face_rectangle
    age = int(faceDictionary.face_attributes.age)
    gender = faceDictionary.face_attributes.gender
    text = f'{gender} {age}'

    # 枠に合わせてフォントサイズを調整
    font_size = max(16, int(rect.width / len(text)))
    font = ImageFont.truetype(r'C:\windows\fonts\meiryo.ttc', font_size)

    return (text, font)


# 認識された顔の上にテキストを描く座標を取得
def get_text_rectangle(faceDictionary, text, font):
    rect = faceDictionary.face_rectangle
    text_width, text_height = font.getsize(text)
    left = rect.left + rect.width / 2 - text_width / 2
    top = rect.top - text_height - 1

    return (left, top)


# テキストを描画
def draw_text(faceDictionary):
    text, font = get_draw_text(faceDictionary)
    text_rect = get_text_rectangle(faceDictionary, text, font)
    draw.text(text_rect, text, align='center', font=font, fill='red')


uploaded_file = st.file_uploader("Choose an image...", type="jpg")
if uploaded_file is not None:
    img = Image.open(uploaded_file)
    stream = io.BytesIO(uploaded_file.getvalue())

    detected_faces = face_client.face.detect_with_stream(
        stream, return_face_attributes=['age', 'gender'])
    if not detected_faces:
        raise Exception('画像から顔を検出できませんでした。')
    img = Image.open(uploaded_file)

    draw = ImageDraw.Draw(img)
    for face in detected_faces:
        draw.rectangle(get_rectangle(face), outline='green', width=3)
        draw_text(face)

    st.image(img, caption='Uploaded Image.', use_column_width=True)

전체의 기본 흐름은 이전과 동일합니다.
크게 바뀐 부분을 설명합니다.

클라이언트 인증



사용하기 전에 클라이언트를 인증합니다.
FaceClient의 인스턴스를 만듭니다.
face_client = FaceClient(endpoint, CognitiveServicesCredentials(subscription_key))

얼굴 검출 결과 취득



detect_with_stream을 사용하여 결과를 가져옵니다.
전달하는 데이터가 바이트가 아니라 이미지 스트림으로 바뀌고 있기 때문에 io.BytesIO를 사용하여 만든 데이터를 인수에 전달합니다.
stream = io.BytesIO(uploaded_file.getvalue())
detected_faces = face_client.face.detect_with_stream(stream, return_face_attributes=['age', 'gender'])

실행 결과



전회와 같은 결과가 되었으므로, 맛있게 가고 있는 것 같습니다.

좋은 웹페이지 즐겨찾기