本文提出了一种基于覆盖图像的MSB的无编码信息隐藏方法。
首先,发送者将封面图像分割成许多相同大小的片段。大小为Fw*Fh。
其次,发送方求每段像素均值。
第三,将秘密信息转换为二进制位。
第四,根据发送方和接收方决定的映射序列(Km),用图像片段的MSB映射秘密信息。
映射的结果是获取映射标志(Kf),然后通过普通通道与引导图像一起发送到接收器。接收器可以使用Km和Kf正确地从stego图像中提取秘密信息。
提出方法:
CIHMSB方法的目的是为了传输文本信息。
在通信之前,发送方和接收方需要事先决定Km,并由发送方和接收方共享。Km是一组随机数,用于表示图像片段的序列号。
设覆盖图像大小为Ih*Iw 。
嵌入过程:
1)图像预处理。将载体图像分割成许多图像片段I1,I2,…,Im,其大小是Fw*Fh。片段的总数如式1。
求每段图片Fi的平均像素 , b并将其转化为8位二进制bit串Vi。
其中m=Fm
2)信息预处理。将秘密信息(T)的每个字符转换为7位二进制字符串(B1、B2、…、Bn)。对于长度为C的秘密信息T,bit串长度为:
过程为:
其中n=Cn
3)映射过程
其中j=Km[i],MSB为最大有效bit位,即最左的一位。
提取过程:
1)图像预处理:同嵌入时的图像预处理,得到V1’,V2’,V3’,…,Vm’ 其中m=Fm
2)逆映射。
3)将得到的bit串转换为字符
#中国地质大学 信息安全 2018 朱靖宇
import cv2
import numpy as np
def img2seg(img): #图片分段
h,w=img.shape
ret=[]
#print(h,w)
ch,cw=h//4,w//4
#print(ch,cw)
for i in range(ch):
for j in range(cw):
ret.append(img[i:i+4,j:j+4])
ret=np.array(ret)
#print(ret.shape)
return ret
def text2bits(text, encoding='utf-8', errors='surrogatepass'): #将字符转换为7bit比特串
bits = bin(int.from_bytes(text.encode(encoding, errors), 'big'))[2:]
return bits.zfill(7 * ((len(bits) + 6) // 7))
def bits2text(bits, encoding='utf-8', errors='surrogatepass'): #将7位比特串转换位字符
n = int(bits, 2)
return n.to_bytes((n.bit_length() + 6) // 7, 'big').decode(encoding, errors) or '\0'
def seg2means(seg): #求平均值
return(np.mean(seg,axis=1))
def seg2bits(segs):
B=[]
for x in segs:
bits=bin(x)
B.append(bits)
return B
def preprocess(cover_img): #图像预处理
cover_gray = cv2.cvtColor(cover_img, cv2.COLOR_BGR2GRAY)
frags = img2seg(cover_gray)
Vs = np.uint8(seg2means(frags))
Vs = np.uint8(seg2means(Vs))
Vs_bits = seg2bits(Vs)
return Vs_bits
def embed(img,txt): #嵌入部分
Vs_bits=preprocess(img)
txt_bits = str()
for s in txt:
txt_bits = txt_bits + str(text2bits(s))
n = len(txt_bits)
np.random.seed(1)
Km = np.random.randint(0, len(Vs_bits), len(Vs_bits))
#print(Vs_bits[Km[1]])
#print(str(Vs_bits[Km[1]]))
#print(str(Vs_bits[Km[1]])[2])
Kf = []
for i in range(n):
if txt_bits[i] == str(Vs_bits[Km[i]])[2]:
Kf.append(1)
else:
Kf.append(0)
return Kf,Km
def extract(img,Kf,Km): #提取部分
Vs_bits=preprocess(img)
txt_bits=np.uint(0)
txt = str()
for i in range(len(Kf)):
f=str(Vs_bits[Km[i]])[2]
#print(f)
if Kf[i]==1:
if f=='0':
txt_bits=txt_bits*2
else:
txt_bits=txt_bits*2+1
else:
if f=='0':
txt_bits=txt_bits*2+1
else:
txt_bits=txt_bits*2
if i % 7 == 6 :
#print(txt_bits)
txt=txt+bits2text(bin(txt_bits))
txt_bits=0
#print(txt)
return(txt)
txt='CUG Zhujingyu 20181000645'
cover_path='lena.bmp'
cover_img=cv2.imread(cover_path)
Kf,Km=embed(cover_img,txt)
print(Kf)
print(Km)
img=cv2.GaussianBlur(cover_img,(7,7),1.5) #高斯噪声
recover_txt=extract(img,Kf,Km)
print(recover_txt)