-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 67802e2
Showing
70 changed files
with
1,403 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
""" | ||
Ambadekar, S. P., Jain, J., & Khanapuri, J. (2019). | ||
Digital Image Watermarking Through Encryption and DWT for Copyright Protection. | ||
In Advances in Intelligent Systems and Computing (Vol. 727, pp. 187–195). Springer Singapore. | ||
https://doi.org/10.1007/978-981-10-8863-6_19""" | ||
|
||
from pywt import dwt2, idwt2 | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 1 | ||
|
||
def __init__(self, scale_factor=2**-6) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
self.LL, (self.HL, self.LH, self.HH) = dwt2(host, wavelet='haar') | ||
LL_w, (HL_w, LH_w, HH_w) = dwt2(watermark, wavelet='haar') | ||
|
||
LL_ = self.LL*(1-self.sf) + LL_w*self.sf | ||
HL_ = self.HL*(1-self.sf) + HL_w*self.sf | ||
LH_ = self.LH*(1-self.sf) + LH_w*self.sf | ||
HH_ = self.HH*(1-self.sf) + HH_w*self.sf | ||
|
||
return idwt2((LL_, (HL_, LH_, HH_)), wavelet='haar') | ||
|
||
def extract_watermark(self, watermarked_image): | ||
LL_, (HL_, LH_, HH_) = dwt2(watermarked_image, wavelet='haar') | ||
return idwt2(( | ||
(LL_-self.LL*(1-self.sf))/self.sf, | ||
((HL_-self.HL*(1-self.sf))/self.sf, | ||
(LH_-self.LH*(1-self.sf))/self.sf, | ||
(HH_-self.HH*(1-self.sf))/self.sf,), | ||
), wavelet='haar') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
""" | ||
Chandra, D. V. S. (2010). | ||
Digital image watermarking using singular value decomposition. | ||
The 2002 45th Midwest Symposium on Circuits and Systems, 2002. MWSCAS-2002., 3(3), III-264-III–267. | ||
https://doi.org/10.1109/MWSCAS.2002.1187023 | ||
""" | ||
|
||
# from numpy.linalg import svd | ||
from scipy.linalg import svd, diagsvd | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 1 | ||
|
||
def __init__(self, scale_factor=2**(-4)) -> None: | ||
"""Initiates watermarker object | ||
Args: | ||
scale_factor (float or array of floats, optional): | ||
Simple Scale Factor if the scale_factor is a float . | ||
Multiple Scale Factor if the scale_factor is an array of length k, | ||
where k is the number of singular values. | ||
Defaults to 2**(-4) | ||
""" | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
U, self.s, Vh = svd(host, full_matrices=True) | ||
self.U_w, s_w, self.Vh_w = svd(watermark, full_matrices=True) | ||
s = self.s + self.sf * s_w | ||
return U @ diagsvd(s, *watermark.shape) @ Vh | ||
|
||
def extract_watermark(self, watermarked): | ||
s = svd(watermarked, compute_uv=False) | ||
s_w = (s - self.s) / self.sf | ||
return self.U_w @ diagsvd(s_w, *watermarked.shape) @ self.Vh_w |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
""" | ||
Chang, C. C., Tsai, P., & Lin, C. C. (2005). | ||
SVD-based digital image watermarking scheme. | ||
Pattern Recognition Letters, 26(10), 1577–1586. | ||
https://doi.org/10.1016/j.patrec.2005.01.004 | ||
""" | ||
|
||
from numpy import abs, angle, empty, empty_like, exp, sign | ||
from numpy.linalg import svd | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 4 | ||
|
||
def __init__(self, scale_factor=.012) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host_image, watermark_image): | ||
self.R1 = host_image.shape[0] // watermark_image.shape[0] | ||
self.R2 = host_image.shape[1] // watermark_image.shape[1] | ||
|
||
watermarked = empty_like(host_image) | ||
for i in range(0, watermark_image.shape[0]): | ||
for j in range(0, watermark_image.shape[1]): | ||
U, s, Vh = svd(host_image[i * self.R1:(i + 1) * self.R1, | ||
j * self.R2:(j + 1) * self.R2], | ||
full_matrices=False) | ||
# complexity = s[s != 0].size / s.size | ||
|
||
m = (abs(U[1, 0]) + abs(U[2, 0])) / 2 | ||
d = abs(U[1, 0]) - abs(U[2, 0]) | ||
|
||
if watermark_image[i, j] < .5: | ||
if d < self.sf: | ||
U[1, 0] = (m + self.sf / 2)*exp(angle(U[1, 0])*1j) | ||
U[2, 0] = (m - self.sf / 2)*exp(angle(U[2, 0])*1j) | ||
|
||
else: | ||
if -d < self.sf: | ||
U[1, 0] = (m - self.sf / 2)*exp(angle(U[1, 0])*1j) | ||
U[2, 0] = (m + self.sf / 2)*exp(angle(U[2, 0])*1j) | ||
|
||
watermarked[i * self.R1:(i + 1) * self.R1, | ||
j * self.R2:(j + 1) * self.R2] = (U * s) @ Vh | ||
|
||
return watermarked | ||
|
||
def extract_watermark(self, watermarked_image): | ||
R = self.IMAGE_TO_WATERMARK_RATIO | ||
watermark = empty(shape=(watermarked_image.shape[0] // R, | ||
watermarked_image.shape[1] // R)) | ||
for i in range(0, watermark.shape[0]): | ||
for j in range(0, watermark.shape[1]): | ||
U, s, Vh = svd( | ||
watermarked_image[i * self.R1:(i + 1) * self.R1, | ||
j * self.R2:(j + 1) * self.R2]) | ||
# complexity = s[s != 0].size / s.size | ||
|
||
positive = abs(U[2, 0]) - abs(U[1, 0]) >= self.sf / 2 | ||
|
||
# negative = abs(U[1, 0]) - abs(U[2, 0]) >= self.sf / 2 | ||
# assert positive or negative | ||
|
||
watermark[i, j] = positive | ||
|
||
return watermark |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
""" | ||
Ganic, E., & Eskicioglu, A. M. (2004). | ||
Robust DWT-SVD domain image watermarking. | ||
In Proceedings of the 2004 multimedia and security workshop on Multimedia and security - MM&Sec ’04 (p. 166). New York, New York, USA: ACM Press. | ||
https://doi.org/10.1145/1022431.1022461 | ||
""" | ||
|
||
from pywt import dwt2, idwt2 | ||
|
||
from Chandra2002 import Watermarker as chandraWatermarker | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 2 | ||
|
||
def __init__(self, scale_factor=.05) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
LL, (HL, LH, HH) = dwt2(host, wavelet='haar') | ||
|
||
self.svd_watermarker_1 = chandraWatermarker(self.sf) | ||
self.svd_watermarker_2 = chandraWatermarker(self.sf / 50) | ||
self.svd_watermarker_3 = chandraWatermarker(self.sf / 50) | ||
self.svd_watermarker_4 = chandraWatermarker(self.sf / 50) | ||
|
||
LL_ = self.svd_watermarker_1.add_watermark(LL, watermark) | ||
HL_ = self.svd_watermarker_2.add_watermark(HL, watermark) | ||
LH_ = self.svd_watermarker_3.add_watermark(LH, watermark) | ||
HH_ = self.svd_watermarker_4.add_watermark(HH, watermark) | ||
|
||
return idwt2((LL_, (HL_, LH_, HH_)), wavelet='haar') | ||
|
||
def extract_watermark(self, watermarked_image): | ||
LL, (HL, LH, HH) = dwt2(watermarked_image, wavelet='haar') | ||
return self.svd_watermarker_1.extract_watermark(LL) | ||
return self.svd_watermarker_2.extract_watermark(HL) | ||
return self.svd_watermarker_3.extract_watermark(LH) | ||
return self.svd_watermarker_4.extract_watermark(HH) | ||
|
||
def extract_watermarks(self, watermarked_image): | ||
LL, (HL, LH, HH) = dwt2(watermarked_image, wavelet='haar') | ||
return ( | ||
self.svd_watermarker_1.extract_watermark(LL), | ||
self.svd_watermarker_2.extract_watermark(HL), | ||
self.svd_watermarker_3.extract_watermark(LH), | ||
self.svd_watermarker_4.extract_watermark(HH), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
""" | ||
Guo, J.-M. M., & Prasetyo, H. (2014). | ||
False-positive-free SVD-based image watermarking. | ||
Journal of Visual Communication and Image Representation, 25(5), 1149–1163. | ||
https://doi.org/10.1016/j.jvcir.2014.03.012 | ||
""" | ||
|
||
from numpy import empty, empty_like | ||
from scipy.linalg import diagsvd, svd | ||
# from numpy.linalg import svd | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 4 | ||
|
||
def __init__(self, scale_factor=.01) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host_image, watermark_image): | ||
R = host_image.shape[0] // watermark_image.shape[0] | ||
# R = host_image.shape[1] // watermark_image.shape[1] | ||
|
||
U_w, s_w, self.Vh_w = svd(watermark_image, full_matrices=True) | ||
P_w = U_w @ diagsvd(s_w, *watermark_image.shape) | ||
|
||
watermarked = empty_like(host_image) | ||
self.s = empty_like(watermark_image) | ||
for i in range(0, watermark_image.shape[0]): | ||
for j in range(0, watermark_image.shape[1]): | ||
U, s, Vh = svd(host_image[i * R:(i + 1) * R, | ||
j * R:(j + 1) * R], | ||
full_matrices=False) | ||
self.s[i, j] = s[0] | ||
s[0] += self.sf * P_w[i, j] | ||
watermarked[i * R:(i + 1) * R, | ||
j * R:(j + 1) * R] = (U * s) @ Vh | ||
|
||
return watermarked | ||
|
||
def extract_watermark(self, watermarked_image): | ||
R = self.IMAGE_TO_WATERMARK_RATIO | ||
P_w = empty(shape=(watermarked_image.shape[0] // R, | ||
watermarked_image.shape[1] // R)) | ||
for i in range(0, P_w.shape[0]): | ||
for j in range(0, P_w.shape[1]): | ||
s = svd(watermarked_image[i * R:(i + 1) * R, | ||
j * R:(j + 1) * R], | ||
compute_uv=False) | ||
P_w[i, j] = (s[0] - self.s[i, j]) / self.sf | ||
return P_w @ self.Vh_w | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
""" | ||
Lagzian, S., Soryani, M., & Fathy, M. (2011). | ||
A New Robust Watermarking Scheme Based on RDWT-SVD. | ||
International Journal of Intelligent Information Processing, 2(1), 22–29. | ||
https://doi.org/10.4156/ijiip.vol2.issue1.3 | ||
""" | ||
|
||
# from numpy.linalg import svd | ||
from scipy.linalg import diagsvd, svd | ||
from pywt import dwt2, idwt2 | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 2 | ||
|
||
def __init__(self, scale_factor=.02) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
LL, H = dwt2(host, wavelet='haar') | ||
self.U, s, self.Vh = svd(LL, full_matrices=False) | ||
self.U_w, s_w, self.Vh_w = svd(watermark, full_matrices=False) | ||
LL_ = self.U * s_w @ self.Vh | ||
return idwt2((LL_, H), wavelet='haar') | ||
|
||
def extract_watermark(self, watermarked_image): | ||
LL, H = dwt2(watermarked_image, wavelet='haar') | ||
s_w_ = svd(LL, compute_uv=False) | ||
return self.U_w * s_w_ @ self.Vh_w |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
""" | ||
Jain, C., Arora, S., & Panigrahi, P. K. (2008). | ||
A Reliable SVD based Watermarking Schem. May 2018, 1–8. | ||
preprint | ||
http://arxiv.org/abs/0808.0309 | ||
""" | ||
|
||
# from numpy.linalg import svd | ||
from scipy.linalg import diagsvd, svd | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 1 | ||
|
||
def __init__(self, scale_factor=.02) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
self.host = host | ||
w, h = host.shape | ||
self.U, s, self.Vh = svd(self.host, full_matrices=True) | ||
U_w, s_w, self.Vh_w = svd(watermark, full_matrices=True) | ||
P_w = U_w @ diagsvd(s_w, *watermark.shape) | ||
D = diagsvd(s, w, h) + self.sf * P_w | ||
return self.U @ D @ self.Vh | ||
|
||
def extract_watermark(self, watermarked): | ||
D = watermarked - self.host | ||
return (self.U.T.conj() @ D @ self.Vh.T.conj()) / self.sf @ self.Vh_w |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
""" | ||
Jane, O., Elbaşi, E., & İlk, H. G. (2014). | ||
Hybrid Non-Blind Watermarking Based on DWT and SVD. | ||
Journal of Applied Research and Technology, 12(4), 750–761. | ||
https://doi.org/10.1016/S1665-6423(14)70091-4 | ||
""" | ||
|
||
from pywt import dwt2, idwt2 | ||
|
||
from Liu2002 import Watermarker as Liu2002Watermarker | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 2 | ||
|
||
def __init__(self, scale_factor=.05) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
self.svd_watermarker = Liu2002Watermarker(self.sf) | ||
|
||
LL, (HL, LH, HH) = dwt2(host, wavelet='haar') | ||
|
||
LL_ = self.svd_watermarker.add_watermark(LL, watermark) | ||
|
||
return idwt2((LL_, (HL, LH, HH)), wavelet='haar') | ||
|
||
def extract_watermark(self, watermarked_image): | ||
LL, (HL, LH, HH) = dwt2(watermarked_image, wavelet='haar') | ||
return self.svd_watermarker.extract_watermark(LL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"""Lai, C.-C., & Tsai, C.-C. (2010). | ||
Digital Image Watermarking Using Discrete Wavelet Transform and Singular Value Decomposition. | ||
IEEE Transactions on Instrumentation and Measurement, 59(11), 3060–3063. | ||
https://doi.org/10.1109/TIM.2010.2066770 | ||
""" | ||
|
||
from pywt import dwt2, idwt2 | ||
|
||
from Liu2002 import Watermarker as Liu2002Watermarker | ||
|
||
|
||
class Watermarker: | ||
IMAGE_TO_WATERMARK_RATIO = 2 | ||
|
||
def __init__(self, scale_factor=.01) -> None: | ||
self.sf = scale_factor | ||
|
||
def add_watermark(self, host, watermark): | ||
# 1) Use one-level Haar DWT to decompose the cover imageAinto four subbands (i.e., LL, LH, HL, and HH). | ||
LL, (HL, LH, HH) = dwt2(host, wavelet='haar') | ||
|
||
# 2) Apply SVD to LH and HL subbands, i.e.,Ak=UkSkVkT,k=1,2(1)wherekrepresents one of two subbands. | ||
self.svd_watermarker_1 = Liu2002Watermarker(self.sf) | ||
self.svd_watermarker_2 = Liu2002Watermarker(self.sf) | ||
|
||
# 3) Divide the watermark into two parts: W=W_1+W_2,where W_k denotes half of the watermark. | ||
watermark_1 = watermark.copy() | ||
watermark_1[watermark > watermark.mean()] = 0 | ||
watermark_2 = watermark - watermark_1 | ||
|
||
# 4) Modify the singular values in HL and LH subbands with half of the watermark image and then apply SVD to them,respectively, | ||
# 5) Obtain the two sets of modified DWT coefficients, i.e.,A∗k=UkSkWVkT,k=1,2.(3) | ||
LH_ = self.svd_watermarker_1.add_watermark(LH, watermark_1) | ||
HL_ = self.svd_watermarker_2.add_watermark(HL, watermark_2) | ||
|
||
# 6) Obtain the watermarked imageAWby performing the in-verse DWT using two sets of modified DWT coefficients andtwo sets of nonmodified DWT coefficients. | ||
|
||
return idwt2((LL, (HL_, LH_, HH)), wavelet='haar') | ||
|
||
def extract_watermark(self, watermarked_image): | ||
# 1) Use one-level Haar DWT to decompose the watermarked(possibly distorted) imageA∗Winto four subbands: LL, LH,HL, and HH. | ||
LL, (HL_, LH_, HH) = dwt2(watermarked_image, wavelet='haar') | ||
|
||
# 2) Apply SVD to the LH and HL subbands, i.e.,A∗kW=U∗kS∗kWV∗kT,k=1,2(4)wherekrepresents one of two subbands. | ||
# 3) Compute D∗k=UkWS∗kWVkTW,k=1,2. | ||
# 4) Extract half of the watermark image from each subband, i.e.,W∗k=(D∗k−Sk)/α,k=1,2.(5) | ||
|
||
watermark_image_1 = self.svd_watermarker_1.extract_watermark(LH_) | ||
watermark_image_2 = self.svd_watermarker_2.extract_watermark(HL_) | ||
|
||
# 5) Combine the results of Step 4 to obtain the embedded water-mark:W∗=W∗1+W∗2. | ||
return watermark_image_1 + watermark_image_2 |
Oops, something went wrong.