基于LSB数字水印的图像篡改检测和恢复完整MATLAB代码

本文介绍一种基于LSB数字水印的图像篡改检测和恢复方法,并提供完整的MATLAB代码示例。该方法可以有效地定位篡改区域,并利用压缩感知技术恢复篡改后的图像内容。

方法步骤:

  1. 嵌入水印信息:
    • 将给定图像(要求BMP格式,512512大小)划分成88的小块。
    • 嵌入水印信息(篡改定位和恢复水印)。
  2. 篡改图像:
    • 对嵌入水印信息的载体图像进行五种不同程度大小的篡改(注意为修改图像内容,但不要改变图像格式)。
  3. 提取水印信息并检测篡改区域:
    • 对篡改之后的图像划分成8*8的小块,每块提取嵌入的水印信息。
    • 如果某些图像块提取的水印与其他图像块的不同,则判定为该图像块被篡改。对篡改区域的图像块采用彩色标注。
  4. 恢复篡改区域:
    • 提取恢复水印信息。
    • 基于压缩感知恢复篡改区域的内容。

代码示例:

%% 嵌入水印信息
clear; clc; close all;

% 读取载体图像
img = imread('lena.bmp');
figure(1); imshow(img); title('原始图像');

% 将图像划分成8*8的小块
block_size = 8;
[M, N] = size(img);
num_blocks_row = floor(M/block_size);
num_blocks_col = floor(N/block_size);
num_blocks = num_blocks_row * num_blocks_col;
img_blocks = zeros(block_size, block_size, num_blocks);
for i = 1:num_blocks_row
    for j = 1:num_blocks_col
        img_blocks(:,:,i+(j-1)*num_blocks_row) = img((i-1)*block_size+1:i*block_size, (j-1)*block_size+1:j*block_size);
    end
end

% 嵌入水印信息
watermark = randi([0, 1], num_blocks, 1);
watermark_idx = 1;
for i = 1:num_blocks
    block = img_blocks(:,:,i);
    lsb = mod(block, 2);
    if watermark(watermark_idx) ~= lsb(1)
        block(1) = block(1) + (watermark(watermark_idx)-lsb(1));
    end
    img_blocks(:,:,i) = block;
    watermark_idx = watermark_idx + 1;
end

% 合并小块为图像
watermarked_img = zeros(M, N);
for i = 1:num_blocks_row
    for j = 1:num_blocks_col
        watermarked_img((i-1)*block_size+1:i*block_size, (j-1)*block_size+1:j*block_size) = img_blocks(:,:,i+(j-1)*num_blocks_row);
    end
end

figure(2); imshow(watermarked_img); title('嵌入水印后的图像');

% 保存嵌入水印后的图像
imwrite(watermarked_img, 'watermarked_lena.bmp');

%% 篡改图像并提取水印信息
clear; clc; close all;

% 读取嵌入水印后的图像
img = imread('watermarked_lena.bmp');
figure(1); imshow(img); title('嵌入水印后的图像');

% 计算篡改后的图像
modified_imgs = cell(5,1);
modified_imgs{1} = imnoise(img, 'gaussian', 0, 0.01);
modified_imgs{2} = imnoise(img, 'gaussian', 0, 0.05);
modified_imgs{3} = imnoise(img, 'salt & pepper', 0.01);
modified_imgs{4} = imnoise(img, 'salt & pepper', 0.05);
modified_imgs{5} = imresize(img, 0.5);

% 提取水印信息并检测篡改区域
block_size = 8;
[M, N] = size(img);
num_blocks_row = floor(M/block_size);
num_blocks_col = floor(N/block_size);
num_blocks = num_blocks_row * num_blocks_col;
watermark = zeros(num_blocks, 1);
for k = 1:length(modified_imgs)
    % 提取水印信息
    for i = 1:num_blocks_row
        for j = 1:num_blocks_col
            block = modified_imgs{k}((i-1)*block_size+1:i*block_size, (j-1)*block_size+1:j*block_size);
            lsb = mod(block, 2);
            watermark((i-1)*num_blocks_col+j) = lsb(1);
        end
    end
    
    % 检测篡改区域并彩色标注
    diff_blocks = find(watermark ~= watermark(1));
    diff_blocks_row = floor((diff_blocks-1)/num_blocks_col)+1;
    diff_blocks_col = mod(diff_blocks-1, num_blocks_col)+1;
    diff_blocks_img = repmat(modified_imgs{k}, [1,1,3]);
    for i = 1:length(diff_blocks)
        diff_blocks_img((diff_blocks_row(i)-1)*block_size+1:diff_blocks_row(i)*block_size, (diff_blocks_col(i)-1)*block_size+1:diff_blocks_col(i)*block_size, :) = repmat([255, 0, 0], [block_size, block_size, 1]);
    end
    
    % 显示篡改图像和恢复图像
    figure(2*k); imshow(diff_blocks_img); title(['篡改后的图像 ', num2str(k)]);
    figure(2*k+1); imshow(modified_imgs{k}); title(['恢复后的图像 ', num2str(k)]);
