论文复现代码《基于自适应哈夫曼编码的密文可逆信息隐藏算法》调试版

news2024/9/24 17:18:15

前言

本文展示论文《基于自适应哈夫曼编码的密文可逆信息隐藏算法》的复现代码。代码块的结构如下:

其中,每个代码块都包含了测试该代码块的功能的主函数代码,使用时可放心运行,前提是你按照这个包结构把文件命名改好,放在同一个文件夹下放好。.idea和__pycache__文件不用管。还有main.py、InformationEmbedding.py也是多余的文件。

论文内容解析请参考本人的这篇文章:

论文简述基于自适应哈夫曼编码的密文可逆信息隐藏算法(基于位图压缩的加密图像可逆信息隐藏算法)_zrc007007的博客-CSDN博客

精简版代码在这里:

论文复现代码《基于自适应哈夫曼编码的密文可逆信息隐藏算法》导演剪辑版-CSDN博客

复现代码

MedianEdgeDetector.py

首先是中值预测器,文件名为MedianEdgeDetector.py:

import numpy as np


class MED:
    def __init__(self):
        # 示例数据
        self.data = [
            [162, 162, 162, 161, 162, 157, 163, 161],
            [162, 162, 162, 161, 162, 157, 163, 161],
            [162, 162, 162, 161, 162, 157, 163, 161],
            [162, 162, 162, 161, 162, 157, 163, 161],
            [162, 162, 162, 161, 162, 157, 163, 161],
            [164, 164, 158, 155, 161, 159, 159, 160],
            [160, 160, 163, 158, 160, 162, 159, 156],
            [159, 159, 155, 157, 158, 159, 156, 157]
        ]

    def detect(self, data):
        # 中值预测
        result = np.zeros_like(data)
        result[0][0] = data[0][0]
        for i in range(1, len(data)):
            result[i][0] = data[i][0]
            result[0][i] = data[0][i]
        for i in range(1, len(data)):
            for j in range(1, len(data[0])):
                a = data[i - 1][j - 1]
                b = data[i - 1][j]
                c = data[i][j - 1]
                if a <= min(b, c):
                    result[i][j] = max(b, c)
                elif a >= max(b, c):
                    result[i][j] = min(b, c)
                else:
                    result[i][j] = b + c - a
        return result


if __name__ == "__main__":
    print(MED().detect(MED().data))

AdaptiveHuffmanEncoding.py

对图像进行自适应哈夫曼编码,文件名为AdaptiveHuffmanEncoding.py:

from MedianEdgeDetector import MED
import numpy as np
from math import inf


