Skip to content

Commit

Permalink
ignore pyc files
Browse files Browse the repository at this point in the history
  • Loading branch information
naaci committed Apr 26, 2023
0 parents commit 67802e2
Show file tree
Hide file tree
Showing 70 changed files with 1,403 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pyc
34 changes: 34 additions & 0 deletions Ambadekar2019.py
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')
36 changes: 36 additions & 0 deletions Chandra2002.py
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
66 changes: 66 additions & 0 deletions Chang2005.py
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
48 changes: 48 additions & 0 deletions Ganic2004.py
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),
)
51 changes: 51 additions & 0 deletions Guo2014.py
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

29 changes: 29 additions & 0 deletions Gupta2012.py
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
29 changes: 29 additions & 0 deletions Jain2008.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Jain, C., Arora, S., &#38; 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
30 changes: 30 additions & 0 deletions Jane2014.py
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)
52 changes: 52 additions & 0 deletions Lai2010.py
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
Loading

0 comments on commit 67802e2

Please sign in to comment.