信息隐藏课老师布置了作业,要求是把校徽嵌入一段音频里:
完整代码数据+PPT:
链接:https://pan.baidu.com/s/1JDcgrZeuJrQelN6WyiN0hg
提取码:9qyr
最终我采用的是将校徽转成二值图像然后化成矩阵的形式,将水印图像转化为01比特流
最终选择了两种嵌入方法,一种是新加一个信道,一种是在原来的信道上嵌入信息
在实验时用的是python,安装ffmpeg时遇到了一些问题,最终直接使用conda安装,解决了问题
conda install -c https://conda.anaconda.org/menpo ffmpeg
关键代码如下:
添加水印
def add_signerature(wav_path='test_wav.wav'):
# 往wav文件中添加水印
signerature_array = list(image2binary())
array_length = len(signerature_array)
fs, sig = wav.read('test_wav.wav')
block_length = len(sig) // array_length
print(block_length, array_length)
result = []
count = 0
for each_row in sig:
count = count + 1
byte2insert = signerature_array[min(count // block_length, len(signerature_array) - 1)]
if byte2insert == 255:
byte2insert = 1
third_channel_value = 10
else:
byte2insert = 0
third_channel_value = -10
each_row = list(each_row)
if (each_row[1] - each_row[0]) % 2 != byte2insert:
each_row[0] = each_row[0] + 1
result.append(each_row + [third_channel_value])
result = np.array(result)
wav_path = 'signeratured_' + wav_path
wav.write(wav_path, fs, result.astype('int16'))
提取水印
def get_signerature_thirdchannel(wav_path='signeratured_test_wav.wav', array_length=22500):
# 提取水印变成图片显示,从第三信道提取水印
fs, sig = wav.read(wav_path)
zero_count = 0
one_count = 0
count = 0
signerature_list = []
value_dict = {}
for each_row in sig:
each_row = list(each_row)
if abs(each_row[2]) in value_dict.keys():
value_dict.update({abs(each_row[2]): value_dict.get(abs(each_row[2])) + 1})
else:
value_dict.update({abs(each_row[2]): 1})
max = -1
for each_key in value_dict.keys():
if value_dict.get(each_key) > max:
max = value_dict.get(each_key)
target_value = each_key
sig_removenoise = []
for each_row in sig:
each_row = list(each_row)
if abs(abs(each_row[2]) -target_value)<=5:
sig_removenoise.append(each_row)
block_length = len(sig_removenoise) // array_length
for each_row in sig_removenoise:
count = count + 1
if zero_count >= block_length:
signerature_list.append(0)
zero_count = 0
if one_count >= block_length:
signerature_list.append(255)
one_count = 0
message = each_row[2]
if message > 0 :
one_count = one_count + 1
else:
zero_count = zero_count + 1
array2pic(signerature_list)