摘要:恢复原图像数据该恢复过程分为三步复原开销信息根据开销信息中保存的原像素位置,将对应位置像素灰度值置为。
这是一篇06年发表的针对可逆数据隐藏的经典研究论文(IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY , VOL. 16, NO. 3, MARCH 2006),笔者使用python将原论文中的算法进行实现。
一,嵌入操作(算法实现)
1.所使用的库函数
import cv2 as cvimport matplotlib.pyplot as pltimport 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 binshistogram, bins, patch = plt.hist(pixelSequence, numberBins, facecolor="blue", histtype="stepfilled") # histogramingmax_a = max(histogram) # max pixel numbermin_b = min(histogram) # min pixel numberhistogram_list = histogram.tolist()MaxPoint = histogram_list.index(max(histogram_list))+1 # max gray valueMinPoint = histogram_list.index(min(histogram_list))+1 # min gray value# judge the min pixel number is 0 or notBookKeeping = []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 datan = 0for 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->512pixelSequence = img.reshape([h * w, ]) # [262144,]
2.提取隐藏数据
扫描整幅图像:
1)当遇到像素灰度值为a-1,提取1;
2)当遇到像素灰度值为a,提取0。
Recover_Data = []count = 0for 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])
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/121935.html
摘要:什么是推导式大家好,今天为大家带来问我最喜欢的推导式使用指南,让我们先来看看定义推导式是的一种独有特性,推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 什么是推导式 大家好,今天为大家带来问我最喜欢的Python推导式使用指南,让我们先来看看定义~ 推导式(comprehensions)是Python的一种独有特性,推导式是可以从一个数据序列构建另一个新的数据序列的结构体。...
摘要:昨天的比赛又一次见识到了大师傅们多么厉害,疯狂上分,可怜如我,只做出了四个杂项。暑假这三个月都没有做题,明年就要专升本了,所以一直在看高数英语嗐,高中贪玩儿的后果。 ...
摘要:的作用是让大容量信息在用数字签名软件签署私人密钥前被压缩成一种保密的格式就是把一个任意长度的字节串变换成一定长的十六进制数字串。获取由位随机大小写字母数字组成的值每次从中随机取一位获取原始密码的值原始密码随机生成位加密后的密码 MD5是什么 下面的概念是百度百科的: Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列...
摘要:相对于静态图表,人类总是容易被动画和交互式图表所吸引。可以使用轻松生成图表直方图功率谱,条形图,错误图表,散点图等。然而,也有一些方面落后于同类的库。动画使用一组固定的对象。稍后将用数据对行对象进行填充。现在用将它们转换为动画。 翻译:疯狂的技术宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...
摘要:相对于静态图表,人类总是容易被动画和交互式图表所吸引。可以使用轻松生成图表直方图功率谱,条形图,错误图表,散点图等。然而,也有一些方面落后于同类的库。动画使用一组固定的对象。稍后将用数据对行对象进行填充。现在用将它们转换为动画。 翻译:疯狂的技术宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...
阅读 2956·2023-04-25 17:19
阅读 446·2021-11-23 09:51
阅读 1202·2021-11-08 13:19
阅读 1513·2021-10-09 09:41
阅读 592·2021-09-29 09:34
阅读 1459·2021-09-28 09:36
阅读 1273·2021-09-22 14:59
阅读 2573·2019-08-29 16:38