class HuffCode:
    def compare(self, num1, num2):
        # 比较像素值的相同比特位数
        count = 0
        for i in range(8):
            divisor = pow(2, 7-i)
            if int(num1 // divisor) == int(num2 // divisor):
                count += 1
                num1 = num1 - divisor
                num2 = num2 - divisor
            else:
                break
        return count

    def count(self, origindata,  data):
        # 生成图像相同像素值的比特位数的比较结果
        result = {}
        resultMap = np.zeros_like(data)
        resultMap[0][0] = -1
        for i in range(1, len(data)):
            resultMap[i][0] = -1
            resultMap[0][i] = -1
        for i in range(1, len(data)):
            for j in range(1, len(data[0])):
                num = self.compare(origindata[i][j], data[i][j])
                resultMap[i][j] = num
                result[num] = result.get(num, 0) + 1
        return resultMap, result


# 初始化哈夫曼结点
class Huffmannode(object):
    def __init__(self):
        self.parent=0
        self.left=0
        self.right=0
        self.weight=0


# 选择最小的结点下标
def select_node(huffman):
    # 俩个结点直接返回不需要找最小俩个结点
    if len(huffman)==2:
        return 0,1
    min=semin=inf# 初始化成无穷大
    f=s=-1
    for i in range(len(huffman)):
        if huffman[i].parent==0:
            if min>huffman[i].weight:
                semin=min
                s=f
                min=huffman[i].weight
                f=i
            elif semin>huffman[i].weight:
                semin=huffman[i].weight
                s=i
    return f,s


# 编码
def Huffman_code(origin_dict):
    # 给结点赋权重
    n=len(origin_dict)
    m=2*n-1
    huffman=[]
    for i in origin_dict:
        temp_huffmannode=Huffmannode()
        temp_huffmannode.weight=origin_dict[i]
        huffman.append(temp_huffmannode)
    # 构建Huffman树,选择俩个最小的结点合并
    for i in range(n,m):
        f,s=select_node(huffman)
        temp_huffmannode=Huffmannode()
        temp_huffmannode.weight=huffman[f].weight+huffman[s].weight
        temp_huffmannode.right=f  # 小的放在右边
        temp_huffmannode.left=s
        huffman[f].parent=huffman[s].parent=i
        huffman.append(temp_huffmannode)

    # 0,1编码,右0,左1
    codeing_dict = dict.fromkeys(origin_dict, None)
    for i in range(0,n):
        s=''
        k=i
        parent=huffman[i].parent
        while parent!=0:
            if huffman[parent].left==k:
                s+='1'
                k=parent
                parent=huffman[parent].parent
            else:
                s+='0'
                k=parent
                parent=huffman[parent].parent
        codeing_dict[list(origin_dict.keys())[i]]=list(reversed(s))
    for k in codeing_dict.items():
        codeing_dict[k[0]] = ''.join(k[1])

    return codeing_dict


if __name__ == "__main__":
    MED = MED()
    origindata = MED.data
    MEDdata = MED.detect(origindata)
    print(np.array(origindata))
    print(MEDdata)
    print(HuffCode().compare(159, 160))
    resultMap, result = HuffCode().count(origindata, MEDdata)
    print(result)
    '''
    # 输入原始字符集
    s = input('输入即将被编码的字符:')

    # 创建字典计算频率
    dic = {}
    for i in range(len(s)):
        # get方法,如果有键返回该键对应的值,如果没键,可以设置返回值
        dic[s[i]] = dic.get(s[i], 0) + 1
    '''
    code_dict = Huffman_code(result)
    print(code_dict)

Crypting.py

混沌矩阵加密,文件名为Crypting.py:

import numpy as np
from skimage import io
import matplotlib.pyplot as plt


def crypt(im, miu, x0):
    '''
    logistic混沌加密
    :param im: 图像
    :param miu: μ参数
    :param x0: x0参数
    :return: 返回密文图像
    '''
    h, w = im.shape
    c_ = np.zeros_like(im)
    c_[0][0] = x0
    c=[]
    c.append(x0)
    result = np.zeros_like(im)
    result[0][0] = (x0 * pow(2, 48)) % 256
    for x in range(1, h * w):
        i = x // w
        j = x % w
        c.append(miu * c[x - 1] * (1 - c[x - 1]))
        c_[i][j] = (c[x] * pow(2, 48)) % 256
    for i in range(h):
        for j in range(w):
            result[i][j] = im[i][j] ^ c_[i][j]
    return result


def transform(img):
    column, row = img.shape
    result = np.zeros_like(img, dtype='int_')
    for i in range(column):
        for j in range(row):
            result[i][j] = int(img[i][j] * 255)
    return result


if __name__ == "__main__":
    plt.set_cmap(cmap='gray')
    img = io.imread("../img/lena_grey.tif")
    print(img)
    plt.imshow(img)
    img = transform(img)
    print(img)
    plt.figure()
    enc_img = crypt(img, 3.6, 0.5)
    plt.imshow(enc_img)
    plt.figure()
    dec_img = crypt(enc_img, 3.6, 0.5)
    plt.imshow(dec_img)
    plt.show()

LabelMapEmbedding.py

位图嵌入,文件名LabelMapEmbedding.py:

import numpy as np
import math
from AdaptiveHuffmanEncoding import *
from Crypting import *
# from MedianEdgeDetector import *


def int2bin(num, leng):
    '''
    整数int转二进制格式bin
    Transform a integer to a string whose length is leng.
    :param num: numbers waiting for transforming
    :param leng: the length of hoped result string
    :return: a string of leng length
    '''
    if leng < 1:
        raise Exception("Length isn't positive integer!")
    place = 1
    result = ''
    while place <= leng:
        result = str(num % 2) + result
        num = num // 2
        if num == 0:
            return (leng - place) * '0' + result
        place += 1
    raise Exception("Length of binary string isn't enough!")


def bin2int(string, leng):
    '''
    二进制格式bin转整数int
    Transfer a string of length of leng to a positive integer
    :param string: string waiting to be transferred
    :param leng: the length of reading
    :return: a positive integer less than 2^leng
    '''
    if leng < 1:
        raise Exception("Length isn't positive integer!")
    if len(string) < leng:
        raise Exception("Length of string under transferring isn't enough!")
    place = 1
    result = 0
    while place <= leng:
        result += int(string[place - 1]) * pow(2, leng - place)
        place += 1
    return result


def binstrcomplmt(string, length, complement):
    '''
    给二进制格式补位,补到前面。比如补0就给complement传0,补1就传1
    Complement strings with which we decide.
    :param string: string waiting to be complemented
    :param length: what we hope it to length
    :param complement: using what character to complement it
    :return: string already complemented
    '''
    return (length - len(string)) * complement + string


def binstrbackcomplmt(string, length, complement):
    '''
    给二进制格式补位,补到后面
    Complement strings with which we decide on its backhand.
    :param string: string waiting to be complemented
    :param length: what we hope it to length
    :param complement: using what character to complement it
    :return: string already complemented
    '''
    return string + (length - len(string)) * complement


def generatec(dict):
    '''
    生成嵌入信息中的c1到c8
    generate c info
    :param dict: Huffman code diction
    :return:
    '''
    result = ''
    c = []
    for i in range(9):
        c.append(0)
        c[i] = len(dict.get(i, ''))
        result += int2bin(c[i], 4)
    print(c)
    return result


def generateh(dict):
    '''
    生成嵌入信息中的h1到h8
    generate h info
    :param dict: Huffman code diction
    :return:
    '''
    result = ''
    h = []
    for i in range(9):
        h.append('')
        h[i] = binstrcomplmt(dict.get(i, '0'), 8, '0')
        result += h[i]
    print(h)
    return result


def countLm(countDict, lenDict):
    '''
    生成论文中说的Lm,变成Eta还需要转换一下
    Counting Lm
    :param countDict: diction of Huffman codes' appearance
    :param lenDict: Huffman code diction
    :return:
    '''
    count = 0
    for i in range(9):
        count += countDict.get(i, 0) * len(lenDict.get(i, ''))
    return count


def generatef(Lm, shapeOfImg):
    '''
    生成嵌入信息中的f
    generate f, which is Lm's bits' num's binary format
    :param Lm:
    :param shapeOfImg:
    :return:
    '''
    return int2bin(Lm, math.ceil(np.log2(shapeOfImg[0])) + math.ceil(np.log2(shapeOfImg[1])) + 2)


def generateEta(dic, labelmap):
    '''
    生成嵌入信息中的Eta
    Transferred label map's binary format
    :param dic:
    :param labelmap:
    :return:
    '''
    result = ''
    for i in range(1, labelmap.shape[0]):
        for j in range(1, labelmap.shape[1]):
            result += dic[labelmap[i][j]]
    return result


def generatelabelinfo(HuffDict, CountDict, LabelMap):
    '''
    生成总的嵌入信息
    Generate embedding information of label map
    :param HuffDict: Huffman code diction
    :param CountDict: Length of Huffman codes' diction
    :param LabelMap: The label map
    :return: Embedding information of label map
    '''
    return generatec(HuffDict) + generateh(HuffDict) + generatef(countLm(CountDict,HuffDict), LabelMap.shape)\
           + generateEta(HuffDict, LabelMap)


def embedinfo(LabelInfo, EncryptedImg, LabelMap, data):
    # 嵌入位图信息
    ReferencePixels = ''
    result = np.array(EncryptedImg)
    for i in range(EncryptedImg.shape[0]):
        ReferencePixels += int2bin(EncryptedImg[0][i], 8)
        result[0][i] = bin2int(LabelInfo, 8)
        LabelInfo = LabelInfo[8:]  # 截掉8个
    for i in range(1, EncryptedImg.shape[1]):
        ReferencePixels += int2bin(EncryptedImg[i][0], 8)
        result[i][0] = bin2int(LabelInfo, 8)
        LabelInfo = LabelInfo[8:]
    EmbeddingInfo = LabelInfo + ReferencePixels + data
    print("Length of Reference Pixels is:", len(ReferencePixels))
    count = 0
    row = count // (EncryptedImg.shape[1] - 1) + 1
    column = count % (EncryptedImg.shape[1] - 1) + 1
    t = LabelMap[row][column]
    maximum = (EncryptedImg.shape[0] - 1) * (EncryptedImg.shape[1] - 1)
    while len(EmbeddingInfo) > 0:
        if 0 <= t <= 6:
            result[row][column] = EncryptedImg[row][column] % pow(2, 7 - t)\
                                  + bin2int(binstrbackcomplmt(EmbeddingInfo[:t+1], 8, '0'), 8)
            EmbeddingInfo = EmbeddingInfo[t+1:]
        elif 7 <= t <= 8:
            result[row][column] = bin2int(binstrbackcomplmt(EmbeddingInfo[:8], 8, '0'), 8)
            EmbeddingInfo = EmbeddingInfo[8:]
        count += 1
        if count >= maximum:
            raise Exception("There's no room for embedding!")
        row = count // (EncryptedImg.shape[1] - 1) + 1
        column = count % (EncryptedImg.shape[1] - 1) + 1
        t = LabelMap[row][column]
    return result


def detect(data):
    '''
    测试用预测函数
    :param data:
    :return:
    '''
    result = np.zeros_like(data)
    result[0][0] = data[0][0]
    for i in range(1, len(data)):
        result[i][0] = data[i][0]
        result[0][i] = data[0][i]
    for i in range(1, len(data)):
        for j in range(1, len(data[0])):
            a = data[i - 1][j - 1]
            b = data[i - 1][j]
            c = data[i][j - 1]
            if a <= min(b, c):
                result[i][j] = max(b, c)
            elif a >= max(b, c):
                result[i][j] = min(b, c)
            else:
                result[i][j] = b + c - a
    return result


if __name__ == "__main__":
    print(128//2)
    print(128%2)
    strng = int2bin(1, 8)
    print(strng)
    print(bin2int(strng,8))
    print(bin2int('1', 1))
    MED = MED()
    origindata = MED.data
    origindata = np.array(origindata)
    MEDdata = MED.detect(origindata)
    print("The origin data is:")
    print(np.array(origindata))
    print("The predicted data is:")
    print(MEDdata)
    print(HuffCode().compare(159, 160))
    resultMap, countingResult = HuffCode().count(origindata, MEDdata)
    print("The label map is:")
    print(resultMap)
    print("The counting result of Huffman coding is:", countingResult)
    '''
    # 输入原始字符集
    s = input('输入即将被编码的字符:')

    # 创建字典计算频率
    dic = {}
    for i in range(len(s)):
        # get方法,如果有键返回该键对应的值,如果没键,可以设置返回值
        dic[s[i]] = dic.get(s[i], 0) + 1
    '''

    code_dict = Huffman_code(countingResult)
    print(code_dict)
    generatec(code_dict)
    print(generatec(code_dict))
    print(len(generatec(code_dict)))
    print(generateh(code_dict), len(generateh(code_dict)))

    lm = countLm(countingResult, code_dict)
    print("Lm is:", lm)
    f = generatef(lm, MEDdata.shape)
    print("f is:", f)
    print("length of f is:", len(f))
    Eta = generateEta(code_dict, resultMap)
    print("The length of Eta is:", len(Eta))
    print("Eta is:")
    print(Eta)

    labelInfo = generatelabelinfo(code_dict,countingResult, resultMap)
    print("The length of labelInfo is:", len(labelInfo))
    print("Label info:")
    print(labelInfo)

    print("Is length of c, h, f and Eta equals to labelInfo:", len(generatec(code_dict)) + len(generateh(code_dict)) +\
                                                               len(f) + len(Eta) == len(labelInfo))

    embedded = embedinfo(labelInfo, crypt(origindata, 3.6, 0.5), resultMap, '0110')
    print(embedded)

    strng = int2bin(903, 11)
    print(strng)
    print(strng[12:] == '')
    print(strng[:3])

    print(detect(origindata))

DataExtractionandImageRecovery.py

数据提取和恢复,文件名DataExtractionandImageRecovery.py:

from LabelMapEmbedding import *
from skimage import io
import matplotlib.pyplot as plt


def HuffDecode(HuffDict, info):
    # 哈夫曼解码
    for i in range(9):
        if info[:len(HuffDict.get(i, ''))] == HuffDict.get(i, -1):
            print("The i is:", i)
            print(info[:8])
            print(HuffDict)
            return i, len(HuffDict[i])
    raise Exception("No string matches!")


def extractpixel(pixel, t):
    # 根据t值,恢复像素位数
    if 0 <= t <= 7:
        return int2bin(pixel, 8)[:t+1]
    elif t == 8:
        return int2bin(pixel, 8)
    else:
        raise Exception("T out of range!")


def calctcut(t):
    # 根据t值,返回像素数
    if 0 <= t <= 7:
        return t + 1
    elif t == 8:
        return 8
    else:
        raise Exception("T out of range!")


def extract1(encrypted):
    # 提取第一行、第一列
    info = ''
    LenDict = {}
    HuffDict = {}
    for i in range(encrypted.shape[0]):
        info += int2bin(encrypted[0][i], 8)
    for i in range(1, encrypted.shape[1]):
        info += int2bin(encrypted[i][0], 8)
    for i in range(9):
        LenDict[i] = bin2int(info[:4], 4)
        info = info[4:]
    for i in range(9):
        if LenDict[i] != 0:
            HuffDict[i] = info[8-LenDict[i]:8]
        info = info[8:]
    print(LenDict, HuffDict)
    return HuffDict, info


def extract_exp(encrypted, HuffDict, info, datalen, Label):  # Label是用来测试位图和算出来的是不是一样的,可以删掉
    # 提取位图
    LabelMap = np.zeros_like(encrypted)
    decrypted1 = np.array(encrypted)
    LmLen = math.ceil(np.log2(encrypted.shape[0])) + math.ceil(np.log2(encrypted.shape[1])) + 2
    Lm = bin2int(info[:LmLen], LmLen)
    info = info[LmLen:]
    infoLen = Lm + ((encrypted.shape[0] - 1) + (encrypted.shape[1] - 1) - 1) * 8 + datalen
    count = len(info)  # 已提取到的信息长度
    place = 0
    pursuit = 0
    gonext = 0
    count1 = 1
    while count < infoLen:
        print("count:", count)
        print("Info len:", infoLen)
        print("pursuit:", pursuit)
        row = place // (encrypted.shape[1] - 1) + 1
        column = place % (encrypted.shape[1] - 1) + 1
        print("origin row, column:", row, column)
        if count1 == 1 and count < Lm:
            t, CodeLen = HuffDecode(HuffDict, info)
            print("t is:", t)
            LabelMap[row][column] = t
            info = info[CodeLen:] + extractpixel(encrypted[row][column], t)
            count += calctcut(t)
            place += 1
            print("step1")
            print("Is the Label Map equal to the extrated one:", Label[row][column] == t)
            print("place is:", place)
            print("count is:", count)
        else:
            pursuit = 1
            count1 = 0
        if pursuit == 1 and gonext == 0:
            record = place
            print("\nThe staring of step 2's row and column is:\n", row , column)
            while place < (encrypted.shape[0] - 1) * (encrypted.shape[1] - 1):
                row = place // (encrypted.shape[1] - 1) + 1
                column = place % (encrypted.shape[1] - 1) + 1
                t, CodeLen = HuffDecode(HuffDict, info)
                LabelMap[row][column] = t
                info = info[CodeLen:] + extractpixel(encrypted[row][column], t)
                print("step2")
                print("Is the Label Map equal to the extrated one:", Label[row][column] == t)
                print("T is {}, and the Label is {}".format(t, Label[row][column]))
                print("place:", place)
                print("row, column:", row, column)
                place += 1
                print('haha',place)
                print("end")
            place = record
            row = place // (encrypted.shape[1] - 1) + 1
            column = place % (encrypted.shape[1] - 1) + 1
            gonext = 1
        if gonext == 1 and count - Lm < (encrypted.shape[0] - 1) * (encrypted.shape[1] - 1) * 8 + datalen:
            # print("place:",place)
            # print("row, column:", row, column)
            info += extractpixel(encrypted[row][column], LabelMap[row][column])
            count += calctcut(LabelMap[row][column])
            # print("infolen:", infoLen)
            # print("count:", count)
            # print()
            place += 1
    for i in range(encrypted.shape[0]):
        LabelMap[0][i] = -1
        decrypted1[0][i] = bin2int(info[:8], 8)
        info = info[8:]
    for i in range(1, encrypted.shape[1]):
        LabelMap[i][0] = -1
        decrypted1[i][0] = bin2int(info[:8], 8)
        info = info[8:]
    data = info[:datalen]
    return LabelMap, decrypted1, data


def reverse(char):
    # 反转0和1
    if char == '0':
        return '1'
    elif char == '1':
        return '0'
    else:
        raise Exception("Not 0 or 1!")


def detect(data, i, j):
    '''
    测试用预测函数
    :param data:
    :return:
    '''
    a = data[i - 1][j - 1]
    b = data[i - 1][j]
    c = data[i][j - 1]
    if a <= min(b, c):
        result = max(b, c)
    elif a >= max(b, c):
        result = min(b, c)
    else:
        result = b + c - a
    return result


def recovery(img, LabelMap):
    # 恢复图像
    result = np.zeros_like(img)
    for i in range(img.shape[0]):
        result[0][i] = img[0][i]
    for i in range(1, img.shape[1]):
        result[i][0] = img[i][0]
    for i in range(1, img.shape[0]):
        for j in range(1, img.shape[1]):
            px = detect(result, i, j)
            t = LabelMap[i][j]
            if t == 8:
                result[i][j] = px
            elif 0 <= t <= 7:
                result[i][j] = bin2int(int2bin(px, 8)[:t] + '0' * (8 - t), 8)\
                               + int(reverse(int2bin(px, 8)[t:t+1])) * pow(2, 7 - t) + img[i][j] % pow(2, 7 - t)
            else:
                raise Exception("T out of range!")
    return result


if __name__ == "__main__":
    MED = MED()
    # origindata = MED.data
    origindata = io.imread("../img/lena_grey.tif")
    origindata = transform(origindata)
    origindata = np.array(origindata)
    MEDdata = MED.detect(origindata)
    print("The origin data is:")
    print(np.array(origindata))
    print("The predicted data is:")
    print(MEDdata)
    print(HuffCode().compare(159, 160))
    resultMap, countingResult = HuffCode().count(origindata, MEDdata)
    print("The label map is:")
    print(resultMap)
    print("The counting result of Huffman coding is:", countingResult)

    code_dict = Huffman_code(countingResult)
    print(code_dict)
    generatec(code_dict)
    print(generatec(code_dict))
    print(len(generatec(code_dict)))
    print(generateh(code_dict), len(generateh(code_dict)))

    lm = countLm(countingResult, code_dict)
    print("Lm is:", lm)
    f = generatef(lm, MEDdata.shape)
    print("f is:", f)
    print("length of f is:", len(f))
    Eta = generateEta(code_dict, resultMap)
    print("The length of Eta is:", len(Eta))
    print("Eta is:")
    print(Eta)

    labelInfo = generatelabelinfo(code_dict,countingResult, resultMap)
    print("The length of labelInfo is:", len(labelInfo))
    print("Label info:")
    print(labelInfo)
    secret = '0110010000' * 50  # 用于测试的秘密信息
    embedded = embedinfo(labelInfo, crypt(origindata, 3.6, 0.5), resultMap, secret)  # 嵌入秘密信息
    print(embedded)
    huff_code, info1 = extract1(embedded)
    print("The length of rest of info waiting for extracting is:", len(info1))
    print(int2bin(100, 8))
    print(extractpixel(100, 0))
    # resultMap2, decrypted1, data= extract2(embedded, huff_code, info1, 4)
    resultMap2, decrypted1, data = extract_exp(embedded, huff_code, info1, len(secret), resultMap)
    print("The encrypted img is:\n", crypt(origindata, 3.6, 0.5))
    print("The decrypted1 img is:\n", decrypted1)
    print(resultMap2)
    print(resultMap)
    print(data)
    if secret == data:
        print("THE extract is successful!")
    img1 = crypt(decrypted1, 3.6, 0.5)
    print("img1 is:\n",img1)
    '''
    print("Origin:")
    print(origindata)
    print("Detect img:")
    print(detect(img1))
    print("Detected origin data:")
    print(detect(origindata))
    '''
    res = img1 - origindata
    print("result compare with origin data:\n")
    print(res)
    img2 = recovery(img1, resultMap2)
    print(img2)
    res = img2 - origindata
    print("img2 compares to origin:\n", res)
    plt.set_cmap(cmap='gray')
    plt.subplot(221)
    plt.imshow(origindata)
    plt.title("Origin imagery")
    plt.subplot(222)
    plt.imshow(embedded)
    plt.title("Embedded imagery")
    plt.subplot(223)
    plt.imshow(img1)
    plt.title("Preliminary decrypted imagine")
    plt.subplot(224)
    plt.imshow(img2)
    plt.title("Fully recovered imagine")
    plt.show()

Comparison.py

计算指标,比较结果,文件名Comparison.py:

import numpy as np
import math
import cv2
from DataExtractionandImageRecovery import *
from skimage.color import rgb2gray


def ssim(img1, img2):
   #计算ssim指标
  C1 = (0.01 * 255)**2
  C2 = (0.03 * 255)**2
  img1 = img1.astype(np.float64)
  img2 = img2.astype(np.float64)
  kernel = cv2.getGaussianKernel(11, 1.5)
  window = np.outer(kernel, kernel.transpose())
  mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5] # valid
  mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5]
  mu1_sq = mu1**2
  mu2_sq = mu2**2
  mu1_mu2 = mu1 * mu2
  sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq
  sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq
  sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2
  ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) *
                              (sigma1_sq + sigma2_sq + C2))
  return ssim_map.mean()


