alphatomy0011 commited on
Commit
9d3ef99
·
verified ·
1 Parent(s): 75862e4

Upload 4 files

Browse files
02_🎭_Face_Feature_Swap.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ import numpy as np
4
+ from PIL import Image
5
+ from utils.face_utils import swap_facial_features
6
+
7
+ # Page configuration
8
+ st.set_page_config(
9
+ page_title="🎭 Face Feature Swapper",
10
+ page_icon=":smiley:",
11
+ layout="wide"
12
+ )
13
+
14
+ # Title and description
15
+ st.title("🎭 Face Feature Swapper")
16
+ st.subheader("Combine facial features from different photos")
17
+ st.markdown("""
18
+ Upload two photos to swap facial features:
19
+ 1. **Base Photo**: The main face that will be modified
20
+ 2. **Donor Photo**: Provides features to transfer
21
+ """)
22
+
23
+ # Initialize session state
24
+ if 'result_image' not in st.session_state:
25
+ st.session_state.result_image = None
26
+ if 'base_img' not in st.session_state:
27
+ st.session_state.base_img = None
28
+ if 'donor_img' not in st.session_state:
29
+ st.session_state.donor_img = None
30
+
31
+ # Upload widgets
32
+ col1, col2 = st.columns(2)
33
+ with col1:
34
+ base_file = st.file_uploader("Base Photo", type=["jpg", "jpeg", "png"])
35
+ if base_file:
36
+ st.session_state.base_img = np.array(Image.open(base_file))
37
+ st.image(st.session_state.base_img, caption="Base Photo", use_column_width=True)
38
+
39
+ with col2:
40
+ donor_file = st.file_uploader("Donor Photo", type=["jpg", "jpeg", "png"])
41
+ if donor_file:
42
+ st.session_state.donor_img = np.array(Image.open(donor_file))
43
+ st.image(st.session_state.donor_img, caption="Donor Photo", use_column_width=True)
44
+
45
+ # Feature selection and options
46
+ if st.session_state.base_img is not None and st.session_state.donor_img is not None:
47
+ st.subheader("Feature Selection")
48
+ features = st.multiselect(
49
+ "Select features to swap:",
50
+ ["Eyes", "Lips", "Eyebrows", "Nose"],
51
+ default=["Eyes", "Lips"]
52
+ )
53
+
54
+ blend_intensity = st.slider("Blending Intensity", 0.0, 1.0, 0.9)
55
+ show_landmarks = st.checkbox("Show Facial Landmarks", True)
56
+
57
+ if st.button("Swap Features", use_container_width=True):
58
+ with st.spinner("Creating your custom face..."):
59
+ # Swap features
60
+ result = swap_facial_features(
61
+ st.session_state.base_img.copy(),
62
+ st.session_state.donor_img.copy(),
63
+ features,
64
+ blend_intensity
65
+ )
66
+
67
+ # Convert to PIL for display
68
+ st.session_state.result_image = Image.fromarray(result)
69
+
70
+ st.success("Feature swap complete!")
71
+
72
+ # Display results
73
+ if st.session_state.result_image:
74
+ st.subheader("Result")
75
+ col1, col2 = st.columns([1, 1])
76
+
77
+ with col1:
78
+ st.image(st.session_state.result_image, caption="Modified Face", use_column_width=True)
79
+
80
+ # Download button
81
+ buf = BytesIO()
82
+ st.session_state.result_image.save(buf, format="JPEG")
83
+ st.download_button(
84
+ label="Download Result",
85
+ data=buf.getvalue(),
86
+ file_name="custom_face.jpg",
87
+ mime="image/jpeg",
88
+ use_container_width=True
89
+ )
90
+
91
+ with col2:
92
+ if show_landmarks:
93
+ st.subheader("Feature Visualization")
94
+ from utils.face_utils import detect_landmarks, get_feature_mask
95
+
96
+ # Create visualization
97
+ vis_img = st.session_state.base_img.copy()
98
+ landmarks = detect_landmarks(vis_img)
99
+
100
+ if landmarks:
101
+ for feature in features:
102
+ mask = get_feature_mask(landmarks, feature.lower(), vis_img.shape)
103
+ color = {
104
+ 'eyes': (0, 255, 0),
105
+ 'lips': (0, 0, 255),
106
+ 'eyebrows': (255, 0, 0),
107
+ 'nose': (255, 255, 0)
108
+ }[feature.lower()]
109
+
110
+ # Draw contours
111
+ contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
112
+ cv2.drawContours(vis_img, contours, -1, color, 2)
113
+
114
+ st.image(vis_img, caption="Feature Regions", use_column_width=True)
115
+ else:
116
+ st.warning("Could not detect facial features in base image")
117
+
118
+ # Preset management
119
+ st.sidebar.subheader("Presets")
120
+ preset_name = st.sidebar.text_input("Save current settings as preset:")
121
+ if st.sidebar.button("Save Preset"):
122
+ if preset_name:
123
+ st.session_state[preset_name] = {
124
+ 'features': features,
125
+ 'blend_intensity': blend_intensity
126
+ }
127
+ st.sidebar.success(f"Preset '{preset_name}' saved!")
128
+ else:
129
+ st.sidebar.warning("Please enter a preset name")
130
+
131
+ # Load presets
132
+ preset_names = [k for k in st.session_state.keys() if k not in ['base_img', 'donor_img', 'result_image']]
133
+ selected_preset = st.sidebar.selectbox("Load preset", preset_names)
134
+ if selected_preset and st.sidebar.button("Apply Preset"):
135
+ preset = st.session_state[selected_preset]
136
+ features = preset['features']
137
+ blend_intensity = preset['blend_intensity']
138
+ st.experimental_rerun()
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ libgl1-mesa-glx
2
+ libglib2.0-0
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ mediapipe==0.10.9
2
+ opencv-python==4.9.0.80
3
+ numpy==1.26.4
4
+ streamlit==1.32.0
5
+ Pillow==10.3.0
tempCodeRunnerFile.py ADDED
@@ -0,0 +1 @@
 
 
1
+ BytesIO