def SVD_embed(im, wm, strength, blk_size): U, S, V = block_SVD(im, blk_size) S_new = embed(S, wm, strength) im_wm = block_ISVD(U, S_new, V, blk_size) return im_wm def SVD_extract(im_wm, im, strength, block_size): _, S, _ = block_SVD(im, block_size) _, S_wm, _ = block_SVD(im_wm, block_size) tmp = S_wm - S wm_ex = np.empty_like(tmp, dtype=int) for i in range(tmp.shape[0]): for j in range(tmp.shape[1]): wm_ex[i, j] = np.sum(tmp[i, j]) wm_ex = wm_ex / block_size[0] / strength return wm_ex def embed(S, wm, strength): wm = wm.flatten() row, col = S.shape S = S.flatten() for i in range(S.size): S[i] = S[i] + strength * wm[i] S = S.reshape(row, col) return S这段代码什么意思
时间: 2023-12-04 15:06:27 浏览: 109
这段代码实现了基于SVD的数字水印嵌入和提取算法。具体来说,它包括以下两个函数:
- SVD_embed(im, wm, strength, blk_size): 该函数输入原始图像im,数字水印wm,嵌入强度strength和块大小blk_size,输出嵌入数字水印后的图像im_wm。
- SVD_extract(im_wm, im, strength, block_size): 该函数输入嵌有数字水印的图像im_wm,原始图像im,嵌入强度strength和块大小block_size,输出提取出的数字水印wm_ex。
具体来说,SVD_embed函数首先将原始图像im分成大小为blk_size的块,对每个块进行SVD分解,并将数字水印嵌入到分解后的S矩阵中。然后通过逆SVD变换,将嵌有数字水印的块合并成嵌入数字水印后的图像im_wm。
SVD_extract函数则是将原始图像im和嵌有数字水印的图像im_wm都分成大小为block_size的块,对每个块进行SVD分解,计算出嵌有数字水印的块和原始块的S矩阵之差,并将差值除以块大小和嵌入强度得到数字水印。最后将数字水印wm_ex返回。
相关问题
def block_SVD(M, blk_size): row_block = M.shape[0] // blk_size[0] col_block = M.shape[1] // blk_size[1] U = np.empty((row_block, col_block), dtype=object) S = np.empty((row_block, col_block), dtype=object) V = np.empty((row_block, col_block), dtype=object) M = M[:M.shape[0] - M.shape[0] % blk_size[0], :M.shape[1] - M.shape[1] % blk_size[1]] rows = [] for i in range(0, M.shape[0], blk_size[0]): cols = [] for j in range(0, M.shape[1], blk_size[1]): max_ndx = (min(i + blk_size[0], M.shape[0]), min(j + blk_size[1], M.shape[1])) u, s, v = np.linalg.svd(M[i:max_ndx[0], j:max_ndx[1]]) U[i // blk_size[0], j // blk_size[1]] = u S[i // blk_size[0], j // blk_size[1]] = s V[i // blk_size[0], j // blk_size[1]] = v return U, S, V def block_ISVD(U, S, V, blk_size): row_U, col_U = U.shape U = U.flatten() S = S.flatten() V = V.flatten() im_tmp = np.empty_like(U) im_wm = np.empty((row_U*blk_size[0],col_U*blk_size[1])) for i in range(U.size): tmp = np.matmul(U[i],np.diag(S[i])) im_tmp[i] = np.matmul(tmp,V[i]) im_tmp = im_tmp.reshape(row_U, col_U) for i in range(row_U): for j in range(col_U): im_wm[i*blk_size[0]:(i+1)*blk_size[0], j*blk_size[1]:(j+1)*blk_size[1]] = im_tmp[i,j] return im_wm 这段代码什么意思
这段代码实现了基于块的 SVD(奇异值分解)和逆 SVD 操作。具体地,它分为两个函数:
1. block_SVD(M, blk_size):输入一个矩阵 M 和一个块大小 blk_size,输出 M 的基于块的 SVD 分解结果,包括 U、S、V 三个矩阵。其中 U 和 V 是正交矩阵,S 是对角线上的奇异值向量。
2. block_ISVD(U, S, V, blk_size):输入基于块的 SVD 分解结果 U、S、V 和块大小 blk_size,输出原始矩阵 M。这个函数实际上是对 U、S、V 分别进行逆 SVD 操作,然后将结果拼接成原始矩阵 M。
整个过程中,矩阵 M 被分成多个大小为 blk_size 的块,每个块分别进行 SVD 分解和逆 SVD 操作,最终得到整个矩阵的 SVD 分解结果和原始矩阵。这种基于块的 SVD 分解和逆 SVD 操作可以在处理大型矩阵时提高计算效率,并且适用于分布式计算环境。
阅读全文