def psnr(img1, img2):
   # 计算PSNR指标
   mse = np.mean( (img1/255. - img2/255.) ** 2 )
   if mse < 1.0e-10:
      return 100
   PIXEL_MAX = 1
   return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))


if __name__ == "__main__":
    MED = MED()
    # Baboon 3.6 0.5
    origindata = io.imread("../img/lena_gray_512.tif")
    # origindata = rgb2gray(origindata)
    print(origindata)
    # origindata = transform(origindata)
    origindata = np.array(origindata)
    MEDdata = MED.detect(origindata)
    resultMap, countingResult = HuffCode().count(origindata, MEDdata)
    code_dict = Huffman_code(countingResult)
    labelInfo = generatelabelinfo(code_dict, countingResult, resultMap)
    encrypted = crypt(origindata, 3.7, 0.9)
    containingLabel = embedinfo(labelInfo, encrypted, resultMap, '')
    embedded = embedinfo(labelInfo, encrypted, resultMap, '0110010000')
    huff_code, info1 = extract1(embedded)
    # resultMap2, decrypted1, data = extract_exp(embedded, huff_code, info1, 10, resultMap)
    # img1 = crypt(decrypted1, 3.6, 0.5)
    print("Lena")
    print("Comparison of PSNR and SSIM between encrypted imagine and the original:")
    print("PSNR:", psnr(origindata, encrypted))
    print("SSIM:", ssim(origindata, encrypted))

    print()
    print("Comparison of PSNR and SSIM between containing Label Map imagine and the original:")
    print("PSNR:", psnr(origindata, containingLabel))
    print("SSIM:", ssim(origindata, containingLabel))

    print()
    print("Comparison of PSNR and SSIM between embedded imagine and the original:")
    print("(With the secret of '0110010000')")
    print("PSNR:", psnr(origindata, embedded))
    print("SSIM:", ssim(origindata, embedded))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1272198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 keep-alive页面切换报错:parentComponent.ctx.deactivate is not a function