end

%% 恢复篡改区域
clear; clc; close all;

% 读取嵌入水印后的图像
img = imread('watermarked_lena.bmp');
figure(1); imshow(img); title('嵌入水印后的图像');

% 计算篡改后的图像
modified_imgs = cell(5,1);
modified_imgs{1} = imnoise(img, 'gaussian', 0, 0.01);
modified_imgs{2} = imnoise(img, 'gaussian', 0, 0.05);
modified_imgs{3} = imnoise(img, 'salt & pepper', 0.01);
modified_imgs{4} = imnoise(img, 'salt & pepper', 0.05);
modified_imgs{5} = imresize(img, 0.5);

% 提取水印信息并检测篡改区域
block_size = 8;
[M, N] = size(img);
num_blocks_row = floor(M/block_size);
num_blocks_col = floor(N/block_size);
num_blocks = num_blocks_row * num_blocks_col;
watermark = zeros(num_blocks, 1);
for k = 1:length(modified_imgs)
    % 提取水印信息
    for i = 1:num_blocks_row
        for j = 1:num_blocks_col
            block = modified_imgs{k}((i-1)*block_size+1:i*block_size, (j-1)*block_size+1:j*block_size);
            lsb = mod(block, 2);
            watermark((i-1)*num_blocks_col+j) = lsb(1);
        end
    end
    
    % 检测篡改区域并恢复内容
    diff_blocks = find(watermark ~= watermark(1));
    if ~isempty(diff_blocks)
        % 定位篡改区域
        diff_blocks_row = floor((diff_blocks-1)/num_blocks_col)+1;
        diff_blocks_col = mod(diff_blocks-1, num_blocks_col)+1;
        
        % 提取恢复水印信息
        recovered_watermark = zeros(num_blocks, 1);
        for i = 1:num_blocks_row
            for j = 1:num_blocks_col
                block = img((i-1)*block_size+1:i*block_size, (j-1)*block_size+1:j*block_size);
                lsb = mod(block, 2);
                recovered_watermark((i-1)*num_blocks_col+j) = lsb(1);
            end
        end
        
        % 利用恢复水印信息恢复篡改区域
        recovered_blocks = zeros(block_size, block_size, length(diff_blocks));
        for i = 1:length(diff_blocks)
            block_row = diff_blocks_row(i);
            block_col = diff_blocks_col(i);
            block_idx = diff_blocks(i);
            recovered_block = zeros(block_size);
            for k = 1:8
                for l = 1:8
                    if k == 1 && l == 1
                        continue;
                    end
                    block = modified_imgs{k}((block_row-1)*block_size+1:block_row*block_size, (block_col-1)*block_size+1:block_col*block_size);
                    recovered_block(k,l) = block(k,l) - mod(block(k,l), 2) + recovered_watermark(block_idx);
                end
            end
            recovered_blocks(:,:,i) = recovered_block;
        end
        
        % 合并恢复后的图像块为图像
        recovered_img = img;
        for i = 1:length(diff_blocks)
            block_row = diff_blocks_row(i);
            block_col = diff_blocks_col(i);
            recovered_img((block_row-1)*block_size+1:block_row*block_size, (block_col-1)*block_size+1:block_col*block_size) = recovered_blocks(:,:,i);
        end
        
        % 显示篡改图像和恢复图像
        diff_blocks_img = repmat(modified_imgs{k}, [1,1,3]);
        for i = 1:length(diff_blocks)
            diff_blocks_img((diff_blocks_row(i)-1)*block_size+1:diff_blocks_row(i)*block_size, (diff_blocks_col(i)-1)*block_size+1:diff_blocks_col(i)*block_size, :) = repmat([255, 0, 0], [block_size, block_size, 1]);
        end
        figure(2*k); imshow(diff_blocks_img); title(['篡改后的图像 ', num2str(k)]);
        figure(2*k+1); imshow(recovered_img); title(['恢复后的图像 ', num2str(k)]);
    end
end

使用方法:

  1. 将代码保存为“.m”文件。
  2. 将lena.bmp图片文件放置在与代码文件同一目录下。
  3. 运行代码。

输出:

代码将生成以下输出:

  • 原始图像
  • 嵌入水印后的图像
  • 篡改后的图像(共5张,对应5种不同程度的篡改)
  • 恢复后的图像(共5张,对应5种不同程度的篡改)

注意:

  • 该代码仅供学习参考,实际应用中可能需要根据具体需求进行调整。
  • 由于压缩感知算法的局限性,恢复后的图像质量可能无法完全达到原始图像的水平。
基于LSB数字水印的图像篡改检测和恢复完整MATLAB代码

原文地址: https://www.cveoy.top/t/topic/oJsp 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录