【HIT信息隐藏技术基础】RS隐写分析大作业

原出处链接:hakulamtta/RS-steganalysis: 在不同隐写率之下针对LSB隐写的RS隐写分析实现 (github.com)

首先感谢前辈代码给予我的帮助!

在原代码基础上,修改了一些由于时代技术更新发展引起的语法格式之类的问题,调整了部分代码并添加了一些注释以便自己阅读和理解。

感觉前辈完成得很好很好,值得大家学习。

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt  # plt 用于显示图片
import matplotlib.image as mpimg  # mpimg 用于读取图片
import numpy as np
import pylab as pl
import random


# 对像素块进行Z字排序
def Z(tmp):
    size = 8
    a = [0] * 64    # 一维,装像素值
    n = 0   # 计数像素值个数
    i = 0   # 所在列数(0-7)
    j = 0   # 所在行数(0-7)
    status = 0  # 标记下一状态 0:右上运动 1:左下运动
    while n < size * size:
        # 奇数/偶数从0计数

        # 当前位于像素矩阵左边的奇数位且不是边界(没到底边),向下移动,下一步向右上运动
        if ((i == 0 and j % 2 != 0) or (j == 1 and i == 0)) and j != size - 1:
            a[n] = tmp[i][j]
            j = j + 1
            n = n + 1
            status = 0

        # 当前位于像素矩阵左边的奇数位且为边界(到底边),向右移动,下一步向右上运动
        if ((i == 0 and j % 2 != 0) or (j == 1 and i == 0)) and j == size - 1:
            a[n] = tmp[i][j]
            i = i + 1
            n = n + 1
            status = 0

        # 当前位于像素矩阵上边的偶数位,向右移动,下一步向左下运动(第1个格子的情况)
        elif (j == 0 and i % 2 == 0 and i > 1) or (i == 0 and j == 0):
            a[n] = tmp[i][j]
            i = i + 1
            n = n + 1
            status = 1

        # 当前位于像素矩阵左边的偶数位,向右上移动
        elif (i == 0 and j % 2 == 0 and j > 1) or (j == 0 and i == 0):
            a[n] = tmp[i][j]
            j = j - 1
            i = i + 1
            n = n + 1
            status = 0

        # 当前位于像素矩阵上边的奇数位,向左下移动
        elif (j == 0 and i % 2 != 0) or (i == 1 and j == 0):
            a[n] = tmp[i][j]
            i = i - 1
            j = j + 1
            n = n + 1
            status = 1

        # 当前位于像素矩阵右边的奇数位,向下移动,下一步向左下运动
        elif i == size - 1 and j % 2 != 0:
            a[n] = tmp[i][j]
            j = j + 1
            n = n + 1
            status = 1

        # 当前位于像素矩阵下边的偶数位,向右移动,下一步向右上移动
        elif j == size - 1 and i % 2 == 0 and i > 1:
            a[n] = tmp[i][j]
            i = i + 1
            n = n + 1
            status = 0

        # 当前位于像素矩阵右边的偶数位,向左下移动
        elif i == size - 1 and j % 2 == 0 and j > 1:
            a[n] = tmp[i][j]
            i = i - 1
            j = j + 1
            n = n + 1
            status = 1

        # 当前位于像素矩阵下边的奇数位,向右上移动
        elif j == size - 1 and i % 2 != 0:
            a[n] = tmp[i][j]
            i = i + 1
            j = j - 1
            n = n + 1
            status = 0

        # 不是边界条件时,使用状态值判断移动方向
        else:
            if status == 0:  # 右上运动
                a[n] = tmp[i][j]
                i = i + 1
                j = j - 1
                n = n + 1
                status = 0
            elif status == 1:  # 左下运动
                a[n] = tmp[i][j]
                i = i - 1
                j = j + 1
                n = n + 1
                status = 1
    return a


# 计算像素相关性
def Calculate(a):
    res = 0
    for i in range(63):
        if a[i + 1] > a[i]:     # 相邻元素差的绝对值之和
            res = res + a[i + 1] - a[i]
        else:
            res = res + a[i] - a[i + 1]
    return res


# 0翻转
def F0(val):
    return val


# 正向翻转
def F1(val):
    if val % 2 == 0:  # 偶数加一
        val = val + 1
    elif val % 2 == 1:  # 奇数减一
        val = val - 1
    return val


# 负向翻转
def F_1(val):
    if val % 2 == 0:  # 偶数减一
        val = val - 1
    elif val % 2 == 1:  # 奇数加一
        val = val + 1
    return val


# 生成随机数组(决定是正翻转还是负翻转)
def Random(typ):
    ran = [0] * 64
    if typ == 1:
        for i in range(64):
            ran[i] = random.randint(0, 1)
    elif typ == -1:
        for i in range(64):
            ran[i] = random.randint(-1, 0)
    return ran


