我正在为一个大学项目写这篇论文的代码.其思想是在灰度图像中插入一个不可见的水印,稍后可以提取该水印以验证图像的所有权.

  import pywt
import numpy as np
import  cv2
from PIL import  Image
from math import  sqrt, log10
from scipy.fftpack import dct, idct




def Get_MSB_LSB_Watermark () : #Function that separates the watermark into MSB and LSB images
    MSBs = []
    LSBs = []
    for i in range (len(Watermark)) :
            binary =  '{:0>8}'.format(str(bin(Watermark[i]))[2:])
            MSB = (binary[0:4])
            LSB = (binary[4:])
            MSB = int(MSB, 2)
            LSB = int(LSB,2)
            MSBs.append(MSB)
            LSBs.append(LSB)
    MSBs = np.array(MSBs)
    LSBs = np.array(LSBs)
    return MSBs.reshape(64,64), LSBs.reshape(64,64)



def split(array, nrows, ncols): #Split array into blocks of size nrows* ncols
    r, h = array.shape
    return (array.reshape(h//nrows, nrows, -1, ncols)
                 .swapaxes(1, 2)
                 .reshape(-1, nrows, ncols))


def unblockshaped(arr, h, w): #the inverse of the split function
    n, nrows, ncols = arr.shape
    return (arr.reshape(h//nrows, -1, nrows, ncols)
               .swapaxes(1,2)
               .reshape(h, w))

def ISVD (U,S,V): #the inverse of singular value decomposition
    s = np.zeros(np.shape(U))
    for i in range(4):
        s[i, i] = S[i]
    recon_image = U @ s @ V
    return recon_image

def Watermark_Embedding (blocks, watermark) :
    Watermarked_blocks = []
    k1 = []
    k2 = []
    #convert the watermark to a list
    w = list(np.ndarray.flatten(watermark))
    for i in range (len(blocks)) :
        B = blocks[i]
        #Aplly singular value decoposition to the block
        U, s, V = np.linalg.svd(B)
        #Modify the singular values of the block
        P = s[1] - s[2]
        delta = abs(w[i]) - P
        s[1] = s[1] + delta
        if s[0] >= s[1] :
            k1.append(1)
        else :
            k1.append(-1)
        #the inverse of SVD after watermark embedding
        recunstructed_B = ISVD(U, s, V)
        Watermarked_blocks.append(recunstructed_B)
    for j in range(len(w)):
        if w[j] >= 0:
            k2.append(1)
        else:
            k2.append(-1)
    return k1,k2, np.array(Watermarked_blocks)


def apply_dct(image_array):
    size = image_array[0].__len__()
    all_subdct = np.empty((size, size))
    for i in range (0, size, 4):
        for j in range (0, size, 4):
            subpixels = image_array[i:i+4, j:j+4]
            subdct = dct(dct(subpixels.T, norm="ortho").T, norm="ortho")
            all_subdct[i:i+4, j:j+4] = subdct

    return all_subdct

def inverse_dct(all_subdct):
    size = all_subdct[0].__len__()
    all_subidct = np.empty((size, size))
    for i in range (0, size, 4):
        for j in range (0, size, 4):
            subidct = idct(idct(all_subdct[i:i+4, j:j+4].T, norm="ortho").T, norm="ortho")
            all_subidct[i:i+4, j:j+4] = subidct

    return all_subidct



#read watermark
Watermark = Image.open('Copyright.png').convert('L')
Watermark = list(Watermark.getdata())
#Separate the watermark into LSB and MSB images
Watermark1, Watermark2 = Get_MSB_LSB_Watermark()
#Apply descrete cosine Transform on the two generated images
DCT_Watermark1 = apply_dct(Watermark1)
DCT_Watermark2 = apply_dct(Watermark2)




#read cover Image
Cover_Image = Image.open('10.png').convert('L')
#Apply 1 level descrete wavelet transform
LL1, (LH1, HL1, HH1) = pywt.dwt2(Cover_Image, 'haar')
#Split the LH1 and HL1 subbands into blocks of size 4*4
blocks_LH1 = split(LH1,4,4)
blocks_HL1 = split(HL1,4,4)
#Watermark Embedding in LH1 and HL1 and Keys generation
Key1, Key3, WatermarkedblocksLH1 = Watermark_Embedding(blocks_LH1,DCT_Watermark1)
Key2 ,Key4,  WatermarkedblocksHL1 = Watermark_Embedding(blocks_HL1,DCT_Watermark2)
#Merge the watermzrked Blocks
reconstructed_LH1 = unblockshaped(WatermarkedblocksLH1, 256,256)
reconstructed_HL1 = unblockshaped(WatermarkedblocksHL1, 256,256)
#Apply the inverse of descrete wavelet transform to get the watermarked image
IDWT = pywt.idwt2((LL1, (reconstructed_LH1, reconstructed_HL1, HH1)), 'haar')
cv2.imwrite('Watermarked_img.png', IDWT)

这是我为提取过程编写的代码:

 import pywt
from scipy import fftpack
import numpy as np
import  cv2
from PIL import  Image
import scipy
from math import  sqrt, log10
from Watermark_Embedding import *


def Watermark_Extraction(blocks,key1, key2) :
    Extracted_Watermark = []
    for i in range(len(blocks)):
        B = blocks[i]
        #apply SVD on the Block
        U, s, V = np.linalg.svd(B)
        if key1[i] == 1 :
                P = (s[1] - s[2])
                Extracted_Watermark.append(P)
        else :
                P = (s[0] - s[2])
                Extracted_Watermark.append(P)
    for j in range(len(Extracted_Watermark)) :
        if key2[j] == 1 :
            Extracted_Watermark[j] = Extracted_Watermark[j]
        else :
            Extracted_Watermark[j] = - (Extracted_Watermark[j])
    return np.array(Extracted_Watermark)




def Merge_W1_W2 ():
    Merged_watermark = []
    w1 = list(np.ndarray.flatten(IDCTW1))
    w2 = list(np.ndarray.flatten(IDCTW2))
    for i in range (len(w2)):
        bw1 = '{:0>4}'.format((bin(int(abs(w1[i]))))[2:])
        bw2 = '{:0>4}'.format((bin(int(abs(w2[i]))))[2:])
        P = bw1+bw2
        pixel = (int(P,2))
        Merged_watermark.append(pixel)
    return Merged_watermark






Watermarked_Image = Image.open('Watermarked_img.png')
LL1, (LH1, HL1, HH1) = pywt.dwt2(Watermarked_Image, 'haar')
blocks_LH1 = split(LH1,4,4)
blocks_HL1 = split(HL1,4,4)
W1 = Watermark_Extraction(blocks_LH1, Key1,Key3)
W2 = Watermark_Extraction(blocks_HL1, Key2, Key4)
W1 = W1.reshape(64,64)
W2 = W2.reshape(64,64)

IDCTW1 = inverse_dct(W1)
IDCTW2 = inverse_dct(W2)
Merged = np.array(Merge_W1_W2())
Merged = Merged.reshape(64,64)
cv2.imwrite('Extracted_Watermark.png', Merged)

大小为512*512的封面图片:

enter image description here

我使用的64*64水印

enter image description here

水印图像:

enter image description here

我获得的提取水印:

enter image description here

我使用SSIM计算了两个水印之间的相似性:

from skimage.metrics import structural_similarity

 original_Watermark = cv2.imread('Copyright.png')
    extracted_watermark = cv2.imread('Extracted_Watermark.png')
    # Convert images to grayscale
    original_watermark = cv2.cvtColor(original_Watermark, cv2.COLOR_BGR2GRAY)
    extracted_Watermark = cv2.cvtColor(extracted_watermark, cv2.COLOR_BGR2GRAY)
    # Compute SSIM between two images
    (score, diff) = structural_similarity(original_Watermark, extracted_Watermark, full=True)
    print("SSIM = ", score)

我没有对水印图像进行任何修改,得到的SSIM是0.8445354561524052.然而,根据论文,提取的水印的SSIM应为0.99.

推荐答案

有两个问题:

  1. Merge_W1_W2中,您使用intfloat转换为int,但这会导致浮点数表示不准确的数字出现错误(例如14.99999999999997);这可以通过使用round来解决.
  2. 保存cv2.imwrite('Watermarked_img.png', IDWT)是有损操作,因为它将IDWT中的值舍入为最接近的整数;如果使用Watermarked_Image = IDWT,则会返回完全相同的水印图像.

Python相关问答推荐

如何使用Google Gemini API为单个提示生成多个响应?

如何在图片中找到这个化学测试条?OpenCV精明边缘检测不会绘制边界框

Python多处理:当我在一个巨大的pandas数据框架上启动许多进程时,程序就会陷入困境

Matlab中是否有Python的f-字符串等效物

重新匹配{ }中包含的文本,其中文本可能包含{{var}

运行Python脚本时,用作命令行参数的SON文本

数据抓取失败:寻求帮助

当从Docker的--env-file参数读取Python中的环境变量时,每个\n都会添加一个\'.如何没有额外的?

使用setuptools pyproject.toml和自定义目录树构建PyPi包

如何在solve()之后获得症状上的等式的值

我如何根据前一个连续数字改变一串数字?

如何在Polars中从列表中的所有 struct 中 Select 字段?

将pandas导出到CSV数据,但在此之前,将日期按最小到最大排序

Django—cte给出:QuerySet对象没有属性with_cte''''

在嵌套span下的span中擦除信息

如何在Pyplot表中舍入值

Python避免mypy在相互引用中从另一个类重定义类时失败

修改.pdb文件中的值并另存为新的

通过对列的其余部分进行采样,在Polars DataFrame中填充_null`?

如何计算Pandas 中具有特定条件的行之间的天差