CALL_FACE01GRAPHICS129についてソースコードと共に解説

今日はCALL_FACE01GRAPHICS129.pyについてお話します。

CALL_FACE01GRAPHICS129についてソースコードと共に解説

CALL_FACE01GRAPHICS129.py

CALL_FACE01GRAPHICS129.pyはFACE01 GRAPHICS ver.1.2.9をconfig_FACE01GRAPHICS129.iniに書かれた設定を元に起動させるプログラムです。

config_FACE01GRAPHICS129.iniは手動またはSETTING MANAGER for FACE01 GRAPHICS ver.1.2.9によって上書きされます。

ソースコード

config_FACE01GRAPHICS129.ini

[DEFAULT]
similar_percentage = 99.0
jitters = 0
priset_face_images_jitters = 100
upsampling = 0
mode = cnn
frame_skip = -1
movie = test.mp4
set_area = NONE
set_width = 550
rectangle = False
target_rectangle = True
show_video = False
crop_face_image = True
frequency_crop_image = 80
default_face_image_draw = False
show_overlay = True
show_percentage = False
show_name = False
print_property = False
calculate_time = False
multiple_faces = False
bottom_area = True

CALL_FACE01GRAPHICS129.py

import configparser
from concurrent.futures import ThreadPoolExecutor

import cv2
import PySimpleGUI as sg

import FACE01GRAPHICS129 as fg

# configファイル読み込み
conf=configparser.ConfigParser()
conf.read('config_FACE01GRAPHICS129.ini', 'utf-8')

kaoninshoDir, priset_face_imagesDir=fg.home()

known_face_encodings, known_face_names=fg.load_priset_image(
    kaoninshoDir,
    priset_face_imagesDir, 
    jitters=                        int(conf.get('DEFAULT','priset_face_images_jitters')) 
)

xs=fg.face_attestation(
    kaoninshoDir, 
    known_face_encodings, 
    known_face_names, 
    similar_percentage=             float(conf.get('DEFAULT','similar_percentage')), 
    jitters=                        int(conf.get('DEFAULT','jitters')), 
    upsampling=                     int(conf.get('DEFAULT','upsampling')),
    mode=                           conf.get('DEFAULT','mode'), 
    model=                          'small', 
    frame_skip=                     int(conf.get('DEFAULT','frame_skip')), 
    movie=                          conf.get('DEFAULT','movie'), 
    rectangle=                      conf.getboolean('DEFAULT','rectangle'), 
    target_rectangle=               conf.getboolean('DEFAULT','target_rectangle'), 
    show_video=                     conf.getboolean('DEFAULT','show_video'),
    frequency_crop_image=           int(conf.get('DEFAULT','frequency_crop_image')), 
    set_area=                       conf.get('DEFAULT','set_area'),
    print_property=                 conf.getboolean('DEFAULT','print_property'),
    calculate_time=                 conf.getboolean('DEFAULT','calculate_time'),
    SET_WIDTH=                      int(conf.get('DEFAULT','SET_WIDTH')),
    default_face_image_draw=        conf.getboolean('DEFAULT', 'default_face_image_draw'),
    show_overlay=                   conf.getboolean('DEFAULT', 'show_overlay'),
    show_percentage=                conf.getboolean('DEFAULT', 'show_percentage'),
    crop_face_image=                conf.getboolean('DEFAULT', 'crop_face_image'),
    show_name=                      conf.getboolean('DEFAULT', 'show_name'),
    multiple_faces=                 conf.getboolean('DEFAULT', 'multiple_faces'),
    bottom_area=                    conf.getboolean('DEFAULT', 'bottom_area')
)

layout = [
    [sg.Image(filename='', key='display', pad=(0,0))],
    [sg.Button('終了', key='terminate', pad=(0,10))]
]

window = sg.Window(
    'CALL_FACE01GRAPHICS', layout, alpha_channel=1, margins=(0, 0), 
    no_titlebar=True, grab_anywhere=True,
    location=(350,130), modal=True
)