# RS隐写分析(处理每个8*8块)
def RS(tmp):
    # 非负翻转
    ran = Random(1)
    rev = [[0 for co in range(8)] for ro in range(8)]  # 用于放置进行翻转后的二维数组(藏入信息后的二维数组)
    rm = 0
    sm = 0

    r1 = Z(tmp)
    res1 = Calculate(r1)  # 翻转之前的像素相关性

    k = 0
    for i in range(8):
        for j in range(8):
            if ran[k] == 0:  # F0翻转
                rev[i][j] = F0(tmp[i][j])
            elif ran[k] == 1:  # F1翻转
                rev[i][j] = F1(tmp[i][j])
            k = k + 1

    r2 = Z(rev)  # 将图像块进行Z字形排序
    res2 = Calculate(r2)  # 翻转之后的像素相关性

    if res1 > res2:     # 相关性减少
        sm = sm + 1
    elif res1 < res2:   # 相关性增加
        rm = rm + 1

    # 非正翻转
    k = 0
    r_m = 0
    s_m = 0
    ran = Random(-1)
    rev = [[0 for co in range(8)] for ro in range(8)]  # 进行翻转后的二维数组
    for i in range(8):
        for j in range(8):
            if ran[k] == 0:
                rev[i][j] = F0(tmp[i][j])
            elif ran[k] == -1:
                rev[i][j] = F_1(tmp[i][j])
            k = k + 1

    r3 = Z(rev)  # 将图像块进行Z字形排序
    res3 = Calculate(r3)  # 翻转之后的像素相关性

    if res1 > res3:
        s_m = s_m + 1
    elif res1 < res3:
        r_m = r_m + 1

    res = [rm, sm, r_m, s_m]
    return res


# LSB隐写
def LSB(fig, rate):
    s = int(512 * 512 * rate)
    sec = [0] * (s)
    k = 0

    for i in range(s):
        sec[i] = random.randint(0, 1)

    for i in range(512):
        for j in range(512):
            if k < s:
                if sec[k] == 1 and fig[i][j] % 2 == 0:  # 偶数嵌入1
                    fig[i][j] = fig[i][j] + 1
                    k += 1
                elif sec[k] == 1 and fig[i][j] % 2 == 1:  # 奇数嵌入1
                    fig[i][j] = fig[i][j] + 0
                    k += 1
                elif sec[k] == 0 and fig[i][j] % 2 == 0:  # 偶数嵌入0
                    fig[i][j] = fig[i][j] + 0
                    k += 1
                elif sec[k] == 0 and fig[i][j] % 2 == 1:  # 奇数嵌入0
                    fig[i][j] = fig[i][j] - 1
                    k += 1
    return fig


# 总流程

img = mpimg.imread('lena.bmp')
# plt.imshow(img)  # 显示图片
# plt.imshow(img_1,cmap='gray')
# plt.axis('off')  # 不显示坐标轴
# plt.show()
print(img.shape)    # 图像尺寸

# 将图片信息转存在二维数组中
img_1 = img[:, :, 0]
fig = np.array(img_1)
# print fig

# 对图像分块并计算相关性
tmp = [[0 for co in range(8)] for ro in range(8)]   # 用于存储8*8块
# print len(tmp)
# print tmp
row = img.shape[0] / 8  # 行
col = img.shape[1] / 8  # 列
result = [0] * 4
nn = 0

for i in range(64):
    for j in range(64):
        x = 0
        for k in range(i * 8, (i + 1) * 8):
            y = 0
            for h in range(j * 8, (j + 1) * 8):
                tmp[x][y] = fig[k][h]
                y = y + 1
            x = x + 1
        # print tmp
        res = RS(tmp)  # 进行RS隐写分析,res = [rm,sm,r_m,s_m]     # tmp循环使用
        for n in range(4):
            result[n] = result[n] + res[n]          # 对每个块的四个值累加,得到图像总值
print("orignal picture:")
print("rm=", result[0], "  sm=", result[1], "  r_m=", result[2], "  s_m=", result[3])

# 进行LSB隐写之后
rate = 0
rm = [0] * (11)
sm = [0] * (11)
r_m = [0] * (11)
s_m = [0] * (11)
while (rate <= 1.0):
    fig = LSB(fig, rate)    # 隐写
    # 对图像分块并计算相关性
    tmp = [[0 for co in range(8)] for ro in range(8)]

    row = img.shape[0] / 8  # 行
    col = img.shape[1] / 8  # 列
    result = [0] * 4

    for i in range(64):
        for j in range(64):
            x = 0
            for k in range(i * 8, (i + 1) * 8):
                y = 0
                for h in range(j * 8, (j + 1) * 8):
                    tmp[x][y] = fig[k][h]
                    y = y + 1
                x = x + 1
            # print tmp
            res = RS(tmp)  # 进行RS隐写分析,res = [rm,sm,r_m,s_m]
            for n in range(4):
                result[n] = result[n] + res[n]
    print("rate=", rate, "after LSB:")
    print("rm=", result[0], "  sm=", result[1], "  r_m=", result[2], "  s_m=", result[3])
    rate += 0.1

    rm[nn] = result[0]      # 存下来用于画图
    sm[nn] = result[1]
    r_m[nn] = result[2]
    s_m[nn] = result[3]
    nn = nn + 1

rate = 0
arr = [0] * 11
k = 0
while (k <= 10):
    arr[k] = rate
    k += 1
    rate = rate + 0.1
pl.plot(arr, rm)
pl.plot(arr, sm)
pl.plot(arr, r_m)
pl.plot(arr, s_m)
pl.show()

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值