|
import streamlit as st |
|
import streamlit.components.v1 as components |
|
import cv2 |
|
import numpy as np |
|
from PIL import Image, ExifTags |
|
|
|
|
|
st.set_page_config(page_title="λ₯νμ΄ν¬ μ¬μ λ°©μ§ νν°(ν
μ€νΈ)", layout="wide") |
|
|
|
|
|
st.title("λ₯νμ΄ν¬ μ¬μ λ°©μ§ νν°(ν
μ€νΈ)") |
|
st.markdown("") |
|
st.markdown("<span style='font-size: 18px;'>μλ
νμΈμ! μ ν¬λ λ₯νμ΄ν¬λ‘λΆν° μ¬λ¬λΆμ μ¬μ§μ 보νΈνλ μ루μ
μ κ°λ°νκ³ μμ΅λλ€.</span>", unsafe_allow_html=True) |
|
st.markdown("<span style='font-size: 18px;'>μ ν¬μ λͺ©νλ μ¨λΌμΈμ κ²μλ κ°μΈμ μ¬μ§μ΄ μ
μ± λ₯νμ΄ν¬ μμμ μ¬μ©λμ§ μλλ‘ νλ κ²μ
λλ€. μ μ λ‘ μΉμ μμ, μ¬λ¬λΆμ μ견μ λ£κΈ° μν΄ κ°λ¨ν ν
μ€νΈλ₯Ό μ§ννκ³ μμ΅λλ€.</span>", unsafe_allow_html=True) |
|
st.markdown("<span style='font-size: 18px;'>μ΅κ·Ό SNSμ μ
λ‘λλ μ΄λ―Έμ§κ° λ₯νμ΄ν¬μ μ
μ©λλ μ¬λ‘κ° λ§€μΌ λ³΄κ³ λκ³ μμ΅λλ€. λ°λΌμ ν΄κ²°μ±
μ κ°κ΅¬νκΈ° μν΄, μ¬λ¬λΆμ μμ€ν μκ²¬μ΄ νμν©λλ€.</span>", unsafe_allow_html=True) |
|
st.markdown("") |
|
st.markdown("<span style='font-size: 18px;'>μ§ν κ³Όμ 1. μ¬λ μ΄λ―Έμ§λ₯Ό μ
λ‘λνλ©΄, μ¬μ λ°©μ§ νν°κ° μ μ©λ μ΄λ―Έμ§λ₯Ό 보μ¬λ립λλ€.</span>", unsafe_allow_html=True) |
|
st.markdown("<span style='font-size: 18px;'>μ§ν κ³Όμ 2. λ₯νμ΄ν¬ μ€ν λ²νΌμ ν΄λ¦νλ©΄, λ₯νμ΄ν¬ κ²°κ³Όλ₯Ό νμΈν μ μμ΅λλ€.</span>", unsafe_allow_html=True) |
|
st.markdown("<span style='font-size: 18px;'>μ¬λ¬λΆμ μ°Έμ¬μ κ°μ¬λ립λλ€!</span>", unsafe_allow_html=True) |
|
st.markdown("<span style='font-size: 14px;'> *μ¬μ λ°©μ§ νν°λ: μ¬μ§μ λ―ΈμΈν λ³νλ₯Ό μ£Όμ΄ λ₯νμ΄ν¬ λͺ¨λΈμ νμ΅λμ§ λͺ»νλλ‘ λ°©ν΄νλ νν°.</span>", unsafe_allow_html=True) |
|
st.markdown( |
|
""" |
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet"> |
|
<style> |
|
/* κ³΅ν΅ μ€νμΌ */ |
|
.stFileUploader label, |
|
.stRadio label, |
|
.stRadio div, |
|
.custom-caption-1, |
|
.custom-caption-2, |
|
.custom-caption-3, |
|
.button-container, |
|
.stButton button, |
|
.survey, |
|
.survey-1, |
|
.survey-2, |
|
.a-tag, |
|
a { |
|
transition: all 0.3s ease; |
|
} |
|
.stFileUploader label { |
|
font-size: 20px; |
|
font-weight: 500; |
|
color: #1f77b4; |
|
} |
|
.stRadio label { |
|
font-size: 20px; |
|
font-weight: 500; |
|
color: #1f77b4; |
|
} |
|
.stRadio div { |
|
display: flex; |
|
gap: 20px; |
|
} |
|
.custom-caption-1 { |
|
font-size: 36px; |
|
font-weight: bold; |
|
text-align: center; |
|
margin-top: 10px; |
|
padding: 0 0 200px 0; |
|
} |
|
.custom-caption-2 { |
|
font-size: 36px; |
|
font-weight: bold; |
|
text-align: center; |
|
margin-top: 10px; |
|
padding: 0 0 30px 0; |
|
} |
|
.custom-caption-3 { |
|
font-size: 30px; |
|
# font-weight: bold; |
|
text-align: center; |
|
margin-top: 10px; |
|
padding: 0 0 30px 0; |
|
} |
|
.button-container { |
|
text-align: center; |
|
margin-top: 30px; |
|
} |
|
.stButton button { |
|
width: 50%; |
|
font-size: 25px; |
|
padding: 10px 20px; |
|
background-color: #FFFFFF; |
|
font-weight: bold; |
|
color: black; |
|
opacity: 0.8; |
|
border: 3px solid black; |
|
border-radius: 5px; |
|
cursor: pointer; |
|
margin: 0 auto 50px auto; |
|
display: block; |
|
} |
|
.stButton button:hover { |
|
background-color: #FFFFFF; |
|
border: 3px solid #FF0080; |
|
color: #FF0080; |
|
opacity: 1; |
|
} |
|
.survey { |
|
text-align: center; |
|
margin-top: 10px |
|
} |
|
.survey-1 { |
|
font-size: 25px; |
|
text-align: center; |
|
margin-top: 10px |
|
font-weight: bold; |
|
} |
|
.survey-2 { |
|
text-align: center; |
|
margin-top: 10px |
|
font-weight: bold; |
|
padding 0 auto 50px auto |
|
} |
|
.a-tag { |
|
color: #FF0080; |
|
text-decoration: none; |
|
} |
|
a:hover { |
|
color: #FF0080; |
|
text-decoration: none; |
|
} |
|
|
|
/* μ€λ§νΈν° νλ©΄ μ€νμΌ */ |
|
@media only screen and (max-width: 600px) { |
|
.stFileUploader label, |
|
.stRadio label, |
|
.stButton button, |
|
.survey-1 { |
|
font-size: 16px; |
|
} |
|
.custom-caption-1, |
|
.custom-caption-2 { |
|
font-size: 24px; |
|
padding: 0 0 20px 0; |
|
} |
|
.custom-caption-3 { |
|
font-size: 20px; |
|
padding: 0 0 20px 0; |
|
} |
|
.stButton button { |
|
width: 100%; |
|
font-size: 18px; |
|
} |
|
} |
|
</style> |
|
""", |
|
unsafe_allow_html=True, |
|
) |
|
|
|
def change_hair_to_blonde(image): |
|
|
|
image = np.array(image) |
|
|
|
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV) |
|
|
|
|
|
lower_hair = np.array([0, 0, 0]) |
|
upper_hair = np.array([180, 255, 30]) |
|
|
|
|
|
mask = cv2.inRange(hsv, lower_hair, upper_hair) |
|
|
|
|
|
hsv[mask > 0] = (30, 255, 200) |
|
|
|
|
|
image_blonde = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) |
|
return image_blonde |
|
|
|
def add_noise(image): |
|
|
|
image_np = np.array(image) |
|
|
|
noise = np.random.normal(0, 25, image_np.shape).astype(np.uint8) |
|
|
|
noisy_image = cv2.add(image_np, noise) |
|
return noisy_image |
|
|
|
def correct_image_orientation(image): |
|
try: |
|
for orientation in ExifTags.TAGS.keys(): |
|
if ExifTags.TAGS[orientation] == 'Orientation': |
|
break |
|
exif = image._getexif() |
|
if exif is not None: |
|
orientation = exif.get(orientation, 1) |
|
if orientation == 3: |
|
image = image.rotate(180, expand=True) |
|
elif orientation == 6: |
|
image = image.rotate(270, expand=True) |
|
elif orientation == 8: |
|
image = image.rotate(90, expand=True) |
|
except (AttributeError, KeyError, IndexError): |
|
pass |
|
return image |
|
|
|
uploaded_file = st.file_uploader("μ΄λ―Έμ§λ₯Ό μ
λ‘λνμΈμ...", type=["jpg", "png", "jpeg"]) |
|
|
|
if uploaded_file is not None: |
|
image = Image.open(uploaded_file) |
|
image = correct_image_orientation(image) |
|
|
|
st.write("μ΄λ―Έμ§ μ²λ¦¬ μ€...") |
|
|
|
|
|
image_np = np.array(image) |
|
|
|
col1, col2 = st.columns(2) |
|
|
|
with col1: |
|
st.image(image, use_column_width=True) |
|
st.markdown('<div class="custom-caption-1">μ
λ‘λν μλ³Έ μ΄λ―Έμ§</div>', unsafe_allow_html=True) |
|
|
|
with col2: |
|
st.image(image, use_column_width=True) |
|
st.markdown('<div class="custom-caption-1">νν°λ₯Ό μ
ν μ΄λ―Έμ§</div>', unsafe_allow_html=True) |
|
|
|
st.markdown('<div class="custom-caption-1">νν°λ₯Ό μ
ν μ΄λ―Έμ§λ μ‘μμΌλ‘ λ΄€μλ, ν° μ°¨μ΄κ° μμ</div>', unsafe_allow_html=True) |
|
|
|
button_clicked = st.button("λ₯νμ΄ν¬ μ μ©νκΈ°") |
|
|
|
col3, col4 = st.columns(2) |
|
|
|
if button_clicked: |
|
processed_image = change_hair_to_blonde(image) |
|
deepfake_image = add_noise(image) |
|
else: |
|
processed_image = None |
|
deepfake_image = None |
|
|
|
if processed_image is not None and deepfake_image is not None: |
|
with col3: |
|
st.image(processed_image, use_column_width=True) |
|
st.markdown('<div class="custom-caption-2">μλ³Έ μ΄λ―Έμ§λ‘ λ₯νμ΄ν¬λ₯Ό μ μν κ²½μ°</div>', unsafe_allow_html=True) |
|
st.markdown('<div class="custom-caption-3">μ΄ν΄λ₯Ό λκΈ° μν΄ μ¬μ§μ λ
Έλμμ μ
νλ λ₯νμ΄ν¬ μκ³ λ¦¬μ¦ μ μ©. μλ³Έ μ΄λ―Έμ§λ λ₯νμ΄ν¬ μκ³ λ¦¬μ¦μ μν₯μ λ°μ.</div>', unsafe_allow_html=True) |
|
|
|
with col4: |
|
st.image(deepfake_image, use_column_width=True) |
|
st.markdown('<div class="custom-caption-2">λ°©μ§ νν° μ΄λ―Έμ§λ‘ λ₯νμ΄ν¬λ₯Ό μ μν κ²½μ°</div>', unsafe_allow_html=True) |
|
st.markdown('<div class="custom-caption-3">λ°©μ§ νν°λ₯Ό μ
ν μ΄λ―Έμ§λ λ₯νμ΄ν¬μ μν₯μ λ°μ§ μκ³ μμ보기 νλ μ¬μ§μ μΆλ ₯ν¨μΌλ‘μ¨ μ΄λ―Έμ§λ₯Ό 보νΈν¨.</div>', unsafe_allow_html=True) |
|
|
|
st.markdown('<p class="survey"> μ μ¬ν μλΉμ€λ₯Ό μ¬μ©ν΄ 보μ
¨κ±°λ, μ ν¬ κΈ°μ μ μ리μ κ΄μ¬μ΄ μμΌμ λΆλ€κ»μ μλμ κ°λ¨ν μΈν°λ·°μ μ°Έμ¬ν΄ μ£Όμλ©΄ μ§μ¬μΌλ‘ κ°μ¬λλ¦¬κ² μ΅λλ€.</p>', unsafe_allow_html=True) |
|
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) |
|
st.markdown('<p class="survey-2">μλΉμ€λ₯Ό μ΄μ©ν΄ μ£Όμ
μ κ°μ¬ν©λλ€! μ’μ ν루 보λ΄μΈμ!</p>', unsafe_allow_html=True) |