问题&#xff1a; <router-view v-slot"{ Component }"><keep-alive ><component :is"Component" v-if"$route.meta.keepAlive" /></keep-alive><component :is"Component" v-if"!$route.meta.keepA…

【软件测试】白盒测试和黑盒测试

一、软件测试基本分类 一般地&#xff0c;我们将软件测试活动分为以下几类&#xff1a;黑盒测试、白盒测试、静态测试、动态测试、手动测试、自动测试等等。 黑盒测试 黑盒测试又叫功能测试、数据驱动测试或给予需求规格说明书的功能测试。这种测试注重于测试软件的功能性需…

java二十章多线程

概念 有很多工作是可以同时完成的&#xff0c;这种思想放在Java中被称为并发&#xff0c;并发完成每一件事被称为线程。 程序员可以在程序中执行多个线程&#xff0c;每一个线程完成一个功能//与其他线程并发执行&#xff0c;这种机制被称为多线程&#xff0c;并不算所有编程…

PLC:200smart(13-16章)

PLC&#xff1a;200smart 第十三章2、带参子程序3、将子程序设置成库文件 第十三章 项目ValueValue主程序MAIN一个项目只能有一个&#xff0c;循环扫描子程序SBR_0项目中最多有128个&#xff0c;只有在调用时 才执行&#xff08;子程序可以嵌套其他子程序&#xff0c;最多八层…

