IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> Reversible Data Hiding 可逆数据隐藏的python实现 -> 正文阅读

[人工智能]Reversible Data Hiding 可逆数据隐藏的python实现

这是一篇06年发表的针对可逆数据隐藏的经典研究论文(IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY , VOL. 16, NO. 3, MARCH 2006),笔者使用python将原论文中的算法进行实现。

一,算法介绍

1.算法目的:

????????该算法分为信息隐藏信息提取两个部分。前者是将一组二进制数据嵌入到原图像中,且不影响原图像的显示内容。后者是将已嵌入信息的处理图像进行信息提取并还原图像信息。

2.信息隐藏:

? ? ? ? 1)生成原图像的灰度直方图H(x),寻找H(x)中的最大值H(a)和最小值H(b),其中的最大值点a和最小值点b对应原图像中数量最多和数量最少的灰度值。

? ? ? ? 2)如果最小值H(b)是非零的,需要将原图像中该最小灰度值的像素信息进行另存(即开销信息O),然后将这些像素的灰度值重新编码(具体操作在算法实现中我会讲解),使最小灰度值的像素数量为0,即H(b) = 0,得到的开销信息后面和隐藏信息一起嵌入到图像中。

? ? ? ? 3)为了保持一般性,假设最小值点b > 最大值点a,将原图像中灰度值在(b,a)之间的像素灰度值加1(如果b<a,则减1),对于图像像素的整体变换,而且变换大小只有一个灰度值,这对图像的正常内容显示不会产生影响。此时,直方图中H(a+1)=0,而H(a)是最大值,则这一组(a,b)中的数据嵌入量C为:C=H(a) - O,其中O表示H(b)的开销信息,在2)中已经进行另存处理。

? ? ? ? 4)开始嵌入操作,扫描整幅图像,当遇到灰度值为a的像素,检查嵌入数据,如果嵌入数据为1,则将该像素灰度值加1;如果嵌入数据为0,则保持不变。

3.信息提取:

3.1提取隐藏数据:

????????扫描整幅图像,当遇到像素灰度值为a+1时,提取”1”,当遇到像素灰度值为a时,提取”0”。

3.2恢复图像数据:

? ? ? ? 1)复原开销信息:获取开销信息长度,用以提取后面的开销信息。根据开销信息中保存的原像素位置,将对应像素的灰度值置为b。

????????2)将直方图中灰度值在[b,a)间的像素整体减1(b>a则加1),即左移一个单位。经过以上两步操作,图像的原始信息和隐藏信息得到分离,图像没有任何损失。

二,嵌入操作(算法实现)

1.所使用的库函数

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np

2.读取数据

为了满足读取图像以及保存图像的无损过程,本文采用格式为PNG的图像。(JPEG图像使用imwrite函数无法无损保存)

为便于操作,本文使用“Lena”的灰度图像,获取图像各像素灰度值后将其转化为一维数组,便于后续操作。

img = cv.imread("lena.png",0)  # Use the classical Image 'Lena'
h, w = img.shape[:2]  # 512 * 512 
pixelSequence = img.reshape([h * w, ])	# [262144,]

3.寻找直方图最值点

通过直方图,判断最大值点a和最小值点b。如果最小值非零,即将原图像中灰度值为该最小值的像素位置打包为开销信息(另外保存),然后将像素值置为(b,a)之外的值,因为最小值的数量少,不会影响图像整体显示。(本文将最小值左移一位,即b-1)

numberBins = [i + 0.5 for i in list(range(0, 256))]  # set the range of bins
histogram, bins, patch = plt.hist(pixelSequence, numberBins, 
facecolor='blue', histtype='stepfilled')  # histograming

max_a = max(histogram)  # max pixel number
min_b = min(histogram)	# min pixel number
histogram_list = histogram.tolist()
MaxPoint = histogram_list.index(max(histogram_list))+1  # max gray value
MinPoint = histogram_list.index(min(histogram_list))+1  # min gray value

