import sys import os import glob import numpy as np import streamlit as st from PIL import Image import zipfile from emotion_analyzer import EmotionAnalyzer st.title('ベストショット判定アプリ') ## スライダーの定義 st.sidebar.markdown('### 条件設定') sld_anger_deg = st.sidebar.slider('怒り', 1, 5, 1) sld_disgust_deg = st.sidebar.slider('嫌悪', 1, 5, 1) sld_fear_deg = st.sidebar.slider('恐怖', 1, 5, 1) sld_happiness_deg = st.sidebar.slider('喜しさ', 1, 5, 5) sld_sadness_deg = st.sidebar.slider('悲しみ', 1, 5, 1) sld_surprise_deg = st.sidebar.slider('驚き', 1, 5, 1) sld_neutral_deg = st.sidebar.slider('真顔', 1, 5, 1) # 各変数の比率を計算 sld_total_deg = (sld_anger_deg + sld_disgust_deg + sld_fear_deg + sld_happiness_deg + sld_sadness_deg + sld_surprise_deg + sld_neutral_deg) emotion_ratios = { 'anger': sld_anger_deg / sld_total_deg, 'disgust': sld_disgust_deg / sld_total_deg, 'fear': sld_fear_deg / sld_total_deg, 'happiness': sld_happiness_deg / sld_total_deg, 'sadness': sld_sadness_deg / sld_total_deg, 'surprise': sld_surprise_deg / sld_total_deg, 'neutral': sld_neutral_deg / sld_total_deg } image_extensions = ['*.jpg', '*.jpeg', '*.png', '*.gif', '*.bmp'] extract_dir = 'imgs' # アップローダー uploaded_file = st.file_uploader('ZIPファイルをアップロードしてください', type='zip') # イメージファイルのパスを格納するリスト img_file_path_list = [] if uploaded_file: # 一時ディレクトリを作成してZIPファイルを解凍 with zipfile.ZipFile(uploaded_file, 'r') as zip_ref: zip_ref.extractall(extract_dir) # 解凍したファイル・ディレクトリの一覧を取得 extracted_items = os.listdir(extract_dir) # zipファイルのベースファイルを取得 uploaded_file_base_name = uploaded_file.name.split('.zip')[0] # 解凍したディレクトリのパスを取得 extract_dir_path = os.path.join(extract_dir, uploaded_file_base_name) # 各拡張子に対してglobを使用してファイルを取得 for ext in image_extensions: img_file_path_list.extend(glob.glob(os.path.join(extract_dir_path, ext))) if img_file_path_list: st.write(f'{len(img_file_path_list)}枚のイメージファイルが見つかりました') else: st.write('イメージファイルが見つかりませんでした') st.write('再度アップロードしなおしてください') sys.exit() if st.button('表情分析開始'): # 画像を指定して表情認識を実行 with (st.spinner('表情分析中...')): ema = EmotionAnalyzer(img_file_path_list) df_emotions = ema.create_emotion_dataflame() # 各表情の値と設定値との二乗和を取り、最も値が小さい(設定値に近い)写真をベストショットをする df_emotions['distance'] = \ np.sqrt(sum((df_emotions[emotion] - ratio) ** 2 for emotion, ratio in emotion_ratios.items())) best_image_record = df_emotions.loc[df_emotions['distance'].idxmin()] # ベストショットのファイル名 best_image_record_filename = best_image_record.name # 保存した画像を表示 result_detection = df_emotions.loc[best_image_record_filename]['detections'] fig_list = result_detection.plot_detections(faces='landmarks', faceboxes=True, muscles=False, poses=False, gazes=False, add_titles=True, au_barplot=False, emotion_barplot=True, plot_original_image=True) st.markdown('ベストショットはこちら!') # 保存した画像を表示 img = Image.open(best_image_record_filename) st.image(img, width=500) # 分析結果を表示 st.markdown('分析結果') st.pyplot(fig_list[0])