-
-
Notifications
You must be signed in to change notification settings - Fork 721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why need shuffle before SVD operation? Fast mode does not works for white images #78
Comments
I met the problem too |
我觉得可以加掩码来解决这个问题 |
def extract_raw(self, img):
# 每个分块提取 1 bit 信息
self.read_img_arr(img=img)
self.init_block_index()
wm_block_bit = np.zeros(shape=(3, self.block_num)) # 3个channel,length 个分块提取的水印,全都记录下来
self.idx_shuffle = random_strategy1(seed=self.password_img,
size=self.block_num,
block_shape=self.block_shape[0] * self.block_shape[1], # 16
)
for channel in range(3):
wm_block_bit[channel, :] = self.pool.map(self.block_get_wm,
[(self.ca_block[channel][self.block_index[i]], self.idx_shuffle[i])
for i in range(self.block_num)])
return wm_block_bit
def extract_avg(self, wm_block_bit):
# 对循环嵌入+3个 channel 求平均
wm_avg = np.zeros(shape=self.wm_size)
for i in range(self.wm_size):
wm_avg[i] = wm_block_bit[:, i::self.wm_size].mean()
return wm_avg
def extract(self, img, wm_shape):
self.wm_size = np.array(wm_shape).prod()
# 提取每个分块埋入的 bit:
wm_block_bit = self.extract_raw(img=img)
# 做平均:
wm_avg = self.extract_avg(wm_block_bit)
return wm_avg
def extract_with_kmeans(self, img, wm_shape):
wm_avg = self.extract(img=img, wm_shape=wm_shape)
return one_dim_kmeans(wm_avg)
def one_dim_kmeans(inputs):
threshold = 0
e_tol = 10 ** (-6)
center = [inputs.min(), inputs.max()] # 1. 初始化中心点
for i in range(300):
threshold = (center[0] + center[1]) / 2
is_class01 = inputs > threshold # 2. 检查所有点与这k个点之间的距离,每个点归类到最近的中心
center = [inputs[~is_class01].mean(), inputs[is_class01].mean()] # 3. 重新找中心点
if np.abs((center[0] + center[1]) / 2 - threshold) < e_tol: # 4. 停止条件
threshold = (center[0] + center[1]) / 2
break
is_class01 = inputs > threshold
return is_class01 |
my code with mask: import numpy as np
from blind_watermark import WaterMark # '0.4.1'
import hashlib
mask = bytearray()
m = hashlib.sha256()
m.update(b"1145141919810")
for i in range(1024 // 32):
mask.extend(m.digest())
m.update(m.digest())
def bitstring_to_bytes(s):
v = int(s, 2)
b = bytearray()
while v:
b.append(v & 0xff)
v >>= 8
return b[::-1]
# 1057226 - 1024 * 1032 = 458
with open("a.docx", "rb") as f:
data = f.read()
print(len(data))
i = 0
while True:
bwm1 = WaterMark(password_img=1, password_wm=1)
bwm1.bwm_core.fast_mode = True
bwm1.bwm_core.d1 = 72
bwm1.read_img('6b7858c3798b5d0d1afb9f67bf43e2d5.jpg')
kk = data[i * 1024:i * 1024 + 1024]
if i == 1032:
kk = data[i * 1024:i * 1024 + 458]
kk = bytearray(kk)
for k in range(len(kk)):
kk[k] ^= mask[k]
print(kk)
byte = bin(int(kk.hex(), base=16))
wm = np.array(list(byte)) == '1'
bwm1.read_wm(wm, mode='bit')
bwm1.embed('embedded-{}.jpg'.format(i))
len_wm = len(bwm1.wm_bit)
print({i: len_wm})
wm_extract = bwm1.extract('embedded-{}.jpg'.format(i), mode='bit', wm_shape=len_wm)
wm_extract = bitstring_to_bytes("".join(["1" if x else "0" for x in wm_extract]))
print(wm_extract)
for j in range(len(kk)):
if kk[j] != wm_extract[j]:
print(j)
print()
i += 1
if i == 1033:
break output:
|
Closed
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I am curious why u shuffled DCT block before the SVD operation, what's the meaning of that ? For safty? And I found that the fast mode doest works for pure white image . Thank you so much for your time.
Best,
Weizhou
The text was updated successfully, but these errors were encountered: