目录

  • 1 OpenCV入门
    • 1.1 如何使用
    • 1.2 图像读入、显示与保存
  • 2 图像处理基础
    • 2.1 图像处理入门基础
    • 2.2 像素处理
    • 2.3 numpy访问像素
    • 2.4 获取图像属性
    • 2.5 感兴趣区域ROI
    • 2.6 通道操作
  • 3 图像运算
    • 3.1 图像加法
    • 3.2 图像融合
    • 3.3 位平面分解
    • 3.4 图像加密和解密
    • 3.5 数字水印
  • 4 色彩空间类型转换
    • 4.1 色彩类型转换
  • 5 几何变换
    • 5.1 图像缩放
    • 5.2 图像翻转
  • 6 阈值处理
    • 6.1 阈值理论知识
    • 6.2 阈值处理实践
  • 7 图像平滑处理
    • 7.1 均值滤波
    • 7.2 方框滤波
    • 7.3 高斯滤波
    • 7.4 中值滤波
  • 8 形态学操作
    • 8.1 图像腐蚀
    • 8.2 图像膨胀
    • 8.3 开运算
    • 8.4 闭运算
    • 8.5 梯度运算
    • 8.6 礼帽操作
    • 8.7 黑帽图像处理
  • 9 图像梯度
    • 9.1 Sobel理论基础
    • 9.2 Sobel算子及函数使用
    • 9.3 Scharr算子及函数使用
    • 9.4 Sobel算子和Scharr算子的比较
    • 9.5 Laplacian算子及函数使用
  • 10 canny边缘检测
    • 10.1 Canny边缘检测原理
    • 10.2 Canny函数及使用
  • 11 图像金字塔
    • 11.1 理论基础
    • 11.2 pyrDown函数及使用
    • 11.3 pyrUp函数及使用
    • 11.4 采样可逆性的研究
    • 11.5 拉普拉斯金字塔
  • 12 图像轮廓
    • 12.1 图像轮廓操作
  • 13 直方图
    • 13.1 直方图的概念
    • 13.2 绘制直方图
    • 13.3 使用OpenCV统计直方图
    • 13.4 绘制OpenCV统计直方图
    • 13.5 使用掩膜的直方图
    • 13.6 掩膜原理及演示
    • 13.7 直方图均衡化原理
    • 13.8 直方图均衡化函数equalizeHist
    • 13.9 subplot函数的使用
    • 13.10 matplotlib.pyplot.imshow函数的使用
    • 13.11 直方图均衡化对比
  • 14 傅里叶变换
    • 14.1 傅里叶变换的理论基础
    • 14.2 numpy实现傅里叶变换
    • 14.3 numpy实现逆傅里叶变换
    • 14.4 高通滤波演示
    • 14.5 OpenCV实现傅里叶变换
    • 14.6 OpenCV实现逆傅里叶变换
    • 14.7 低通滤波示例
数字水印

3.8数字水印

最低有效位:指的是一个二进制数中的第0位(最低有效位)。

最低有效位信息隐藏:将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位,

 

原理:

嵌入过程:将载体图像的第0个位平面替换为数字水印信息(一幅二值图像)

提取过程:将载体图像的最低有效位所构成的第0个位平面提取出来,得到数字水印信息。

1.    嵌入过程

原始载体图像预处理

将原始图像处理为二进制,并标记出最低有效位

水印图像处理

在嵌入水印前,需要将水印信息处理为二值图像,将灰度二值水印信息进行阈值处理。

嵌入水印

将载体图像的最低有效位替换为二进制水印图像,完成水印的嵌入

2.    提取过程

提取过程是指将水印信息从包含水印信息的载体图像内提取出来的过程,提取水印时,先将含水印载体图像的像素值转换为二进制,然后从其最低有效位提取出水印信息即可。

 

实现方法:

1.    嵌入过程

(1)载体图像预处理

读取原始载体图像O,并获取载体图像的行数N和列数M,将其标记对应的二进制形式OB

(2)建立提取矩阵

建立一个M*N大小,元素值均为254的提取矩阵(数组),用来提取载体图像的高七位。

(3)保留载体图像的高七位,将最低位置0

需要将载体图像与元素值均为254的提取矩阵进行按位与运算。

(4)水印图像处理

当水印图像为8位灰度图的二值图像时,就需要将其转换为二进制二值图像,将其中的像素值255转换为像素值1

(5)嵌入水印

将原始载体图像进行“保留高七位、最低位置0”的操作后,得到一副新的图像,将新图像与水印图像进行按位或运算,就能实现将水印信息嵌入原始载体图像内的效果。

(6)显示图像

完成上述处理后,分别显示原始载体图像、水印图像、含水印图像

2.    提取过程

(1)含水印载体图像处理

读取包含水印的载体图像,获取含水印载体图像的大小M*N

(2)建立提取矩阵