广州华锐视点:基于VR元宇宙技术开展法律法规常识在线教学,打破地域和时间限制

随着科技的飞速发展&#xff0c;人类社会正逐渐迈向一个全新的时代——元宇宙。元宇宙是一个虚拟的、数字化的世界&#xff0c;它将现实世界与数字世界紧密相连&#xff0c;为人们提供了一个全新的交流、学习和娱乐平台。在这个充满无限可能的元宇宙中&#xff0c;法律知识同样…

构建个人代理池:使用GitHub项目proxy_pool的搭建配置及代码接口详解

手把手教你搭建代理IP池&#xff1a; 项目简介&#xff1a; ​ 爬虫代理IP池项目,主要功能为定时采集网上发布的免费代理验证入库&#xff0c;定时验证入库的代理保证代理的可用性&#xff0c;提供API和CLI两种使用方式。同时你也可以扩展代理源以增加代理池IP的质量和数量。…

分治法之归并排序

思路: 将待排序数组分成两个子数组&#xff0c;计算中间位置mid。对左半部分进行递归排序&#xff0c;得到一个有序的子数组。对右半部分进行递归排序&#xff0c;得到另一个有序的子数组。合并两个有序的子数组&#xff0c;得到一个完整的有序数组。 示例图: 代码: #include&…

