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

前言

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

其中,每个代码块都包含了测试该代码块的功能的主函数代码,使用时可放心运行,前提是你按照这个包结构把文件命名改好,放在同一个文件夹下放好。.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))

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值