KevinCS commited on
Commit
8b18a11
1 Parent(s): ee8ed6c
Files changed (7) hide show
  1. Frames1/ej.txt +0 -0
  2. Frames2/ej.txt +1 -0
  3. Frames3/ej.txt +0 -0
  4. Frames4/ej.txt +0 -0
  5. app.py +245 -0
  6. model.h5 +3 -0
  7. requirements.txt +0 -0
Frames1/ej.txt ADDED
File without changes
Frames2/ej.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ o
Frames3/ej.txt ADDED
File without changes
Frames4/ej.txt ADDED
File without changes
app.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import tensorflow as tf
3
+ import tensorflow.keras.backend as K
4
+ import numpy as np
5
+ from PIL import Image
6
+ import matplotlib.pyplot as plt
7
+ import cv2
8
+ import os
9
+ import shutil
10
+ from skimage.metrics import structural_similarity as ssim
11
+
12
+ beta = 1.0
13
+
14
+ # Loss for reveal network
15
+ def rev_loss(s_true, s_pred):
16
+ # Loss for reveal network is: beta * |S-S'|
17
+ return beta * K.sum(K.square(s_true - s_pred))
18
+
19
+ # Loss for the full model, used for preparation and hidding networks
20
+ def full_loss(y_true, y_pred):
21
+ # Loss for the full model is: |C-C'| + beta * |S-S'|
22
+ s_true, c_true = y_true[...,0:3], y_true[...,3:6]
23
+ s_pred, c_pred = y_pred[...,0:3], y_pred[...,3:6]
24
+
25
+ s_loss = rev_loss(s_true, s_pred)
26
+ c_loss = K.sum(K.square(c_true - c_pred))
27
+ return s_loss + c_loss
28
+
29
+ model = tf.keras.models.load_model("model.h5", custom_objects={'full_loss':
30
+ full_loss})
31
+
32
+
33
+ def preprocess_image(img):
34
+ if isinstance(img, np.ndarray):
35
+ img = Image.fromarray(img)
36
+ img = img.resize((124, 124), Image.ANTIALIAS)
37
+ img = np.array(img)
38
+ img = img / 255.0
39
+ return img
40
+
41
+ def steganography_image(imageO, imageF):
42
+ # Preprocess images
43
+ img_S = preprocess_image(imageO)
44
+ img_C = preprocess_image(imageF)
45
+
46
+ # Add batch dimension
47
+ img_S = np.expand_dims(img_S, axis=0)
48
+ img_C = np.expand_dims(img_C, axis=0)
49
+
50
+ # Predict with pre/loaded model
51
+ decoded = model.predict([img_S, img_C])
52
+ decoded_S, decoded_C = decoded[..., 0:3], decoded[..., 3:6]
53
+
54
+ # Post-process outputs
55
+ decoded_S = np.squeeze(decoded_S, axis=0) # Remove batch dimension
56
+ decoded_C = np.squeeze(decoded_C, axis=0) # Remove batch dimension
57
+ decoded_S = (decoded_S * 255).astype(np.uint8)
58
+ decoded_C = (decoded_C * 255).astype(np.uint8)
59
+
60
+ # Calculate absolute differences
61
+ diff_S = np.abs(decoded_S - (img_S.squeeze() * 255)).astype(np.uint8)
62
+ diff_C = np.abs(decoded_C - (img_C.squeeze() * 255)).astype(np.uint8)
63
+
64
+ # Create a plot of differences
65
+ fig, ax = plt.subplots(1, 2, figsize=(10, 5))
66
+ ax[0].imshow(diff_S)
67
+ ax[0].set_title('Difference in Secret Image')
68
+ ax[0].axis('off')
69
+ ax[1].imshow(diff_C)
70
+ ax[1].set_title('Difference in Cover Image')
71
+ ax[1].axis('off')
72
+ plt.tight_layout()
73
+
74
+ # Return images and plot
75
+ return decoded_S, decoded_C, fig
76
+
77
+
78
+ #Function to clear a folder
79
+ def clear_folder(path):
80
+ if os.path.exists(path):
81
+ shutil.rmtree(path)
82
+ os.makedirs(path)
83
+
84
+ #Function to extract every frame of a video and save them in a folder
85
+ def extractImages(pathIn, pathOut):
86
+ clear_folder(pathOut)
87
+ if not os.path.exists(pathOut):
88
+ os.makedirs(pathOut)
89
+
90
+ vidcap = cv2.VideoCapture(pathIn)
91
+ success, image = vidcap.read()
92
+ count = 0
93
+
94
+ while success:
95
+ frame_path = os.path.join(pathOut, f"frame{count}.jpg")
96
+ success, image = vidcap.read()
97
+
98
+ if success:
99
+ resized_image = cv2.resize(image, (124, 124), interpolation=cv2.INTER_AREA)
100
+ cv2.imwrite(frame_path, resized_image)
101
+ print(f'Saved frame {count} to {frame_path}')
102
+ else:
103
+ print(f'Failed to read frame at count {count}')
104
+
105
+ count += 1
106
+
107
+ #Function to create a new video based on a folder of frames
108
+ def rebuildVideo(framesPath, outputPath, fps=30):
109
+ frame_files = sorted([f for f in os.listdir(framesPath) if f.endswith('.jpg')],
110
+ key=lambda x: int(x[5:-4]))
111
+
112
+ first_frame_path = os.path.join(framesPath, frame_files[0])
113
+ frame = cv2.imread(first_frame_path)
114
+ height, width, layers = frame.shape
115
+
116
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
117
+ out = cv2.VideoWriter(outputPath, fourcc, fps, (width, height))
118
+
119
+ for file in frame_files:
120
+ frame_path = os.path.join(framesPath, file)
121
+ frame = cv2.imread(frame_path)
122
+ out.write(frame)
123
+ out.release()
124
+
125
+
126
+ def calculate_ssim(img1, img2):
127
+ img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
128
+ img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
129
+ score, _ = ssim(img1_gray, img2_gray, full=True)
130
+ return score
131
+
132
+ def plot_metrics(metrics):
133
+ fig, ax = plt.subplots()
134
+ ax.plot(metrics, label="SSIM")
135
+ ax.set_xlabel("Frame")
136
+ ax.set_ylabel("SSIM")
137
+ ax.set_title("SSIM over Frames")
138
+ ax.legend()
139
+ ax.grid(True)
140
+ return fig
141
+
142
+ def process_frame(imageO, imageF):
143
+ img_S = preprocess_image(imageO)
144
+ img_C = preprocess_image(imageF)
145
+ img_S = np.expand_dims(img_S, axis=0)
146
+ img_C = np.expand_dims(img_C, axis=0)
147
+ decoded = model.predict([img_S, img_C])
148
+ decoded_S, decoded_C = decoded[..., 0:3], decoded[..., 3:6]
149
+ decoded_S = np.squeeze(decoded_S, axis=0)
150
+ decoded_C = np.squeeze(decoded_C, axis=0)
151
+ decoded_S = (decoded_S * 255).astype(np.uint8)
152
+ decoded_C = (decoded_C * 255).astype(np.uint8)
153
+ return decoded_S, decoded_C
154
+
155
+ def steganography_video(video_path1, video_path2):
156
+ input_frames_path = "Frames1"
157
+ input_frames_path2 = "Frames2"
158
+ output_frames_path = "Frames3"
159
+ output_frames_path2 = "Frames4"
160
+ output_video_path = "output_video.mp4"
161
+ output_video_path2 = "output_video2.mp4"
162
+ extractImages(video_path1, input_frames_path)
163
+ extractImages(video_path2, input_frames_path2)
164
+
165
+ input_frame_files = sorted([f for f in os.listdir(input_frames_path) if f.endswith('.jpg')],
166
+ key=lambda x: int(x[5:-4]))
167
+
168
+ clear_folder(output_frames_path)
169
+ clear_folder(output_frames_path2)
170
+ i = 0
171
+ ssim_scores = []
172
+ ssim_scores2 = []
173
+
174
+ for file in input_frame_files:
175
+ frame_path = os.path.join(input_frames_path, file)
176
+ frame_path2 = os.path.join(input_frames_path2, f"frame{i}.jpg")
177
+ frame = cv2.imread(frame_path)
178
+ try:
179
+ frame2 = cv2.imread(frame_path2)
180
+ except:
181
+ print("Second video is too short, will be cut up to the length of the first one")
182
+ break
183
+ if frame2 is None:
184
+ break
185
+ decoded_S, decoded_C = process_frame(frame, frame2)
186
+ decoded_S_path = os.path.join(output_frames_path, file)
187
+ cv2.imwrite(decoded_S_path, decoded_S)
188
+ decoded_C_path = os.path.join(output_frames_path2, file)
189
+ cv2.imwrite(decoded_C_path, decoded_C)
190
+ print(frame.shape)
191
+ print(decoded_S.shape)
192
+ print(frame2.shape)
193
+ print(decoded_C.shape)
194
+ ssim_scores.append(calculate_ssim(frame, decoded_S))
195
+ ssim_scores2.append(calculate_ssim(frame2, decoded_C))
196
+ i+=1
197
+
198
+ rebuildVideo(output_frames_path, output_video_path, fps=20)
199
+ rebuildVideo(output_frames_path2, output_video_path2, fps=20)
200
+
201
+ return output_video_path, output_video_path2, ssim_scores, ssim_scores2
202
+
203
+ example_secret_image = "Examples/secret.jpg"
204
+ example_cover_image = "Examples/cover.jpg"
205
+ example_cover_video = "Examples/cover.mp4"
206
+ example_secret_video = "Examples/secret.mp4"
207
+
208
+ with gr.Blocks() as demo:
209
+ with gr.Tab("Image Processing"):
210
+ image_input1 = gr.Image(label="Cover Image")
211
+ image_input2 = gr.Image(label="Secret Image")
212
+ image_output1 = gr.Image(label="Decoded Cover Image")
213
+ image_output2 = gr.Image(label="Decoded Secret Image")
214
+ plot = gr.Plot(label = "Noise behind each image")
215
+ btn_image = gr.Button("Process Images")
216
+
217
+ btn_image.click(
218
+ fn=steganography_image,
219
+ inputs=[image_input1, image_input2],
220
+ outputs=[image_output1, image_output2, plot]
221
+ )
222
+
223
+ with gr.Tab("Video Processing"):
224
+ video_input = gr.Video(label="Input Cover Video")
225
+ video_input2 = gr.Video(label="Input Secret Video")
226
+ video_output = gr.Video(label="Output Cover Video")
227
+ video_output2 = gr.Video(label="Output Secret Video")
228
+ plot_output = gr.Plot(label="SSIM over Frames for Cover")
229
+ plot_output2 = gr.Plot(label="SSIM over Frames for Secret")
230
+ btn_video = gr.Button("Process Video")
231
+
232
+ def process_video_and_plot(video_path, video_path2):
233
+ video_path, video_path2, ssim_scores, ssim_scores2 = steganography_video(video_path, video_path2)
234
+ plot = plot_metrics(ssim_scores)
235
+ plot2 = plot_metrics(ssim_scores2)
236
+ plot.show()
237
+ return video_path, video_path2, plot, plot2
238
+
239
+ btn_video.click(
240
+ fn=process_video_and_plot,
241
+ inputs=[video_input, video_input2],
242
+ outputs=[video_output, video_output2, plot_output, plot_output2]
243
+ )
244
+
245
+ demo.launch(debug=True, share = True)
model.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b287c5fa29cda983f4811bc3e33f301ee0e092e50ccc21b97692c8ae0a9b6552
3
+ size 4496460
requirements.txt ADDED
Binary file (3.79 kB). View file