WPF绘制进度条(弧形,圆形,异形)

前言 WPF里面圆形进度条实现还比较麻烦,主要涉及到的就是动态绘制进度条的进度需要用到简单的数学算法。其实原理比较简单,我们需要的是话两条重叠的弧线,里面的弧线要比里面的弧线要宽,这样简单的雏形就出来了。 基础写法 我们可以用Path来绘制弧线,代码如下: <Gr…

Linux:服务器管理工具宝塔(bt)安装教程

一、简介 bt宝塔Linux面板是提升运维效率的服务器管理软件&#xff0c;支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等多项服务的管理功能 二、安装 使用 SSH 连接工具&#xff0c;如堡塔SSH终端连接到您的 Linux 服务器后&#xff0c;挂载磁盘&#xff0c;根据系统执…

C++基础——文件操作

文章目录 1 概述2 文本文件2.1 写文件2.1.1 写文件流程2.1.2 文件打开方式 2.2 读文件 3 二进制文件3.1 写文件3.2 读文件 1 概述 程序最基本的操作之一就是文件操作&#xff0c;程序运行时的数据都是临时数据&#xff0c;当程序结束后就不复存在了。通常都是通过文件或其他持…

酷狗音乐app 评论signature

文章目录 声明目标加密参数定位翻页逻辑代码实现 声明 本文章中所有内容仅供学习交流&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请私信我立即删除&#xff01; 目标 复制curl转python # -*- c…

SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解

SQL SELECT INTO 语句 SELECT INTO 语句将数据从一个表复制到一个新表中。 SELECT INTO 语法 将所有列复制到新表中&#xff1a; SELECT * INTO newtable [IN externaldb] FROM oldtable WHERE condition;只复制一些列到新表中&#xff1a; SELECT column1, column2, colu…

MySQL三大日志详细总结(redo log undo log binlog)

MySQL日志 包括事务日志&#xff08;redolog undolog&#xff09;慢查询日志&#xff0c;通用查询日志&#xff0c;二进制日志&#xff08;binlog&#xff09; 最为重要的就是binlog&#xff08;归档日志&#xff09;事务日志redolog&#xff08;重做日志&#xff09;undolog…

数据结构(超详细讲解!!)第二十六节 图(上)

1.基本概念 图&#xff08;Graph&#xff09;是一种较线性表和树更为复杂的非线性结构。是对结点的前趋和后继个数不加限制的数据结构&#xff0c;用来描述元素之间“多对多”的关系(即结点之间的关系是任意的)。 一个图G &#xff08;V&#xff0c;E&#xff09;由顶点&…

从谷歌搜索结果出现 AI 生成的图片谈起:AI的利与弊

随着人工智能&#xff08;AI&#xff09;的不断发展&#xff0c;其应用领域也越来越广泛。谷歌搜索是现代人日常生活中的一个常用工具&#xff0c;经常用于获取各种信息。最近&#xff0c;谷歌搜索结果中甚至出现了由AI生成的图片&#xff0c;这引发了人们对AI技术的讨论。 首…