定义一个与含水印载体图像等大小的值为1的矩阵(数组)作为提取矩阵

(3)提取水印信息

将含水印载体图像与提取矩阵进行按位与运算,提取水印信息。

(4)计算去除水印后的载体图像

有时需要删除包含在水印载体图像内的水印信息,通过将含水印载体图像的最低有效位置零,即可实现删除水印信息。

通过将含有水印载体图像WOTB进行按位与运算,即可将载体图像WO的最低有效位置零,得到删除水印信息的载体图像ODW

(5)显示图像

根据需要,分别显示提取出来的水印图像WG、删除水印信息的载体图像ODW

 
 
#3.15编写程序,模拟数字水印的嵌入和提取过程
import cv2
import numpy as np
#
读取原始载体图像
lena=cv2.imread("lena.bmp",0)
#
读取水印图像
watermark=cv2.imread("watermark.bmp",0)
#
将水印内的255处理为1,以方便嵌入
#
后续章节会介绍使用threshold处理。
w=watermark[:,:]>0
watermark[w]=1
#
读取原始载体图像的shape
r,c=lena.shape
#============
嵌入过程============
#
生成内部值都是254的数组
t254=np.ones((r,c),dtype=np.uint8)*254
#
获取lena图像的高7
lenaH7=cv2.bitwise_and(lena,t254)
#
watermark嵌入到lenaH7
e=cv2.bitwise_or(lenaH7,watermark)
#============
提取过程============
#
生成内部值都是1的数组
t1=np.ones((r,c),dtype=np.uint8)
#
从载体图像内,提取水印图像
wm=cv2.bitwise_and(e,t1)
print(wm)
#
将水印内的1处理为255以方便显示
#
后续章节会介绍threshold实现。
w=wm[:,:]>0
wm[w]=255
#============
显示============
cv2.imshow("lena",lena)
cv2.imshow("watermark",watermark*255)   #
当前watermark内最大值为1
cv2.imshow("e",e)
cv2.imshow("wm",wm)
cv2.waitKey()
cv2.destroyAllWindows()
 
#3.16编写程序,使用掩码对lena图像的脸部进行打码、解码
import cv2
import numpy as np
#
读取原始载体图像
lena=cv2.imread("lena.bmp",0)
#
读取原始载体图像的shape
r,c=lena.shape
mask=np.zeros((r,c),dtype=np.uint8)
mask[220:400,250:350]=1
#
获取一个key,打码、解码所使用的密钥
key=np.random.randint(0,256,size=[r,c],dtype=np.uint8)
#============
获取打码脸============
#
使用密钥key加密原始图像lena
lenaXorKey=cv2.bitwise_xor(lena,key)
#
获取加密图像的脸部信息encryptFace
encryptFace=cv2.bitwise_and(lenaXorKey,mask*255)
#
将图像lena内的脸部值设置为0,得到noFace1
noFace1=cv2.bitwise_and(lena,(1-mask)*255)
#
得到打码的lena图像
maskFace=encryptFace+noFace1
#============
将打码脸解码============
#
将脸部打码的lena与密钥key异或,得到脸部的原始信息
extractOriginal=cv2.bitwise_xor(maskFace,key)
#
将解码的脸部信息extractOriginal提取出来得到extractFace
extractFace=cv2.bitwise_and(extractOriginal,mask*255)
#
从脸部打码的lena内提取没有脸部信息的lena图像,得到noFace2
noFace2=cv2.bitwise_and(maskFace,(1-mask)*255)
#
得到解码的lena图像
extractLena=noFace2+extractFace
#============
显示图像============
cv2.imshow("lena",lena)
cv2.imshow("mask",mask*255)
cv2.imshow("1-mask",(1-mask)*255)
cv2.imshow("key",key)
cv2.imshow("lenaXorKey",lenaXorKey)
cv2.imshow("encryptFace",encryptFace)
cv2.imshow("noFace1",noFace1)
cv2.imshow("maskFace",maskFace)
cv2.imshow("extractOriginal",extractOriginal)
cv2.imshow("extractFace",extractFace)
cv2.imshow("noFace2",noFace2)
cv2.imshow("extractLena",extractLena)
cv2.waitKey()
cv2.destroyAllWindows()
 
 
#图层提取
import cv2
import numpy as np
lena=cv2.imread("lena.bmp",0)
cv2.imshow("lena",lena)
r,c=lena.shape
x=np.zeros((r,c,8),dtype=np.uint8)
for i in range(8):
    x[:,:,i]=2**i
r=np.zeros((r,c,8),dtype=np.uint8)
for i in range(8):
    r[:,:,i]=cv2.bitwise_and(lena,x[:,:,i])
    mask=r[:,:,i]>0
    r[mask]=255
    cv2.imshow(str(i),r[:,:,i])
cv2.waitKey()
cv2.destroyAllWindows()