# judge the min pixel number is 0 or not
BookKeeping = []
if min_b != 0:
	for i in range(len(pixelSequence)):
		if pixelSequence[i] == MinPoint:
			BookKeeping.append(i)
			pixelSequence[i] = MinPoint - 1

4.移动直方图

在不丧失一般性的情况下,且根据max/min函数的特性,本文的最小值点b < 最大值点a。因此,只需将灰度值在(b,a)以内(不包括a,b)的像素灰度值减1即可。

for i in range(len(pixelSequence)):
	if MinPoint < pixelSequence[i] < MaxPoint:
		pixelSequence[i] -= 1

5.嵌入数据

根据算法原理,嵌入数据为二进制数组。扫描整幅图像,遇到灰度值为最大值点a时进行判断(假设此时扫描到像素n):

????????1)如果嵌入值为1时,像素n的灰度值-1;

? ? ? ? 2)如果嵌入值为0时,像素n的灰度值保存不变。

Hidden_Data = [1,1,0,0,1,0,1,0,0,1,1] # hidden data
n = 0
for i in range(len(pixelSequence)):
	if pixelSequence[i] == MaxPoint:
		if Hidden_Data[n] == 1:
			pixelSequence[i] -= 1
		else:
			pass
		n += 1	
		if n == len(Hidden_Data):
			break

6.生成处理图像

使用cv.imwrite函数,其中[cv.IMWRITE_PNG_COMPRESSION, Compression Ratio]的第二个参数表示压缩比例,从0~9,数值越高压缩比例越高。(笔者测试:无论设置压缩比例为多少,图像的像素序列以及灰度值都不会变,但是图像的内存会减小)

Marked_Image = pixelSequence.reshape(h, w)
cv.imwrite('Marked_Image.png', Marked_Image, [cv.IMWRITE_PNG_COMPRESSION, 0])

三.提取还原操作(算法实现)

上一部分已经将数据嵌入到图像中,提取还原只需要对之前的步骤进行逆向操作即可。

1.读取图像

img = cv.imread("Marked_Image.png",0)  # Use the classical Image 'Lena'
h, w = img.shape[:2]  # get the pixel's high->512 and wide->512
pixelSequence = img.reshape([h * w, ])	# [262144,]

2.提取隐藏数据

扫描整幅图像:

? ? ? ? 1)当遇到像素灰度值为a-1,提取1;

? ? ? ? 2)当遇到像素灰度值为a,提取0。

Recover_Data = []
count = 0
for i in range(len(pixelSequence)):
	if pixelSequence[i] == MaxPoint-1:
		Recover_Data.append(1)
		count += 1
	if pixelSequence[i] == MaxPoint:
		Recover_Data.append(0)
		count += 1
	if count == len(Hidden_Data):
		break

现在,我们打印隐藏数据和恢复数据:

print('Hidden_Data:',Hidden_Data)		
print('Recover_Data:',Recover_Data)	

显然,二者应该相等。

Hidden_Data: [1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1]
Recover_Data: [1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1]

3.恢复原图像数据

该恢复过程分为三步:

????????1)复原开销信息:根据开销信息中保存的原像素位置,将对应位置像素灰度值置为b。

for i in range(len(BookKeeping)):
	pixelSequence[BookKeeping[i]] = MinPoint

? ? ? ? 2)直方图[b,a)整体右移一个单位。

for i in range(len(pixelSequence)):
	if MinPoint <= pixelSequence[i] <= MaxPoint-1:
		pixelSequence[i] += 1

? ? ? ? 3)恢复原图像。

Recover_Image = pixelSequence.reshape(h,w)
cv.imwrite('Recover_Image.png', Recover_Image, [cv.IMWRITE_PNG_COMPRESSION, 0])

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:16:59  更:2021-10-09 16:17:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 10:35:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码