You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于RGB图像LSB隐写的MATLAB代码求助(含编解码需求)

LSB图像隐写:编码/解码代码修复方案

嘿,你遇到的全黑图像问题我太熟了——大概率是编码时对像素值的处理逻辑出错了,比如不小心把整个像素值改成了0,或者用了JPEG这种有损格式保存,直接把隐写的位给冲没了。我给你整理了修复后的Python代码(用PIL库,兼容性拉满),还有对应的解码代码,顺便给你拆解关键细节:

修复后的编码代码

from PIL import Image

def text_to_binary(text):
    # 把每个字符转成8位二进制,末尾加'\0'当结束标记(解码时知道什么时候停)
    binary_str = ''.join(format(ord(c), '08b') for c in text + '\0')
    return binary_str

def lsb_encode(image_path, text_path, output_path):
    # 读取图像并强制转成RGB格式(避免灰度图坑)
    img = Image.open(image_path).convert('RGB')
    pixels = img.load()
    width, height = img.size
    
    # 读取要隐写的文本
    with open(text_path, 'r', encoding='utf-8') as f:
        text = f.read()
    binary_data = text_to_binary(text)
    data_length = len(binary_data)
    
    # 先检查图像能不能装下数据:每个像素能存3位,总容量是宽×高×3
    if data_length > width * height * 3:
        raise ValueError("图像太小啦,装不下这么多文本!")
    
    index = 0
    # 遍历每个像素,依次往R、G、B通道的LSB写二进制位
    for y in range(height):
        for x in range(width):
            if index >= data_length:
                break
            r, g, b = pixels[x, y]
            
            # 改R通道:先把最低位清零,再把当前二进制位写进去
            r = (r & 0xFE) | int(binary_data[index])
            index += 1
            if index >= data_length:
                pixels[x, y] = (r, g, b)
                break
            
            # 改G通道
            g = (g & 0xFE) | int(binary_data[index])
            index += 1
            if index >= data_length:
                pixels[x, y] = (r, g, b)
                break
            
            # 改B通道
            b = (b & 0xFE) | int(binary_data[index])
            index += 1
            pixels[x, y] = (r, g, b)
        if index >= data_length:
            break
    
    # 必须存成PNG!JPEG的压缩会把LSB的信息搞丢
    img.save(output_path, format='PNG')
    print(f"搞定!隐写后的图像已经存到 {output_path} 啦")

# 测试用例:把Hello写到test.txt里,用input_image.png来隐写
lsb_encode('input_image.png', 'test.txt', 'stego_image.png')

编码时的关键注意点

  • 只改最低位:用& 0xFE把像素值的最后一位清零,再用|把二进制位加进去,这样像素值只会变0或1,肉眼完全看不出图像变化
  • 结束标记:给文本末尾加\0,解码时读到这个就停止,不会把多余的像素位当成文本
  • 无损保存:PNG是无损格式,JPEG压缩会破坏LSB里的隐写数据,绝对不能用!

对应的解码代码

要把隐写的文本读出来,用下面的代码:

from PIL import Image

def binary_to_text(binary_str):
    # 每8位转成一个字符,直到碰到结束标记'\0'
    text = []
    for i in range(0, len(binary_str), 8):
        byte = binary_str[i:i+8]
        char = chr(int(byte, 2))
        if char == '\0':
            break
        text.append(char)
    return ''.join(text)

def lsb_decode(stego_image_path, output_text_path):
    img = Image.open(stego_image_path).convert('RGB')
    pixels = img.load()
    width, height = img.size
    
    binary_data = []
    # 遍历每个像素,提取R、G、B通道的LSB
    for y in range(height):
        for x in range(width):
            r, g, b = pixels[x, y]
            binary_data.append(str(r & 1))
            binary_data.append(str(g & 1))
            binary_data.append(str(b & 1))
    
    # 把提取到的二进制位转成文本
    binary_str = ''.join(binary_data)
    text = binary_to_text(binary_str)
    
    with open(output_text_path, 'w', encoding='utf-8') as f:
        f.write(text)
    print(f"解码完成!文本已经存到 {output_text_path} 啦")

# 测试解码
lsb_decode('stego_image.png', 'decoded_text.txt')

你之前得到全黑图像的常见原因

  1. 错误覆盖像素值:比如直接把像素值设成了二进制位(0或1),而不是只改最低位,导致所有像素都变成接近黑色的数值
  2. 用了JPEG保存:JPEG压缩会修改像素值,不仅丢隐写数据,还可能让图像变花甚至全黑
  3. 数据类型出错:比如处理像素时把uint8(0-255的整数)转成了浮点数,保存时没转回来,导致像素值被截断成0
  4. 没处理图像通道:比如用了灰度图却按RGB处理,通道数量不对,导致循环越界或者错误修改像素值

内容的提问来源于stack exchange,提问作者sumit kothia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:02:24