Spaces:
Sleeping
Sleeping
Update app.py
Browse files"๋ฐ์ํ์ผ๋ก"
app.py
CHANGED
@@ -4,8 +4,10 @@ import cv2
|
|
4 |
import numpy as np
|
5 |
from PIL import Image, ExifTags
|
6 |
|
|
|
7 |
st.set_page_config(page_title="๋ฅํ์ดํฌ ์ฌ์ ๋ฐฉ์ง ํํฐ(ํ
์คํธ)", layout="wide")
|
8 |
|
|
|
9 |
ga_code = """
|
10 |
<!-- Global site tag (gtag.js) - Google Analytics -->
|
11 |
<script async src="https://www.googletagmanager.com/gtag/js?id=G-PZPBGNENQG"></script>
|
@@ -16,8 +18,11 @@ ga_code = """
|
|
16 |
gtag('config', 'G-PZPBGNENQG');
|
17 |
</script>
|
18 |
"""
|
|
|
|
|
19 |
components.html(ga_code, height=0)
|
20 |
|
|
|
21 |
st.title("๋ฅํ์ดํฌ ์ฌ์ ๋ฐฉ์ง ํํฐ(ํ
์คํธ)")
|
22 |
st.markdown("")
|
23 |
st.markdown("<span style='font-size: 18px;'>์๋
ํ์ธ์! ์ ํฌ๋ ๋ฅํ์ดํฌ๋ก๋ถํฐ ์ฌ๋ฌ๋ถ์ ์ฌ์ง์ ๋ณดํธํ๋ ์๋ฃจ์
์ ๊ฐ๋ฐํ๊ณ ์์ต๋๋ค.</span>", unsafe_allow_html=True)
|
@@ -32,6 +37,21 @@ st.markdown(
|
|
32 |
"""
|
33 |
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
34 |
<style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
.stFileUploader label {
|
36 |
font-size: 20px;
|
37 |
font-weight: 500;
|
@@ -47,16 +67,18 @@ st.markdown(
|
|
47 |
gap: 20px;
|
48 |
}
|
49 |
.custom-caption-1 {
|
50 |
-
font-size:
|
51 |
font-weight: bold;
|
52 |
text-align: center;
|
53 |
margin-top: 10px;
|
|
|
54 |
}
|
55 |
.custom-caption-2 {
|
56 |
-
font-size:
|
57 |
font-weight: bold;
|
58 |
text-align: center;
|
59 |
margin-top: 10px;
|
|
|
60 |
}
|
61 |
.button-container {
|
62 |
text-align: center;
|
@@ -106,27 +128,61 @@ st.markdown(
|
|
106 |
color: #FF0080;
|
107 |
text-decoration: none;
|
108 |
}
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
114 |
}
|
115 |
-
.
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
118 |
}
|
119 |
}
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
126 |
}
|
127 |
-
.
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
}
|
131 |
}
|
132 |
</style>
|
@@ -135,18 +191,31 @@ st.markdown(
|
|
135 |
)
|
136 |
|
137 |
def change_hair_to_blonde(image):
|
|
|
138 |
image = np.array(image)
|
|
|
139 |
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
|
|
|
|
|
140 |
lower_hair = np.array([0, 0, 0])
|
141 |
upper_hair = np.array([180, 255, 30])
|
|
|
|
|
142 |
mask = cv2.inRange(hsv, lower_hair, upper_hair)
|
|
|
|
|
143 |
hsv[mask > 0] = (30, 255, 200)
|
|
|
|
|
144 |
image_blonde = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
|
145 |
return image_blonde
|
146 |
|
147 |
def add_noise(image):
|
|
|
148 |
image_np = np.array(image)
|
|
|
149 |
noise = np.random.normal(0, 25, image_np.shape).astype(np.uint8)
|
|
|
150 |
noisy_image = cv2.add(image_np, noise)
|
151 |
return noisy_image
|
152 |
|
@@ -176,54 +245,33 @@ if uploaded_file is not None:
|
|
176 |
|
177 |
st.write("์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค...")
|
178 |
|
|
|
179 |
image_np = np.array(image)
|
180 |
-
processed_image = change_hair_to_blonde(image)
|
181 |
-
deepfake_image = add_noise(image)
|
182 |
-
|
183 |
-
def image_to_base64(image):
|
184 |
-
from io import BytesIO
|
185 |
-
import base64
|
186 |
-
buffered = BytesIO()
|
187 |
-
image.save(buffered, format="PNG")
|
188 |
-
return base64.b64encode(buffered.getvalue()).decode()
|
189 |
-
|
190 |
-
image_base64 = image_to_base64(image)
|
191 |
-
processed_image_base64 = image_to_base64(Image.fromarray(processed_image))
|
192 |
-
|
193 |
-
components.html(f"""
|
194 |
-
<div class="img-grid">
|
195 |
-
<div>
|
196 |
-
<img src="data:image/png;base64,{image_base64}" />
|
197 |
-
<div class="custom-caption-1">์
๋ก๋ํ ์ด๋ฏธ์ง</div>
|
198 |
-
</div>
|
199 |
-
<div>
|
200 |
-
<img src="data:image/png;base64,{processed_image_base64}" />
|
201 |
-
<div class="custom-caption-1">ํํฐ๋ฅผ ์
ํ ์ด๋ฏธ์ง</div>
|
202 |
-
</div>
|
203 |
-
</div>
|
204 |
-
""", height=600)
|
205 |
-
|
206 |
-
button_clicked = st.button("์๋จ์ ๋ ์ฌ์ง์ ๋ฅํ์ดํฌ ๋ชจ๋ธ์ ํ์ต์ํค๊ธฐ")
|
207 |
|
208 |
-
|
209 |
-
processed_image_base64 = image_to_base64(Image.fromarray(processed_image))
|
210 |
-
deepfake_image_base64 = image_to_base64(Image.fromarray(deepfake_image))
|
211 |
-
|
212 |
-
components.html(f"""
|
213 |
-
<div class="img-grid">
|
214 |
-
<div>
|
215 |
-
<img src="data:image/png;base64,{processed_image_base64}" />
|
216 |
-
<div class="custom-caption-2">์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๋ฅํ์ดํฌ ๋ชจ๋ธ์ ๋ฃ์์ ๊ฒฝ์ฐ</div>
|
217 |
-
<span>์ดํด๋ฅผ ๋๊ธฐ ์ํด ์ฌ์ง์ ๋
ธ๋์์ ์
ํ๋ ๋ฅํ์ดํฌ ์๊ณ ๋ฆฌ์ฆ ์ ์ฉ. ์๋ณธ ์ด๋ฏธ์ง๋ ๋ฅํ์ดํฌ ์๊ณ ๋ฆฌ์ฆ์ ์ํฅ์ ๋ฐ์.</span>
|
218 |
-
</div>
|
219 |
-
<div>
|
220 |
-
<img src="data:image/png;base64,{deepfake_image_base64}" />
|
221 |
-
<div class="custom-caption-2">์ฌ์ ๋ฐฉ์ง ํํฐ ์ด๋ฏธ์ง๋ฅผ ๋ฅํ์ดํฌ ๋ชจ๋ธ์ ๋ฃ์์ ๊ฒฝ์ฐ</div>
|
222 |
-
<span>์ฌ์ ๋ฐฉ์ง ํํฐ๋ฅผ ์
ํ ์ด๋ฏธ์ง๋ ๋ฅํ์ดํฌ ์๊ณ ๋ฆฌ์ฆ์ ์ํฅ์ ๋ฐ์ง ์๊ณ ๋
ธ์ด์ฆ ์ฒ๋ฆฌ๊ฐ ๋์ด ์์๋ณด๊ธฐ ํ๋ ์ฌ์ง์ ์ถ๋ ฅ. ์ฆ, ๋ฅํ์ดํฌ ์ฌ์ง ํฉ์ฑ์ ๋ฐฉํดํจ.</span>
|
223 |
-
</div>
|
224 |
-
</div>
|
225 |
-
""", height=600)
|
226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
st.markdown('<p class="survey">์ ์๋น์ค๋ฅผ ์ฌ์ฉํด ๋ณด์
จ๊ฑฐ๋, ์ ํฌ ๊ธฐ์ ์ ์๋ฆฌ์ ๊ด์ฌ์ด ์์ผ์ ๋ถ๋ค๊ป์ ์๋์ ๊ฐ๋จํ ์ธํฐ๋ทฐ์ ์ฐธ์ฌํด ์ฃผ์๋ฉด ์ง์ฌ์ผ๋ก ๊ฐ์ฌ๋๋ฆฌ๊ฒ ์ต๋๋ค.</p>', unsafe_allow_html=True)
|
228 |
st.markdown('<p class="survey-1"><a href="https://docs.google.com/forms/d/e/1FAIpQLSdzRtuvQyp3CQDhlxEag40v2yDM7u9NYpJ2gv5kgwuNbo1gUA/viewform?usp=sf_link" target="_blank" class="a-tag">์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ฌ ์ธํฐ๋ทฐ์ ์ํด ์ฃผ์ ๋ค๋ฉด ํฐ ๋์์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค!!</a></p>', unsafe_allow_html=True)
|
229 |
st.markdown('<p class="survey-2">์๋น์ค๋ฅผ ์ด์ฉํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! ์ข์ ํ๋ฃจ ๋ณด๋ด์ธ์!</p>', unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import numpy as np
|
5 |
from PIL import Image, ExifTags
|
6 |
|
7 |
+
# ๊ฐ์ฅ ๋จผ์ set_page_config() ํธ์ถ
|
8 |
st.set_page_config(page_title="๋ฅํ์ดํฌ ์ฌ์ ๋ฐฉ์ง ํํฐ(ํ
์คํธ)", layout="wide")
|
9 |
|
10 |
+
|
11 |
ga_code = """
|
12 |
<!-- Global site tag (gtag.js) - Google Analytics -->
|
13 |
<script async src="https://www.googletagmanager.com/gtag/js?id=G-PZPBGNENQG"></script>
|
|
|
18 |
gtag('config', 'G-PZPBGNENQG');
|
19 |
</script>
|
20 |
"""
|
21 |
+
|
22 |
+
# Streamlit์ GA ์ฝ๋ ์ฝ์
|
23 |
components.html(ga_code, height=0)
|
24 |
|
25 |
+
# ๋๋จธ์ง Streamlit ์ฝ๋
|
26 |
st.title("๋ฅํ์ดํฌ ์ฌ์ ๋ฐฉ์ง ํํฐ(ํ
์คํธ)")
|
27 |
st.markdown("")
|
28 |
st.markdown("<span style='font-size: 18px;'>์๋
ํ์ธ์! ์ ํฌ๋ ๋ฅํ์ดํฌ๋ก๋ถํฐ ์ฌ๋ฌ๋ถ์ ์ฌ์ง์ ๋ณดํธํ๋ ์๋ฃจ์
์ ๊ฐ๋ฐํ๊ณ ์์ต๋๋ค.</span>", unsafe_allow_html=True)
|
|
|
37 |
"""
|
38 |
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
39 |
<style>
|
40 |
+
/* ๊ณตํต ์คํ์ผ */
|
41 |
+
.stFileUploader label,
|
42 |
+
.stRadio label,
|
43 |
+
.stRadio div,
|
44 |
+
.custom-caption-1,
|
45 |
+
.custom-caption-2,
|
46 |
+
.button-container,
|
47 |
+
.stButton button,
|
48 |
+
.survey,
|
49 |
+
.survey-1,
|
50 |
+
.survey-2,
|
51 |
+
.a-tag,
|
52 |
+
a {
|
53 |
+
transition: all 0.3s ease;
|
54 |
+
}
|
55 |
.stFileUploader label {
|
56 |
font-size: 20px;
|
57 |
font-weight: 500;
|
|
|
67 |
gap: 20px;
|
68 |
}
|
69 |
.custom-caption-1 {
|
70 |
+
font-size: 36px;
|
71 |
font-weight: bold;
|
72 |
text-align: center;
|
73 |
margin-top: 10px;
|
74 |
+
padding: 0 0 200px 0;
|
75 |
}
|
76 |
.custom-caption-2 {
|
77 |
+
font-size: 36px;
|
78 |
font-weight: bold;
|
79 |
text-align: center;
|
80 |
margin-top: 10px;
|
81 |
+
padding: 0 0 30px 0;
|
82 |
}
|
83 |
.button-container {
|
84 |
text-align: center;
|
|
|
128 |
color: #FF0080;
|
129 |
text-decoration: none;
|
130 |
}
|
131 |
+
|
132 |
+
/* ์ค๋งํธํฐ ํ๋ฉด ์คํ์ผ */
|
133 |
+
@media only screen and (max-width: 600px) {
|
134 |
+
.stFileUploader label,
|
135 |
+
.stRadio label,
|
136 |
+
.stButton button,
|
137 |
+
.survey-1 {
|
138 |
+
font-size: 16px;
|
139 |
}
|
140 |
+
.custom-caption-1,
|
141 |
+
.custom-caption-2 {
|
142 |
+
font-size: 24px;
|
143 |
+
padding: 0 0 20px 0;
|
144 |
+
}
|
145 |
+
.stButton button {
|
146 |
+
width: 100%;
|
147 |
+
font-size: 18px;
|
148 |
}
|
149 |
}
|
150 |
+
|
151 |
+
/* ํ๋ธ๋ฆฟ ํ๋ฉด ์คํ์ผ */
|
152 |
+
@media only screen and (min-width: 601px) and (max-width: 1024px) {
|
153 |
+
.stFileUploader label,
|
154 |
+
.stRadio label,
|
155 |
+
.stButton button,
|
156 |
+
.survey-1 {
|
157 |
+
font-size: 18px;
|
158 |
}
|
159 |
+
.custom-caption-1,
|
160 |
+
.custom-caption-2 {
|
161 |
+
font-size: 28px;
|
162 |
+
padding: 0 0 40px 0;
|
163 |
+
}
|
164 |
+
.stButton button {
|
165 |
+
width: 75%;
|
166 |
+
font-size: 20px;
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/* ๋ฐ์คํฌํฑ ํ๋ฉด ์คํ์ผ */
|
171 |
+
@media only screen and (min-width: 1025px) {
|
172 |
+
.stFileUploader label,
|
173 |
+
.stRadio label,
|
174 |
+
.stButton button,
|
175 |
+
.survey-1 {
|
176 |
+
font-size: 20px;
|
177 |
+
}
|
178 |
+
.custom-caption-1,
|
179 |
+
.custom-caption-2 {
|
180 |
+
font-size: 36px;
|
181 |
+
padding: 0 0 200px 0;
|
182 |
+
}
|
183 |
+
.stButton button {
|
184 |
+
width: 50%;
|
185 |
+
font-size: 25px;
|
186 |
}
|
187 |
}
|
188 |
</style>
|
|
|
191 |
)
|
192 |
|
193 |
def change_hair_to_blonde(image):
|
194 |
+
# Convert to OpenCV format
|
195 |
image = np.array(image)
|
196 |
+
# Convert the image to HSV color space
|
197 |
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
|
198 |
+
|
199 |
+
# Define the range for hair color (dark colors)
|
200 |
lower_hair = np.array([0, 0, 0])
|
201 |
upper_hair = np.array([180, 255, 30])
|
202 |
+
|
203 |
+
# Create a mask for hair
|
204 |
mask = cv2.inRange(hsv, lower_hair, upper_hair)
|
205 |
+
|
206 |
+
# Change hair color to blonde (light yellow)
|
207 |
hsv[mask > 0] = (30, 255, 200)
|
208 |
+
|
209 |
+
# Convert back to RGB color space
|
210 |
image_blonde = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
|
211 |
return image_blonde
|
212 |
|
213 |
def add_noise(image):
|
214 |
+
# Convert to OpenCV format
|
215 |
image_np = np.array(image)
|
216 |
+
# Generate random noise
|
217 |
noise = np.random.normal(0, 25, image_np.shape).astype(np.uint8)
|
218 |
+
# Add noise to the image
|
219 |
noisy_image = cv2.add(image_np, noise)
|
220 |
return noisy_image
|
221 |
|
|
|
245 |
|
246 |
st.write("์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค...")
|
247 |
|
248 |
+
# Save the original image as a numpy array
|
249 |
image_np = np.array(image)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
|
251 |
+
col1, col2 = st.columns(2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
|
253 |
+
with col1:
|
254 |
+
st.image(image, use_column_width=True)
|
255 |
+
st.markdown('<div class="custom-caption-1">์
๋ก๋ํ ์ด๋ฏธ์ง</div>', unsafe_allow_html=True)
|
256 |
+
|
257 |
+
with col2:
|
258 |
+
st.image(image, use_column_width=True)
|
259 |
+
st.markdown('<div class="custom-caption-1">ํํฐ๋ฅผ ์
ํ ์ด๋ฏธ์ง</div>', unsafe_allow_html=True)
|
260 |
+
|
261 |
+
button_clicked = st.button("์๋จ์ ๋ ์ฌ์ง์ ๋ฅํ์ดํฌ ๋ชจ๋ธ์ ํ์ต์ํค๊ธฐ")
|
262 |
st.markdown('<p class="survey">์ ์๋น์ค๋ฅผ ์ฌ์ฉํด ๋ณด์
จ๊ฑฐ๋, ์ ํฌ ๊ธฐ์ ์ ์๋ฆฌ์ ๊ด์ฌ์ด ์์ผ์ ๋ถ๋ค๊ป์ ์๋์ ๊ฐ๋จํ ์ธํฐ๋ทฐ์ ์ฐธ์ฌํด ์ฃผ์๋ฉด ์ง์ฌ์ผ๋ก ๊ฐ์ฌ๋๋ฆฌ๊ฒ ์ต๋๋ค.</p>', unsafe_allow_html=True)
|
263 |
st.markdown('<p class="survey-1"><a href="https://docs.google.com/forms/d/e/1FAIpQLSdzRtuvQyp3CQDhlxEag40v2yDM7u9NYpJ2gv5kgwuNbo1gUA/viewform?usp=sf_link" target="_blank" class="a-tag">์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ฌ ์ธํฐ๋ทฐ์ ์ํด ์ฃผ์ ๋ค๋ฉด ํฐ ๋์์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค!!</a></p>', unsafe_allow_html=True)
|
264 |
st.markdown('<p class="survey-2">์๋น์ค๋ฅผ ์ด์ฉํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! ์ข์ ํ๋ฃจ ๋ณด๋ด์ธ์!</p>', unsafe_allow_html=True)
|
265 |
+
|
266 |
+
if button_clicked:
|
267 |
+
with col1:
|
268 |
+
processed_image = change_hair_to_blonde(image)
|
269 |
+
st.image(processed_image, use_column_width=True)
|
270 |
+
st.markdown('<div class="custom-caption-2">์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๋ฅํ์ดํฌ ๋ชจ๋ธ์ ๋ฃ์์ ๊ฒฝ์ฐ</div>', unsafe_allow_html=True)
|
271 |
+
st.markdown("<span>์ดํด๋ฅผ ๋๊ธฐ ์ํด ์ฌ์ง์ ๋
ธ๋์์ ์
ํ๋ ๋ฅํ์ดํฌ ์๊ณ ๋ฆฌ์ฆ ์ ์ฉ. ์๋ณธ ์ด๋ฏธ์ง๋ ๋ฅํ์ดํฌ ์๊ณ ๋ฆฌ์ฆ์ ์ํฅ์ ๋ฐ์.</span>", unsafe_allow_html=True)
|
272 |
+
|
273 |
+
with col2:
|
274 |
+
deepfake_image = add_noise(image)
|
275 |
+
st.image(deepfake_image, use_column_width=True)
|
276 |
+
st.markdown('<div class="custom-caption-2">์ฌ์ ๋ฐฉ์ง ํํฐ ์ด๋ฏธ์ง๋ฅผ ๋ฅํ์ดํฌ ๋ชจ๋ธ์ ๋ฃ์์ ๊ฒฝ์ฐ</div>', unsafe_allow_html=True)
|
277 |
+
st.markdown("<span>์ฌ์ ๋ฐฉ์ง ํํฐ๋ฅผ ์
ํ ์ด๋ฏธ์ง๋ ๋ฅํ์ดํฌ ์๊ณ ๋ฆฌ์ฆ์ ์ํฅ์ ๋ฐ์ง ์๊ณ ๋
ธ์ด์ฆ ์ฒ๋ฆฌ๊ฐ ๋์ด ์์๋ณด๊ธฐ ํ๋ ์ฌ์ง์ ์ถ๋ ฅ. ์ฆ, ๋ฅํ์ดํฌ ์ฌ์ง ํฉ์ฑ์ ๋ฐฉํดํจ.</span>", unsafe_allow_html=True)
|