minhwai commited on
Commit
f3f180a
ยท
verified ยท
1 Parent(s): 6811e34

Update app.py

Browse files

"๋ฐ˜์‘ํ˜•์œผ๋กœ"

Files changed (1) hide show
  1. app.py +112 -64
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: 24px;
51
  font-weight: bold;
52
  text-align: center;
53
  margin-top: 10px;
 
54
  }
55
  .custom-caption-2 {
56
- font-size: 24px;
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
- @media only screen and (max-width: 768px) {
110
- .img-grid {
111
- display: flex;
112
- flex-direction: column;
113
- align-items: center;
 
 
 
114
  }
115
- .img-grid img {
116
- width: 90%;
117
- height: auto;
 
 
 
 
 
118
  }
119
  }
120
- @media only screen and (min-width: 769px) {
121
- .img-grid {
122
- display: flex;
123
- flex-direction: row;
124
- justify-content: center;
125
- gap: 10px;
 
 
126
  }
127
- .img-grid img {
128
- width: 100%;
129
- height: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- if button_clicked:
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)