Update app.py
Browse files
app.py
CHANGED
|
@@ -2,7 +2,6 @@ import streamlit as st
|
|
| 2 |
import os
|
| 3 |
import zipfile
|
| 4 |
import csv
|
| 5 |
-
import base64 # 追加
|
| 6 |
from PIL import Image, ImageFilter
|
| 7 |
from gradio_client import Client
|
| 8 |
import datetime
|
|
@@ -12,20 +11,15 @@ client_nsfw = Client("https://ozoneasai-falconsai-nsfw-image-detection.hf.space/
|
|
| 12 |
client_other = Client("https://ozoneasai-sanali209-imclasif-quality-v001.hf.space/--replicas/m6xqz/")
|
| 13 |
|
| 14 |
# Initialize pagination
|
| 15 |
-
if
|
| 16 |
st.session_state.page = 1
|
| 17 |
|
| 18 |
-
# Initialize blur option
|
| 19 |
-
if
|
| 20 |
-
st.session_state.blur_option =
|
| 21 |
-
|
| 22 |
-
# Create a new checkbox
|
| 23 |
-
blur_option = st.checkbox("NSFW画像にBlurをかける", value=st.session_state.blur_option)
|
| 24 |
-
|
| 25 |
-
# ... (rest of the code remains unchanged)
|
| 26 |
|
| 27 |
# Initialize sort options
|
| 28 |
-
if
|
| 29 |
st.session_state.sort_option = {"column": "timestamp", "ascending": True}
|
| 30 |
|
| 31 |
# Define the function to generate a download link for a file
|
|
@@ -40,28 +34,21 @@ st.title("ファイルアップロードと共有")
|
|
| 40 |
|
| 41 |
uploaded_files = st.file_uploader("ファイルをアップロードしてください", type=["jpg", "png"], accept_multiple_files=True)
|
| 42 |
|
| 43 |
-
#
|
| 44 |
gradio_nsfw_predictions = []
|
| 45 |
gradio_other_predictions = []
|
| 46 |
-
|
| 47 |
-
# List to store good values
|
| 48 |
good_values = []
|
| 49 |
-
|
| 50 |
-
# List to store timestamps
|
| 51 |
timestamps = []
|
| 52 |
-
|
| 53 |
-
# List to store file paths
|
| 54 |
file_paths = []
|
| 55 |
|
| 56 |
def get_gradio_nsfw_prediction(image_path):
|
| 57 |
result = client_nsfw.predict(image_path, api_name="/predict")
|
| 58 |
-
return result
|
| 59 |
|
| 60 |
def get_gradio_other_prediction(image_path):
|
| 61 |
result = client_other.predict(image_path, api_name="/predict")
|
| 62 |
-
return result
|
| 63 |
|
| 64 |
-
# Function to save uploaded files and get Gradio predictions
|
| 65 |
def save_uploaded_files(uploaded_files):
|
| 66 |
if not os.path.exists("temp"):
|
| 67 |
os.makedirs("temp")
|
|
@@ -80,8 +67,8 @@ def save_uploaded_files(uploaded_files):
|
|
| 80 |
|
| 81 |
# Get good value
|
| 82 |
good_value = None
|
| 83 |
-
if "confidences" in gradio_other_prediction:
|
| 84 |
-
good_value = gradio_other_prediction["confidences"][0]["confidence"]
|
| 85 |
good_values.append(good_value)
|
| 86 |
|
| 87 |
# Get timestamp
|
|
@@ -90,20 +77,17 @@ def save_uploaded_files(uploaded_files):
|
|
| 90 |
|
| 91 |
file_paths.append(file_path)
|
| 92 |
|
| 93 |
-
# Function to apply blur to an image
|
| 94 |
def apply_blur(image_path):
|
| 95 |
img = Image.open(image_path)
|
| 96 |
img = img.filter(ImageFilter.GaussianBlur(radius=5))
|
| 97 |
return img
|
| 98 |
|
| 99 |
-
# Paginate files
|
| 100 |
def paginate_files(files, page, files_per_page):
|
| 101 |
start_index = (page - 1) * files_per_page
|
| 102 |
end_index = start_index + files_per_page
|
| 103 |
return files[start_index:end_index]
|
| 104 |
|
| 105 |
-
|
| 106 |
-
def display_images(images, blur_option):
|
| 107 |
for i, file_path in enumerate(images):
|
| 108 |
file_ext = os.path.splitext(file_path)[1].lower()
|
| 109 |
|
|
@@ -113,91 +97,89 @@ def display_images(images, blur_option):
|
|
| 113 |
good_value = good_values[i]
|
| 114 |
timestamp = timestamps[i]
|
| 115 |
|
| 116 |
-
st.write(f"**
|
| 117 |
-
st.write(f"**
|
| 118 |
-
st.write(f"**
|
| 119 |
-
st.write(f"**
|
| 120 |
-
st.write(f"**作成時間:** {timestamp}")
|
| 121 |
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
st.image(
|
| 125 |
else:
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
|
| 128 |
-
# Save uploaded files and get Gradio predictions
|
| 129 |
if uploaded_files:
|
| 130 |
save_uploaded_files(uploaded_files)
|
| 131 |
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
file_paths.sort(key=lambda x: os.path.getmtime(x), reverse=True)
|
| 135 |
-
files_per_page = 10
|
| 136 |
-
num_pages = (len(file_paths) - 1) // files_per_page + 1
|
| 137 |
-
page = st.session_state.get("page", 1)
|
| 138 |
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
if st.button("次へ", key="next_page"):
|
| 141 |
st.session_state.page = min(num_pages, st.session_state.page + 1)
|
| 142 |
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
|
| 147 |
-
|
| 148 |
-
selected_page = st.number_input("移動するページを指定してください", min_value=1, max_value=num_pages, value=st.session_state.page, key="selected_page")
|
| 149 |
-
if selected_page != st.session_state.page:
|
| 150 |
-
st.session_state.page = selected_page
|
| 151 |
-
|
| 152 |
-
st.write(f"現在のページ: {st.session_state.page}")
|
| 153 |
-
|
| 154 |
-
# Display images for the current page
|
| 155 |
-
current_page_files = paginate_files(file_paths, st.session_state.page, files_per_page)
|
| 156 |
-
|
| 157 |
-
# Sort files based on the selected option
|
| 158 |
-
sort_column = st.selectbox("並び替えオプション", ["timestamp", "good"])
|
| 159 |
-
ascending = st.checkbox("昇順", value=st.session_state.sort_option["ascending"])
|
| 160 |
-
st.session_state.sort_option = {"column": sort_column, "ascending": ascending}
|
| 161 |
-
|
| 162 |
-
# Sort files based on the selected option
|
| 163 |
-
if sort_column == "timestamp":
|
| 164 |
-
current_page_files.sort(key=lambda x: timestamps[file_paths.index(x)], reverse=not ascending)
|
| 165 |
-
elif sort_column == "good":
|
| 166 |
-
current_page_files.sort(key=lambda x: good_values[file_paths.index(x)], reverse=not ascending)
|
| 167 |
-
|
| 168 |
-
display_images(current_page_files, st.session_state.blur_option_checkbox)
|
| 169 |
-
|
| 170 |
-
# Save Gradio predictions, good values, and timestamps to CSV
|
| 171 |
-
if st.button("CSVに保存"):
|
| 172 |
-
csv_filename = "gradio_predictions_and_good_values.csv"
|
| 173 |
-
with open(csv_filename, mode='w', newline='', encoding='utf-8') as csv_file:
|
| 174 |
-
csv_writer = csv.writer(csv_file)
|
| 175 |
-
csv_writer.writerow(['ファイル名', 'NSFWの予測', 'Otherの予測', 'Goodの値', '作成時間'])
|
| 176 |
-
for i, file_path in enumerate(file_paths):
|
| 177 |
-
gradio_nsfw_prediction = gradio_nsfw_predictions[i]
|
| 178 |
-
gradio_other_prediction = gradio_other_predictions[i]
|
| 179 |
-
good_value = good_values[i]
|
| 180 |
-
timestamp = timestamps[i]
|
| 181 |
-
csv_writer.writerow([os.path.basename(file_path), gradio_nsfw_prediction, gradio_other_prediction, good_value, timestamp])
|
| 182 |
-
|
| 183 |
-
# CSVファイルをリンクとして提供
|
| 184 |
-
st.markdown(get_binary_file_downloader_html(csv_filename, label="CSVをダウンロード"), unsafe_allow_html=True)
|
| 185 |
-
|
| 186 |
-
# Gradio予測データを保存
|
| 187 |
-
with open("gradio_predictions.txt", "w") as f:
|
| 188 |
-
for prediction in gradio_nsfw_predictions:
|
| 189 |
-
f.write(f"{prediction[0]} (NSFW): {prediction[1]}\n")
|
| 190 |
-
for prediction in gradio_other_predictions:
|
| 191 |
-
f.write(f"{prediction[0]} (Other): {prediction[1]}\n")
|
| 192 |
-
|
| 193 |
-
# Zipファイル作成とダウンロード
|
| 194 |
-
if st.button("ファイルを一括ダウンロード"):
|
| 195 |
-
zip_filename = "files.zip"
|
| 196 |
-
with zipfile.ZipFile(zip_filename, "w") as zipf:
|
| 197 |
-
for file_path in file_paths:
|
| 198 |
-
zipf.write(file_path, os.path.basename(file_path))
|
| 199 |
-
|
| 200 |
-
# Zipファイルをリンクとして提供
|
| 201 |
-
st.markdown(get_binary_file_downloader_html(zip_filename, label="Zipファイルをダウンロード"), unsafe_allow_html=True)
|
| 202 |
|
| 203 |
st.success("ファイルがアップロードされました。このページのURLを他のクライアントと共有してください。")
|
|
|
|
| 2 |
import os
|
| 3 |
import zipfile
|
| 4 |
import csv
|
|
|
|
| 5 |
from PIL import Image, ImageFilter
|
| 6 |
from gradio_client import Client
|
| 7 |
import datetime
|
|
|
|
| 11 |
client_other = Client("https://ozoneasai-sanali209-imclasif-quality-v001.hf.space/--replicas/m6xqz/")
|
| 12 |
|
| 13 |
# Initialize pagination
|
| 14 |
+
if 'page' not in st.session_state:
|
| 15 |
st.session_state.page = 1
|
| 16 |
|
| 17 |
+
# Initialize blur option as a toggle
|
| 18 |
+
if 'blur_option' not in st.session_state:
|
| 19 |
+
st.session_state.blur_option = st.checkbox("NSFW画像にBlurをかける")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
# Initialize sort options
|
| 22 |
+
if 'sort_option' not in st.session_state:
|
| 23 |
st.session_state.sort_option = {"column": "timestamp", "ascending": True}
|
| 24 |
|
| 25 |
# Define the function to generate a download link for a file
|
|
|
|
| 34 |
|
| 35 |
uploaded_files = st.file_uploader("ファイルをアップロードしてください", type=["jpg", "png"], accept_multiple_files=True)
|
| 36 |
|
| 37 |
+
# Lists to store Gradio predictions, good values, timestamps, and file paths
|
| 38 |
gradio_nsfw_predictions = []
|
| 39 |
gradio_other_predictions = []
|
|
|
|
|
|
|
| 40 |
good_values = []
|
|
|
|
|
|
|
| 41 |
timestamps = []
|
|
|
|
|
|
|
| 42 |
file_paths = []
|
| 43 |
|
| 44 |
def get_gradio_nsfw_prediction(image_path):
|
| 45 |
result = client_nsfw.predict(image_path, api_name="/predict")
|
| 46 |
+
return result
|
| 47 |
|
| 48 |
def get_gradio_other_prediction(image_path):
|
| 49 |
result = client_other.predict(image_path, api_name="/predict")
|
| 50 |
+
return result
|
| 51 |
|
|
|
|
| 52 |
def save_uploaded_files(uploaded_files):
|
| 53 |
if not os.path.exists("temp"):
|
| 54 |
os.makedirs("temp")
|
|
|
|
| 67 |
|
| 68 |
# Get good value
|
| 69 |
good_value = None
|
| 70 |
+
if "good" in gradio_other_prediction and "confidences" in gradio_other_prediction["good"]:
|
| 71 |
+
good_value = gradio_other_prediction["good"]["confidences"][0]["confidence"]
|
| 72 |
good_values.append(good_value)
|
| 73 |
|
| 74 |
# Get timestamp
|
|
|
|
| 77 |
|
| 78 |
file_paths.append(file_path)
|
| 79 |
|
|
|
|
| 80 |
def apply_blur(image_path):
|
| 81 |
img = Image.open(image_path)
|
| 82 |
img = img.filter(ImageFilter.GaussianBlur(radius=5))
|
| 83 |
return img
|
| 84 |
|
|
|
|
| 85 |
def paginate_files(files, page, files_per_page):
|
| 86 |
start_index = (page - 1) * files_per_page
|
| 87 |
end_index = start_index + files_per_page
|
| 88 |
return files[start_index:end_index]
|
| 89 |
|
| 90 |
+
def display_images(images):
|
|
|
|
| 91 |
for i, file_path in enumerate(images):
|
| 92 |
file_ext = os.path.splitext(file_path)[1].lower()
|
| 93 |
|
|
|
|
| 97 |
good_value = good_values[i]
|
| 98 |
timestamp = timestamps[i]
|
| 99 |
|
| 100 |
+
st.write(f"**Prediction for {os.path.basename(file_path)} (NSFW):** {gradio_nsfw_prediction}")
|
| 101 |
+
st.write(f"**Prediction for {os.path.basename(file_path)} (Other):** {gradio_other_prediction}")
|
| 102 |
+
st.write(f"**Good value:** {good_value}")
|
| 103 |
+
st.write(f"**Timestamp:** {timestamp}")
|
|
|
|
| 104 |
|
| 105 |
+
if st.session_state.blur_option and gradio_nsfw_prediction.lower() == "nsfw":
|
| 106 |
+
blurred_img = apply_blur(file_path)
|
| 107 |
+
st.image(blurred_img, caption=os.path.basename(file_path), use_column_width=True)
|
| 108 |
else:
|
| 109 |
+
if file_ext in [".jpg", ".png"]:
|
| 110 |
+
st.image(file_path, caption=os.path.basename(file_path), use_column_width=True)
|
| 111 |
+
col1, col2 = st.columns([4, 1])
|
| 112 |
+
with col1:
|
| 113 |
+
if file_ext in [".jpg", ".png"]:
|
| 114 |
+
st.image(file_path, caption=os.path.basename(file_path), use_column_width=True)
|
| 115 |
+
with col2:
|
| 116 |
+
if col2.button("削除", key=file_path):
|
| 117 |
+
os.remove(file_path)
|
| 118 |
+
st.experimental_rerun()
|
| 119 |
|
|
|
|
| 120 |
if uploaded_files:
|
| 121 |
save_uploaded_files(uploaded_files)
|
| 122 |
|
| 123 |
+
files_per_page = 20
|
| 124 |
+
num_pages = (len(file_paths) - 1) // files_per_page + 1
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
+
col1, col2 = st.columns(2)
|
| 127 |
+
with col1:
|
| 128 |
+
if st.button("前へ", key="prev_page"):
|
| 129 |
+
st.session_state.page = max(1, st.session_state.page - 1)
|
| 130 |
+
with col2:
|
| 131 |
if st.button("次へ", key="next_page"):
|
| 132 |
st.session_state.page = min(num_pages, st.session_state.page + 1)
|
| 133 |
|
| 134 |
+
selected_page = st.number_input("移動するページを指定してください", min_value=1, max_value=num_pages, value=st.session_state.page, key="selected_page")
|
| 135 |
+
if selected_page != st.session_state.page:
|
| 136 |
+
st.session_state.page = selected_page
|
| 137 |
+
|
| 138 |
+
st.write(f"現在のページ: {st.session_state.page}")
|
| 139 |
+
|
| 140 |
+
current_page_files = paginate_files(file_paths, st.session_state.page, files_per_page)
|
| 141 |
+
|
| 142 |
+
sort_column = st.selectbox("並び替えオプション", ["timestamp", "good"])
|
| 143 |
+
ascending = st.checkbox("昇順", value=st.session_state.sort_option["ascending"])
|
| 144 |
+
st.session_state.sort_option = {"column": sort_column, "ascending": ascending}
|
| 145 |
+
|
| 146 |
+
if sort_column == "timestamp":
|
| 147 |
+
current_page_files.sort(key=lambda x: timestamps[file_paths.index(x)], reverse=not ascending)
|
| 148 |
+
elif sort_column == "good":
|
| 149 |
+
current_page_files.sort(key=lambda x: good_values[file_paths.index(x)], reverse=not ascending)
|
| 150 |
+
|
| 151 |
+
display_images(current_page_files)
|
| 152 |
+
|
| 153 |
+
# Blurのトグルを更新
|
| 154 |
+
st.session_state.blur_option = st.checkbox("NSFW画像にBlurをかける", value=st.session_state.blur_option)
|
| 155 |
+
|
| 156 |
+
# CSVに保存ボタン
|
| 157 |
+
if st.button("CSVに保存"):
|
| 158 |
+
csv_filename = "gradio_predictions_and_good_values.csv"
|
| 159 |
+
with open(csv_filename, mode='w', newline='', encoding='utf-8') as csv_file:
|
| 160 |
+
csv_writer = csv.writer(csv_file)
|
| 161 |
+
csv_writer.writerow(['ファイル名', 'NSFWの予測', 'Otherの予測', 'Goodの値', '作成時間'])
|
| 162 |
+
for i, file_path in enumerate(file_paths):
|
| 163 |
+
gradio_nsfw_prediction = gradio_nsfw_predictions[i]
|
| 164 |
+
gradio_other_prediction = gradio_other_predictions[i]
|
| 165 |
+
good_value = good_values[i]
|
| 166 |
+
timestamp = timestamps[i]
|
| 167 |
+
csv_writer.writerow([os.path.basename(file_path), gradio_nsfw_prediction, gradio_other_prediction, good_value, timestamp])
|
| 168 |
+
|
| 169 |
+
st.markdown(get_binary_file_downloader_html(csv_filename, label="CSVをダウンロード"), unsafe_allow_html=True)
|
| 170 |
+
|
| 171 |
+
with open("gradio_predictions.txt", "w") as f:
|
| 172 |
+
for prediction in gradio_nsfw_predictions:
|
| 173 |
+
f.write(f"{prediction[0]} (NSFW): {prediction[1]}\n")
|
| 174 |
+
for prediction in gradio_other_predictions:
|
| 175 |
+
f.write(f"{prediction[0]} (Other): {prediction[1]}\n")
|
| 176 |
+
|
| 177 |
+
if st.button("ファイルを一括ダウンロード"):
|
| 178 |
+
zip_filename = "files.zip"
|
| 179 |
+
with zipfile.ZipFile(zip_filename, "w") as zipf:
|
| 180 |
+
for file_path in file_paths:
|
| 181 |
+
zipf.write(file_path, os.path.basename(file_path))
|
| 182 |
|
| 183 |
+
st.markdown(get_binary_file_downloader_html(zip_filename, label="Zipファイルをダウンロード"), unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
| 185 |
st.success("ファイルがアップロードされました。このページのURLを他のクライアントと共有してください。")
|