【论文复现】图像隐写常见问题

1. 提取出错

  1. 首先检查嵌入时的像素值是否越界(0-255),如果越界则在提取的时候无法正确提取
  2. 嵌入的时候注意整数除法和浮点数除法向下取整结果不一样,floor(int(10)/16)=1,floor(double(10)/16)=0

2. 常用代码部分

1.生成随机二进制数

% create and save msg  **matlab**
message = randi([0,1],1024,1);
save 'Catalan-based-Steganography\msg_1024bit.mat' message;

load("msg_256bit.mat");

2. 遍历文件

%% matlab
cover_path =  'D:\database\BOSSbase_1.01_png\';% 图像文件夹路径
img_path_list = dir(strcat(cover_path,'*.png'));%获取该文件夹中所有PNG格式的图像
[~,ind] = natsort({img_path_list.name}); % 自然语序
img_path_list = img_path_list(ind);
img_num = length(img_path_list);%获取图像总数量
if img_num > 0 %有满足条件的图像
    for img_idx = 1:10 %逐一读取图像
        disp(img_idx);
        image_name = img_path_list(img_idx).name;% 图像名
        gray_img =  imread(strcat(cover_path,image_name));
        imwrite(stego,strcat(stego_path,num2str(img_idx),'.pgm')); % save
    end
end
## python
import os
#------------创建文件夹--------------start
path = "/home/user/Documents/"
folder_name = "new_folder"
os.mkdir(os.path.join(path, folder_name))
#-----------创建文件夹--------------end

train_path = r'/home/train/' # 遍历文件夹
for file in os.listdir(train_path):
    print(file)
    fea_train = pd.read_csv(train_path + file, header=None,delimiter=' ')
    

3. 找遗漏的文件

## python
import csv
import os
from natsort import natsorted

folder_path = '/home/database/BOSS_all/BOSSbase_1.01'# 指定完整文件夹路径
file_names = [f.name for f in os.scandir(folder_path) if f.is_file()]# 获取指定文件夹下的所有文件名
sorted_image_files = natsorted(file_names) # 对文件名进行自然排序

sorted_image_files = [x[:-4] for x in sorted_image_files] # 去掉后缀.png
print(sorted_image_files)

# 指定要遍历的文件夹路径
fnns_path = '/home/train'
# 获取指定文件夹下的所有文件名
file_names = [f.name for f in os.scandir(fnns_path) if f.is_file()]
# 对文件名进行自然排序
sorted_fnns_files = natsorted(file_names)
sorted_fnns_files = [x[:-4] for x in sorted_fnns_files] # 去掉后缀.png
print(sorted_fnns_files)

# 求差集
set1 = set(sorted_image_files[:6000])
set2 = set(sorted_fnns_files)
result = list(set1 - set2)
print(result)

4. python多进程调用shell脚本命令

原因:很多数据集都要跑SRM,6000张图提取特征就14-15小时
下面代码块是单个数据集跑SRM的流程

#!/bin/bash
# 1. 修改当前路径,后续调用命令
cd /home/SRMQ1_linux_make_v1.1/release 
start_time=$(date +%s)

# 2. 创建一个包含要处理的文件夹的列表
# elements=("BOSSbase_1.01_256_catalan_75_pgm" "BOSSbase_1.01_256_catalan_80_pgm" "BOSSbase_1.01_256_catalan_85_pgm") # 放在database文件夹下
elements=($1) # $1 是取第1个参数 $2 是取第2个参数 这里就可以在调用的时候传参数

# 3. 使用 for 循环遍历列表中的每个元素并执行相应的操作 针对elements中有多个元素的情况,如果只有一个元素,可以去掉for循环
for algorithm in "${elements[@]}"
do
    echo "正在处理 $algorithm"
    # 1. 创建存特征的父文件夹
    create_folder_command="mkdir /home/SRMQ1_linux_make_v1.1/00_srmq1_fea/$algorithm"
    eval "$create_folder_command" # 将字符串转成命令执行
    echo "创建父文件夹结束"

    # 1.1 创建存特征的 train子文件夹
    create_folder_command="mkdir /home/SRMQ1_linux_make_v1.1/00_srmq1_fea/$algorithm/train"
    eval "$create_folder_command"

    # 1.2 创建存特征的test 子文件夹
    create_folder_command="mkdir /home/SRMQ1_linux_make_v1.1/00_srmq1_fea/$algorithm/test"
    eval "$create_folder_command"
    echo "创建子文件夹结束"

    # 2. 提取特征
    command="./SRMQ1 -I /home/00_database/${algorithm}/train -O /home/SRMQ1_linux_make_v1.1/00_srmq1_fea/$algorithm/train -V"

    eval "$command"
    echo "提取train特征结束"

    command="./SRMQ1 -I /home/00_database/${algorithm}/test -O /home/SRMQ1_linux_make_v1.1/00_srmq1_fea/$algorithm/test -V" 
    eval "$command" 
    echo "提取test特征结束" 

    # 3. 组合特征
    # 直接调用python命令
    /home/miniconda3/envs/steganogan/bin/python3 /home/SRMQ1_linux_make_v1.1/01_SubmodelConcatenation/01_submodel.py $algorithm

    # 4. 调用matlab训练

    command="matlab -nodesktop -nosplash -r \"addpath('/home/SRMQ1_linux_make_v1.1/02_train');srm_tra $algorithm '/home/SRMQ1_linux_make_v1.1/01_SubmodelConcatenation/q1_cover_train.csv' '/home/SRMQ1_linux_make_v1.1/01_SubmodelConcatenation/q1_cover_test.csv' '/home/SRMQ1_linux_make_v1.1/01_SubmodelConcatenation/q1_${algorithm}_train.csv' '/home/SRMQ1_linux_make_v1.1/01_SubmodelConcatenation/q1_${algorithm}_test.csv';exit()\""  

    eval "$command"
    echo "$algorithm SRM训练测试结束" 
done

end_time=$(date +%s)
elapsed_time=$((end_time - start_time))

# 转换为分钟和秒数
minutes=$((elapsed_time / 60))
seconds=$((elapsed_time % 60))
# 输出结果
echo "脚本已经运行了 ${minutes} 分钟 ${seconds} 秒。"

下面是多进程实现同时运行多个数据集跑SRM

import multiprocessing
import subprocess

def run_process(function):
    subprocess.call(["./srm_all.sh",function], cwd="/home/hello/workspace/jinghan/SRMQ1_linux_make_v1.1/release") 
    # cwd用于指定运行路径

if __name__ == "__main__":
    processes = []
    functions = [ # 多个进程,只有输入参数不同
        "\"BOSSbase_1.01_1024_catalan_80_pgm\"",  # 注意\是转义字符
        "\"BOSSbase_1.01_1024_catalan_85_pgm\"", 
        "\"BOSSbase_1.01_lsb_256_80_pgm\"",
        "\"BOSSbase_1.01_lsb_256_85_pgm\"",
        "\"BOSSbase_1.01_fnns_256_75_pgm\"",
        "\"BOSSbase_1.01_fnns_256_80_pgm\"",
        "\"BOSSbase_1.01_mean_256_75_pgm\"",
        "\"BOSSbase_1.01_mean_256_80_pgm\"",
    ]

    for function in functions:
        process = multiprocessing.Process(target=run_process, args=(function,)) # 创建进程,target是目标函数,args是run_process的参数,只有一个参数也需要用括号括起来
        processes.append(process) # 把进程加到列表中
        process.start() # 开启进程

    for process in processes:
        process.join() # 主进程等待子进程完成

3. 代码复现流程

  1. 灰度图尽量用pgm格式
  2. 开始的时候就分好数据集split_dataset,train:valid:test=6:2:2,SRM隐写分析是5:5
  3. 文件夹命名用数字_名字,比如00_预处理。所有数据命名要规范,统一。目前主要用到的有数据集(命名规范:数据集_方法_容量_其他属性),代码(能用Git的尽量用),结果(腾讯文档)
  4. 绘制要做的实验流程图(代码),保存状态,输入和输出路径,日期,统计数据(notion数据库),尽量整理成工作流

你可能感兴趣的:(论文复现,论文阅读)