def multi(x):
    name, pict, date, img, location, percentage_and_symbol = x['name'], x['pict'], x['date'], x['img'], x['location'], x['percentage_and_symbol']
    if not name==None:
        print(
            name, "\n",
            "\t", "類似度\t", percentage_and_symbol, "\n", 
            "\t", "座標\t", location, "\n",
            "\t", "時刻\t", date, "\n",
            "\t", "出力\t", pict, "\n",
            "------------\n"
        )
    return img

pool = ThreadPoolExecutor()

for array_x in xs:
    for x in array_x:
        if x=={}:
            continue

        result = pool.submit(multi, x)
        event, _ = window.read(timeout=1)
        
        if  not result.result() is None:
            imgbytes=cv2.imencode(".png", result.result())[1].tobytes()
            window["display"].update(data=imgbytes)
    
        if event=='terminate':
            break
    else:
        continue
    break

window.close()
print('終了します')

出力結果

test.mp4 :バッファリング中…
安倍晋三 
         類似度  99.8% 
         座標    (107, 320, 201, 225) 
         時刻    2021,10,04,07,25,24,306832 
         出力    output/安倍晋三_99.8%_2021,10,04,07,25,24,306832_0.15.png 
 ------------

安倍晋三 
         類似度  99.8% 
         座標    (107, 320, 201, 225) 
         時刻    2021,10,04,07,25,24,306832 
         出力    output/安倍晋三_99.8%_2021,10,04,07,25,24,306832_0.15.png 
 ------------

安倍晋三 
         類似度  99.8% 
         座標    (107, 320, 201, 225) 
         時刻    2021,10,04,07,25,24,777512 
         出力    output/安倍晋三_99.8%_2021,10,04,07,25,24,777512_0.15.png 
 ------------

安倍晋三 
         類似度  99.8% 
         座標    (107, 320, 201, 225) 
         時刻    2021,10,04,07,25,24,777512 
         出力    output/安倍晋三_99.8%_2021,10,04,07,25,24,777512_0.15.png 
 ------------

安倍晋三 
         類似度  99.8% 
         座標    (116, 320, 211, 225) 
         時刻    2021,10,04,07,25,24,874477 
         出力    output/安倍晋三_99.8%_2021,10,04,07,25,24,874477_0.16.png 
 ------------

解説

CALL_FACE01GRAPHICS129ではPySimpleGUIを用いています。PySimpleGUIについてはこちらのページで解説を行っておりますのでぜひご覧ください。

レイアウトは以下の様になっています。

layout = [
    [sg.Image(filename='', key='display', pad=(0,0))],
    [sg.Button('終了', key='terminate', pad=(0,10))]
]

レイアウトは2ブロックしかありません。すなわち映像表示部と終了ボタン部です。

def multi(x):
    name, pict, date, img, location, percentage_and_symbol = x['name'], x['pict'], x['date'], x['img'], x['location'], x['percentage_and_symbol']
    if not name==None:
        print(
            name, "\n",
            "\t", "類似度\t", percentage_and_symbol, "\n", 
            "\t", "座標\t", location, "\n",
            "\t", "時刻\t", date, "\n",
            "\t", "出力\t", pict, "\n",
            "------------\n"
        )
    return img

multi()関数はFACE01 GRAPHICSを呼出してname, pict, date, img, location, percentage_and_symbolを受取ります。このmulti()関数はfrom concurrent.futures import ThreadPoolExecutorによって並列に呼び出されます。

pool = ThreadPoolExecutor()

for array_x in xs:
    for x in array_x:
        result = pool.submit(multi, x)

multi()関数は標準出力に出力をした後imgを返します。このimgをresultとして受け取り、png画像に変換してPySimpleGUIを使って表示します。

imgbytes=cv2.imencode(".png", result.result())[1].tobytes()
window["display"].update(data=imgbytes)

まとめ

以上のようにCALL_FACE01GRAPHICS129.pyが行っている処理は非常に単純です。このプログラムはサンプルとして書かれています。FACE01 GRAPHICSの動作検証やアプリケーションの参考としてお使いください。

以上です。最後までお読み頂きありがとうございました。