Upload 6 files
Browse files
app.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from image import add_and_detect_watermark_image
|
| 3 |
+
from video import add_and_detect_watermark_video
|
| 4 |
+
from detect import detect_watermark_image
|
| 5 |
+
|
| 6 |
+
# Image Interface
|
| 7 |
+
image_inputs = [
|
| 8 |
+
gr.Image(type="numpy", label="Upload Image"),
|
| 9 |
+
gr.Textbox(label="Watermark Text")
|
| 10 |
+
]
|
| 11 |
+
|
| 12 |
+
image_outputs = [
|
| 13 |
+
gr.Image(type="numpy", label="Watermarked Image"),
|
| 14 |
+
gr.Image(type="numpy", label="Watermark Highlight"),
|
| 15 |
+
gr.File(label="Download Watermarked Image"),
|
| 16 |
+
gr.File(label="Download Watermark Highlight")
|
| 17 |
+
]
|
| 18 |
+
|
| 19 |
+
def process_image(image, text):
|
| 20 |
+
watermarked_image, highlight, watermarked_image_path, highlight_path = add_and_detect_watermark_image(image, text)
|
| 21 |
+
return watermarked_image, highlight, watermarked_image_path, highlight_path
|
| 22 |
+
|
| 23 |
+
image_interface = gr.Interface(
|
| 24 |
+
fn=process_image,
|
| 25 |
+
inputs=image_inputs,
|
| 26 |
+
outputs=image_outputs,
|
| 27 |
+
title="Image Watermark Application",
|
| 28 |
+
description="Upload an image and add a watermark text. Detect watermark and highlight its position."
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
# Video Interface
|
| 32 |
+
video_inputs = [
|
| 33 |
+
gr.Video(label="Upload Video"),
|
| 34 |
+
gr.Textbox(label="Watermark Text")
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
video_outputs = [
|
| 38 |
+
gr.Video(label="Watermarked Video"),
|
| 39 |
+
gr.Video(label="Watermark Highlight"),
|
| 40 |
+
gr.File(label="Download Watermarked Video"),
|
| 41 |
+
gr.File(label="Download Watermark Highlight")
|
| 42 |
+
]
|
| 43 |
+
|
| 44 |
+
def process_video(video, text):
|
| 45 |
+
watermarked_video_path, highlight_video_path, _, _ = add_and_detect_watermark_video(video, text)
|
| 46 |
+
return watermarked_video_path, highlight_video_path, watermarked_video_path, highlight_video_path
|
| 47 |
+
|
| 48 |
+
video_interface = gr.Interface(
|
| 49 |
+
fn=process_video,
|
| 50 |
+
inputs=video_inputs,
|
| 51 |
+
outputs=video_outputs,
|
| 52 |
+
title="Video Watermark Application",
|
| 53 |
+
description="Upload a video and add a watermark text. Detect watermark and highlight its position."
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
# Forensic Watermark Detection Interface
|
| 57 |
+
detect_inputs = [
|
| 58 |
+
gr.Image(type="numpy", label="Upload Image")
|
| 59 |
+
]
|
| 60 |
+
|
| 61 |
+
detect_outputs = [
|
| 62 |
+
gr.Image(type="numpy", label="Watermark Detection Result")
|
| 63 |
+
]
|
| 64 |
+
|
| 65 |
+
detect_interface = gr.Interface(
|
| 66 |
+
fn=detect_watermark_image,
|
| 67 |
+
inputs=detect_inputs,
|
| 68 |
+
outputs=detect_outputs,
|
| 69 |
+
title="Forensic Watermark Detection",
|
| 70 |
+
description="Upload an image to detect forensic watermarks."
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
# Combine interfaces in tabs
|
| 74 |
+
app = gr.TabbedInterface(
|
| 75 |
+
interface_list=[image_interface, video_interface, detect_interface],
|
| 76 |
+
tab_names=["Image", "Video", "Detect"]
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
if __name__ == "__main__":
|
| 80 |
+
app.launch()
|
detect.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import numpy as np
|
| 3 |
+
|
| 4 |
+
def detect_watermark_image(image):
|
| 5 |
+
ycrcb_image = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
|
| 6 |
+
y_channel, _, _ = cv2.split(ycrcb_image)
|
| 7 |
+
dct_y = cv2.dct(np.float32(y_channel))
|
| 8 |
+
|
| 9 |
+
# Detecting the watermark
|
| 10 |
+
watermark = np.zeros_like(dct_y)
|
| 11 |
+
rows, cols = dct_y.shape
|
| 12 |
+
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 13 |
+
text = "WATERMARK"
|
| 14 |
+
text_size = cv2.getTextSize(text, font, 0.5, 1)[0]
|
| 15 |
+
text_x = np.random.randint(0, cols - text_size[0])
|
| 16 |
+
text_y = np.random.randint(text_size[1], rows)
|
| 17 |
+
watermark = cv2.putText(watermark, text, (text_x, text_y), font, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
| 18 |
+
|
| 19 |
+
detected_image = cv2.idct(dct_y + watermark)
|
| 20 |
+
detected_image = np.uint8(np.clip(detected_image, 0, 255))
|
| 21 |
+
|
| 22 |
+
return detected_image
|
image.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import numpy as np
|
| 3 |
+
import random
|
| 4 |
+
import tempfile
|
| 5 |
+
from utils import resize_image, text_to_image
|
| 6 |
+
|
| 7 |
+
def add_and_detect_watermark_image(image, watermark_text, num_watermarks=5):
|
| 8 |
+
watermark_positions = []
|
| 9 |
+
|
| 10 |
+
h, w, _ = image.shape
|
| 11 |
+
h_new = (h // 8) * 8
|
| 12 |
+
w_new = (w // 8) * 8
|
| 13 |
+
image_resized = cv2.resize(image, (w_new, h_new))
|
| 14 |
+
|
| 15 |
+
ycrcb_image = cv2.cvtColor(image_resized, cv2.COLOR_BGR2YCrCb)
|
| 16 |
+
y_channel, cr_channel, cb_channel = cv2.split(ycrcb_image)
|
| 17 |
+
|
| 18 |
+
dct_y = cv2.dct(np.float32(y_channel))
|
| 19 |
+
|
| 20 |
+
rows, cols = dct_y.shape
|
| 21 |
+
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 22 |
+
for _ in range(num_watermarks):
|
| 23 |
+
text_size = cv2.getTextSize(watermark_text, font, 0.5, 1)[0]
|
| 24 |
+
text_x = random.randint(0, cols - text_size[0])
|
| 25 |
+
text_y = random.randint(text_size[1], rows)
|
| 26 |
+
watermark = np.zeros_like(dct_y)
|
| 27 |
+
watermark = cv2.putText(watermark, watermark_text, (text_x, text_y), font, 0.5, (1, 1, 1), 1, cv2.LINE_AA)
|
| 28 |
+
dct_y += watermark * 0.01
|
| 29 |
+
watermark_positions.append((text_x, text_y, text_size[0], text_size[1]))
|
| 30 |
+
|
| 31 |
+
idct_y = cv2.idct(dct_y)
|
| 32 |
+
|
| 33 |
+
ycrcb_image[:, :, 0] = idct_y
|
| 34 |
+
watermarked_image = cv2.cvtColor(ycrcb_image, cv2.COLOR_YCrCb2BGR)
|
| 35 |
+
|
| 36 |
+
watermark_highlight = watermarked_image.copy()
|
| 37 |
+
for (text_x, text_y, text_w, text_h) in watermark_positions:
|
| 38 |
+
cv2.putText(watermark_highlight, watermark_text, (text_x, text_y), font, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
| 39 |
+
cv2.rectangle(watermark_highlight, (text_x, text_y - text_h), (text_x + text_w, text_y), (0, 0, 255), 2)
|
| 40 |
+
|
| 41 |
+
# Save watermarked image and highlight to temporary files
|
| 42 |
+
_, watermarked_image_path = tempfile.mkstemp(suffix=".png")
|
| 43 |
+
_, watermark_highlight_path = tempfile.mkstemp(suffix=".png")
|
| 44 |
+
cv2.imwrite(watermarked_image_path, watermarked_image)
|
| 45 |
+
cv2.imwrite(watermark_highlight_path, watermark_highlight)
|
| 46 |
+
|
| 47 |
+
return watermarked_image, watermark_highlight, watermarked_image_path, watermark_highlight_path
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
numpy
|
| 3 |
+
opencv-python
|
| 4 |
+
moviepy
|
utils.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import cv2
|
| 3 |
+
|
| 4 |
+
def resize_image(img, shape):
|
| 5 |
+
return cv2.resize(img, (shape[1], shape[0]), interpolation=cv2.INTER_LINEAR)
|
| 6 |
+
|
| 7 |
+
def text_to_image(text, img_shape, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=3, thickness=5):
|
| 8 |
+
text_size = cv2.getTextSize(text, font, font_scale, thickness)[0]
|
| 9 |
+
text_x = (img_shape[1] - text_size[0]) // 2
|
| 10 |
+
text_y = (img_shape[0] + text_size[1]) // 2
|
| 11 |
+
|
| 12 |
+
img_wm = np.zeros(img_shape, dtype=np.uint8)
|
| 13 |
+
cv2.putText(img_wm, text, (text_x, text_y), font, font_scale, (255, 255, 255), thickness)
|
| 14 |
+
|
| 15 |
+
return img_wm
|
video.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import numpy as np
|
| 3 |
+
import random
|
| 4 |
+
import tempfile
|
| 5 |
+
from moviepy.editor import VideoFileClip
|
| 6 |
+
from utils import resize_image, text_to_image
|
| 7 |
+
|
| 8 |
+
def add_and_detect_watermark_video(video_path, watermark_text, num_watermarks=5):
|
| 9 |
+
def add_watermark_to_frame(frame):
|
| 10 |
+
watermark_positions = []
|
| 11 |
+
|
| 12 |
+
h, w, _ = frame.shape
|
| 13 |
+
h_new = (h // 8) * 8
|
| 14 |
+
w_new = (w // 8) * 8
|
| 15 |
+
frame_resized = cv2.resize(frame, (w_new, h_new))
|
| 16 |
+
|
| 17 |
+
ycrcb_image = cv2.cvtColor(frame_resized, cv2.COLOR_BGR2YCrCb)
|
| 18 |
+
y_channel, cr_channel, cb_channel = cv2.split(ycrcb_image)
|
| 19 |
+
|
| 20 |
+
dct_y = cv2.dct(np.float32(y_channel))
|
| 21 |
+
|
| 22 |
+
rows, cols = dct_y.shape
|
| 23 |
+
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 24 |
+
for _ in range(num_watermarks):
|
| 25 |
+
text_size = cv2.getTextSize(watermark_text, font, 0.5, 1)[0]
|
| 26 |
+
text_x = random.randint(0, cols - text_size[0])
|
| 27 |
+
text_y = random.randint(text_size[1], rows)
|
| 28 |
+
watermark = np.zeros_like(dct_y)
|
| 29 |
+
watermark = cv2.putText(watermark, watermark_text, (text_x, text_y), font, 0.5, (1, 1, 1), 1, cv2.LINE_AA)
|
| 30 |
+
dct_y += watermark * 0.01
|
| 31 |
+
watermark_positions.append((text_x, text_y, text_size[0], text_size[1]))
|
| 32 |
+
|
| 33 |
+
idct_y = cv2.idct(dct_y)
|
| 34 |
+
|
| 35 |
+
ycrcb_image[:, :, 0] = idct_y
|
| 36 |
+
watermarked_frame = cv2.cvtColor(ycrcb_image, cv2.COLOR_YCrCb2BGR)
|
| 37 |
+
|
| 38 |
+
watermark_highlight = watermarked_frame.copy()
|
| 39 |
+
for (text_x, text_y, text_w, text_h) in watermark_positions:
|
| 40 |
+
cv2.putText(watermark_highlight, watermark_text, (text_x, text_y), font, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
| 41 |
+
cv2.rectangle(watermark_highlight, (text_x, text_y - text_h), (text_x + text_w, text_y), (0, 0, 255), 2)
|
| 42 |
+
|
| 43 |
+
return watermarked_frame, watermark_highlight
|
| 44 |
+
|
| 45 |
+
video = VideoFileClip(video_path)
|
| 46 |
+
video_with_watermark = video.fl_image(lambda frame: add_watermark_to_frame(frame)[0])
|
| 47 |
+
video_with_highlight = video.fl_image(lambda frame: add_watermark_to_frame(frame)[1])
|
| 48 |
+
|
| 49 |
+
temp_fd, watermarked_video_path = tempfile.mkstemp(suffix=".mp4")
|
| 50 |
+
temp_fd_highlight, highlight_video_path = tempfile.mkstemp(suffix=".mp4")
|
| 51 |
+
|
| 52 |
+
video_with_watermark.write_videofile(watermarked_video_path, codec='libx264')
|
| 53 |
+
video_with_highlight.write_videofile(highlight_video_path, codec='libx264')
|
| 54 |
+
|
| 55 |
+
return watermarked_video_path, highlight_video_path, watermarked_video_path, highlight_video_path
|