空域信息隐藏算法(完成基于LSB的图像信息隐藏)

最近在上信息隐藏,做一个记录

一,实验要求

(1)了解信息隐藏算法的分类方式和分类依据
(2)理解空域信息隐藏算法的基本思想
(3)掌握最低有效位算法原理
(4)完成基于LSB的图像信息隐藏

二、实验内容

载体图像为24位真彩色bmp图像Lena.bmp,嵌入的秘密图像为黑白的bmp图像LSB.bmp,要求采用空域信息隐藏算法,将LSB.bmp嵌入到Lena.bmp的最低有效位中,同屏显示原载体图像、需要嵌入的秘密图像、嵌入了秘密图像的伪装载体、提取的秘密图像。
以下为实验材料:lena.bmp 和 LSB.bmp
在这里插入图片描述
隐体:
在这里插入图片描述

三、实验步骤和设计思想

1,使用pyhton库,skimage来完成相关的土图像处理
2,通过skimage库打开隐体,发现只有两个值【255,和 0】所以,其实隐藏时,只要用一位就可以隐藏隐体,将255使用1代替,0不变,将其藏在载体的最后一位即可。
3,因为隐体为RGB三通道图像,为了隐藏的更好,使用随机数将0和1,随机选定一个图层进行隐藏,当然为了能够还原原图像,使用一个seed作为key,这样产生的随机数就可以顺序提取。
4,隐藏和提取时,使用位运算可轻松的实现数字的高低位的存取。
5,将变换后的图片进行保存,再使用相同的key和隐藏信息后的载体,进行提取。
6,为了方便使用,将隐藏的方法和过程使用,面向对象的思想,封装为类。

四,### 代码

from skimage import io
import numpy


class IMG_LSB:

    def __init__(self, key):
        self.key = key

    def show(self, img):
        """
        显示图片
        :param img: 显示的图片矩阵
        :return: none
        """
        io.imshow(img)
        io.show()

    def create_cover(self, img_cover_name, img_info_name, save_img_name):
        """
        使用LSB算法对图像进行隐藏,隐藏到使用key作为种子生成的随机数指定的RGB通道中
        :param img_cover_name: 载体图片名
        :param img_info_name: 隐体图片名
        :param save_img_name: LSB生成后的图片保存位置以及名字
        :return: LSB生成后的图片矩阵
        """
        img_info = io.imread(img_info_name)
        img_cover = io.imread(img_cover_name)

        self.show(img_info)
        self.show(img_cover)
        self.ls_info = img_info.shape[0] # 得到隐体图片的长和宽
        self.ls_cover = img_cover.shape[0] # 得到载体的长和宽
        if self.ls_info > self.ls_cover:
            print("载体太小")
        # 开始隐藏
        numpy.random.seed(self.key)
        for i in range(0, self.ls_info):
            for j in range(0, self.ls_info):
                if img_info[i][j] == 255 :  # 如果隐体为255则藏在R层最低为置为1
                    img_cover[i, j, numpy.random.randint(0, 3)] |= 1    # 随机选定一个通道进行隐藏
                else:
                    img_cover[i, j, numpy.random.randint(0, 3)] &= 254  # 如果隐体为0则藏在R层最低为置为0

        self.show(img_cover)
        io.imsave(save_img_name, img_cover)
        return img_cover

    def  extract_img(self, blmb_name, save_img_name):
        """
        对隐体进行提取并显示
        :param blmb_name: LSB生成的含有隐体的载体名
        :param save_img_name: 提取后的隐体存储的位置
        :return: 提取后的隐体的矩阵
        """
        blmb = io.imread(blmb_name)
        matrix = [[255 for i in range(self.ls_info)] for i in range(self.ls_info)]    # 生成与隐体相同大小的矩阵,并赋值为255
        re_info_img = numpy.array(matrix, dtype=numpy.uint8)   # 将生成的矩阵转化为可存储图像的8位格式
        self.show(re_info_img)
        # 开始提取
        numpy.random.seed(self.key)
        for i in range(0, self.ls_info):
            for j in range(0, self.ls_info):
                randint_value = numpy.random.randint(0, 3)  # 使用seed控制随机数的生成保证与之前隐藏时,生成的随机数一致
                blmb[i, j, randint_value] &= 1 # 取出最后一位
                if blmb[i, j, randint_value] == 0:
                    re_info_img[i][j] &= 0     # 如果最后一位为0则隐体原处为0,为1则为255
                else:
                    re_info_img[i][j] |= 255

        io.imsave("img/re_img.bmp", re_info_img)
        self.show(re_info_img)
        return re_info_img


# 测试
if __name__ == '__main__':
    img = IMG_LSB(123) # key为123
    img.create_cover("img/Lena.bmp", "img/LSB.bmp", "img/blmb2.bmp")
    img.extract_img("img/blmb2.bmp", "img/re_img.bmp")
原文地址:https://www.cnblogs.com/jlxa162hhf/p/14161251.html