Skip to content

Commit fdf091c

Browse files
committed
Add watermark removal project (not finished)
1 parent 1adeca2 commit fdf091c

File tree

9 files changed

+528
-0
lines changed

9 files changed

+528
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,9 @@ dmypy.json
127127

128128
# Pyre type checker
129129
.pyre/
130+
131+
# Mac
132+
.DS_Store
133+
134+
# vscode
135+
.vscode
1.51 MB
Loading
2.58 MB
Loading

watermark_removal/images/test1.jpg

96.6 KB
Loading
216 KB
Loading

watermark_removal/images/test2.jpg

230 KB
Loading

watermark_removal/images/test3.jpg

206 KB
Loading
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
{
2+
"metadata": {
3+
"language_info": {
4+
"codemirror_mode": {
5+
"name": "ipython",
6+
"version": 3
7+
},
8+
"file_extension": ".py",
9+
"mimetype": "text/x-python",
10+
"name": "python",
11+
"nbconvert_exporter": "python",
12+
"pygments_lexer": "ipython3",
13+
"version": "3.9.2"
14+
},
15+
"orig_nbformat": 2,
16+
"kernelspec": {
17+
"name": "python392jvsc74a57bd0eafa71b4a5f824d3055ca9707dde86e6ce800dc54c56e20c6da9d851446cd008",
18+
"display_name": "Python 3.9.2 64-bit ('venv')"
19+
}
20+
},
21+
"nbformat": 4,
22+
"nbformat_minor": 2,
23+
"cells": [
24+
{
25+
"source": [
26+
"## Detect watermark \n",
27+
"\n",
28+
"*Note*: This is only for white semitransparent watermark. \n",
29+
"\n",
30+
"Find the pixels that contain a transparency "
31+
],
32+
"cell_type": "markdown",
33+
"metadata": {}
34+
},
35+
{
36+
"cell_type": "code",
37+
"execution_count": 1,
38+
"metadata": {},
39+
"outputs": [],
40+
"source": [
41+
"import cv2 as cv\n",
42+
"import numpy as np "
43+
]
44+
},
45+
{
46+
"cell_type": "code",
47+
"execution_count": 2,
48+
"metadata": {},
49+
"outputs": [],
50+
"source": [
51+
"image = \"./images/test1.jpg\"\n",
52+
"# image = \"./images/test2-nored.jpg\"\n",
53+
"# image = \"./images/test3.jpg\""
54+
]
55+
},
56+
{
57+
"cell_type": "code",
58+
"execution_count": 3,
59+
"metadata": {},
60+
"outputs": [],
61+
"source": [
62+
"watermarked = cv.imread(image)\n",
63+
"# display\n",
64+
"def display(name, img):\n",
65+
" cv.startWindowThread()\n",
66+
" cv.imshow(name, img/255)\n",
67+
" cv.waitKey(0)\n",
68+
" cv.destroyWindow(name)\n",
69+
" cv.waitKey(1)\n",
70+
"\n",
71+
"display(\"Watermarked\", watermarked)\n"
72+
]
73+
},
74+
{
75+
"cell_type": "code",
76+
"execution_count": 4,
77+
"metadata": {},
78+
"outputs": [],
79+
"source": [
80+
"# obtain the alpha mask\n",
81+
"\n",
82+
"# rectangle to identify watermark\n",
83+
"# test1 \n",
84+
"x, y, w, h = 600, 1400, 250, 35 \n",
85+
"# test2 \n",
86+
"# x, y, w, h = 580, 1480, 470, 70 \n",
87+
"# test3 \n",
88+
"# x, y, w, h = 600, 1400, 250, 35 \n",
89+
"\n",
90+
"selected = np.zeros_like(watermarked)\n",
91+
"cv.rectangle(selected, (x,y), (x+w, y+h), (255,255,255), -1)\n",
92+
"\n",
93+
"# greyscale (for darker images such as test1)\n",
94+
"watermark = cv.bitwise_and(watermarked, selected) \n",
95+
"watermark = watermark.astype(float)\n",
96+
"display(\"Selected\", watermark)\n",
97+
"grey = watermark.max(axis=-1)\n",
98+
"grey[grey>200] = 255 \n",
99+
"grey[grey!=255] = 0 \n",
100+
"display(\"Alpha mask\", grey)\n",
101+
"\n",
102+
"# for lighter images (test2 and test3)\n",
103+
"# highlighted = cv.imread(\"./images/test2.jpg\")\n",
104+
"# watermark = cv.bitwise_and(highlighted, selected) \n",
105+
"# watermark = watermark.astype(float)\n",
106+
"# display(\"Selected\", watermark)\n",
107+
"# watermark[np.where((watermark == [0,0,255]).all(axis = 2))] = [255,255,255]\n",
108+
"# watermark[np.where((watermark != [0,0,255]).all(axis = 2))] = [0,0,0]\n",
109+
"# grey = watermark.max(axis=-1)\n",
110+
"# grey[grey>0] = 255\n",
111+
"# display(\"Mask\", grey)\n",
112+
"\n",
113+
"# HSV (alternative)\n",
114+
"# hsv = cv.cvtColor(watermark, cv.COLOR_BGR2HSV)\n",
115+
"# sensitivity = 50\n",
116+
"# lower_white = np.array([0, 0, 255-sensitivity])\n",
117+
"# upper_white = np.array([255, sensitivity, 255])\n",
118+
"# hsv_mask = cv.inRange(hsv, lower_white, upper_white)\n",
119+
"# display(\"Mask\", hsv_mask)\n"
120+
]
121+
},
122+
{
123+
"cell_type": "code",
124+
"execution_count": 5,
125+
"metadata": {},
126+
"outputs": [
127+
{
128+
"output_type": "stream",
129+
"name": "stdout",
130+
"text": [
131+
"Alpha is 0.9874781183456597\n"
132+
]
133+
}
134+
],
135+
"source": [
136+
"W = grey\n",
137+
"alpha_0 = 1.1* watermark[W!=0].mean()/255 # estimate alpha \n",
138+
"alpha = np.zeros_like(W)\n",
139+
"alpha[W==255] = alpha_0\n",
140+
"print(\"Alpha is \", alpha_0)\n",
141+
"\n",
142+
"# for light images \n",
143+
"# W = grey \n",
144+
"# alpha = np.zeros_like(W)\n",
145+
"# alpha[W>0] = 1 \n",
146+
"\n",
147+
"alpha = np.repeat(alpha, 3, axis=-1).reshape(*(alpha.shape),3)\n",
148+
"W = np.repeat(W, 3, axis=-1).reshape(*(W.shape),3)"
149+
]
150+
},
151+
{
152+
"cell_type": "code",
153+
"execution_count": 6,
154+
"metadata": {},
155+
"outputs": [],
156+
"source": [
157+
"# NOT USED \n",
158+
"def blur_mask(watermarked, alpha, W):\n",
159+
" I = (watermarked.astype(float) - alpha * W)/(1-alpha)\n",
160+
" I[I<0] = 0 \n",
161+
" I[I>255] = 255 \n",
162+
" I = I.astype(uint8)\n",
163+
"\n",
164+
" fI = I.copy()\n",
165+
" fI[y:y+h, x:x+w, :] = cv.medianBlur(fI[y:y+h, x:x+w, :], 5) \n",
166+
"\n",
167+
" "
168+
]
169+
},
170+
{
171+
"cell_type": "code",
172+
"execution_count": 7,
173+
"metadata": {},
174+
"outputs": [],
175+
"source": [
176+
"def process(watermarked, alpha, W, bg, output_name=\"removed.png\"):\n",
177+
" aW = (alpha * W)\n",
178+
" # a1 = (1 / (1-alpha))\n",
179+
" med = bg \n",
180+
" watermarked = watermarked.astype(float)\n",
181+
" J = watermarked\n",
182+
"\n",
183+
" # display(\"Watermarked\", J)\n",
184+
" # display(\"aW\", aW)\n",
185+
" I = (J - aW) # * a1, but for test1, alpha is around 1\n",
186+
" # display(\"I\", I)\n",
187+
" I[I<0] = 0\n",
188+
" I[I>255] = 255 \n",
189+
" I = I.astype(np.uint8)\n",
190+
"\n",
191+
" display(\"Output\", I) \n",
192+
"\n",
193+
" # blur \n",
194+
" fI = I.copy() \n",
195+
" fI[y:y+h, x:x+w, :] = cv.medianBlur(fI[y:y+h, x:x+w, :], 7) \n",
196+
" fI[fI<0] = 0\n",
197+
" fI[fI>255] = 255 \n",
198+
"\n",
199+
" display(\"Output2\", fI)\n",
200+
" cv.imwrite(output_name, fI)"
201+
]
202+
},
203+
{
204+
"cell_type": "code",
205+
"execution_count": 8,
206+
"metadata": {},
207+
"outputs": [],
208+
"source": [
209+
"process(watermarked, alpha, W, W, \"./images/removed1.png\")"
210+
]
211+
},
212+
{
213+
"cell_type": "code",
214+
"execution_count": null,
215+
"metadata": {},
216+
"outputs": [],
217+
"source": []
218+
}
219+
]
220+
}

0 commit comments

Comments
 (0)