CentOS7搭建Kubernetes集群

环境准备&#xff1a;配置好静态IP地址的Centos7&#xff08;2核、master内存3GB、slave内存2GB&#xff09;。 搭建概述&#xff1a;先将一台虚拟机搭建为master、随后克隆出两台虚拟机作为从节点。 虚拟机主机名和IP地址&#xff1a; 主机名IP地址master192.168.138.110sl…

vue3高德地图使用,地址搜索,地址逆解析

在vue3项目里使用高德地图 高德地图文档 先在项目的index.html页面里添加一些东西 <script type"text/javascript">window._AMapSecurityConfig {securityJsCode: "xxxxxxxxxxxxx", //高德安全码};</script> <script src"https://…

Ubuntu Server 20.04.6安装Anaconda3

下载安装包 去下面的网页找到自己想要安装的对应版本的链接&#xff1a; https://repo.anaconda.com/archive/ 我安装的版本链接如下&#xff1a; https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh 复制这个链接后使用如下命令下载&#xff1a; wget …

外汇天眼:在QOINTEC投资需缴纳分成费才给出金?这合理么?

一般来说&#xff0c;在正规的平台上申请出金是不需要缴纳什么费用的&#xff0c;除非有一些特殊情况&#xff0c;像低额出金、没有交易就申请出金等情况下&#xff0c;或许会让你缴纳一定的手续费或者隔夜利息费等&#xff08;不同的平台有不同的规则&#xff09;&#xff0c;…

python爬取robomaster论坛数据,作为后端数据

一. 内容简介 python爬取robomaster论坛数据&#xff0c;作为后端数据 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3代码 三.主要流程 3.1 接口分析 # 接口分析 # 全部数据 # https://bbs.robomaster.com/forum.php?modforumdisplay&fid63 2…