OpenCV入门教程03.13:DFT(离散傅利叶变换)
索引地址:系列索引
DFT
离散傅里叶变换(Discrete Fourier Transform,DFT)傅里叶分析方法是信号分析的最基本方法,傅里叶变换是傅里叶分析的核心,通过它把信号从时间域变换到频率域,进而研究信号的频谱结构和变化规律。
具体介绍:DFT
OpenCV提供的dft函数为:
1 |
|
参数解释:
- InputArray src: 输入图像,可以是实数或虚数
- OutputArray dst: 输出图像,其大小和类型取决于第三个参数flags
- int flags = 0: 转换的标识符,有默认值0.其可取的值如下所示:
- DFT_INVERSE: 用一维或二维逆变换取代默认的正向变换
- DFT_SCALE: 缩放比例标识符,根据数据元素个数平均求出其缩放结果,如有N个元素,则输出结果以1/N缩放输出,常与DFT_INVERSE搭配使用。
- DFT_ROWS: 对输入矩阵的每行进行正向或反向的傅里叶变换;此标识符可在处理多种适量的的时候用于减小资源的开销,这些处理常常是三维或高维变换等复杂操作。
- DFT_COMPLEX_OUTPUT: 对一维或二维的实数数组进行正向变换,这样的结果虽然是复数阵列,但拥有复数的共轭对称性(CCS),可以以一个和原数组尺寸大小相同的实数数组进行填充,这是最快的选择也是函数默认的方法。你可能想要得到一个全尺寸的复数数组(像简单光谱分析等等),通过设置标志位可以使函数生成一个全尺寸的复数输出数组。
- DFT_REAL_OUTPUT: 对一维二维复数数组进行逆向变换,这样的结果通常是一个尺寸相同的复数矩阵,但是如果输入矩阵有复数的共轭对称性(比如是一个带有DFT_COMPLEX_OUTPUT标识符的正变换结果),便会输出实数矩阵。
- int nonzeroRows = 0: 当这个参数不为0,函数会假设只有输入数组(没有设置DFT_INVERSE)的第一行或第一个输出数组(设置了DFT_INVERSE)包含非零值。这样的话函数就可以对其他的行进行更高效的处理节省一些时间,这项技术尤其是在采用DFT计算矩阵卷积时非常有效。
测试代码:
1 |
|
测试效果:
盲水印
水印
普通的水印就是在原始图片上添加文字、图像来表示所有权。
但是这类水印可以通过打马赛克、图片截取的方式规避。
那么实现就简单一点,使用Qt读取图片,然后在图片上绘制文字即可。
1 |
|
使用类包装接口,动态修改字体大小、水印内容、水印位置、水印框
带水印框效果(水印框没有什么用,只是用来矫正效果)
盲水印
盲水印,即不可见水印,使用算法将水印信息嵌入图片中。
就算图片二次修改、截取、破坏,水印信息也可以完整恢复出来。
要求
水印要求在以下操作后还能恢复:
- 涂抹、椒盐、模糊
- 亮度
- 对比度
- 截取、横向裁剪、纵向裁剪
- 旋转
- 缩放
- 格式转换、jpg压缩
- 截图
- 拍照
LSB法
LSB(Least Signifcant Bit,最低有效位)
1 |
|
最低有效位为01100001 = 0x61 = A
这样我们就把字母A藏到了图片数据里。
如果图片被截取、拍照,那么数据就丢失了。
DFT(离散傅里叶变换)
在OpenCV入门教程044:DFT(离散傅利叶变换)中介绍过DFT。
原理是:
- 将图片进行傅里叶变换,得到表示四向限灰度情况的灰度图
- 在灰度图上添加文字、图片
- 将灰度图变换为正常图
解析水印的原理就是
- 将图片解析傅里叶变换,就可以得到灰度图,此灰度图上包含水印
添加水印
1 |
|
结果和原图没什么变换。
解水印
1 |
|
这一步最重要,要可以从添加水印的图片结果中提取出水印,否则就没有意义了
频域变换法
离散余弦变换(Discrete Cosine Transform,DCT)
离散小波变换(Discrete Wavelet Transform,DWT)
字形变换法
patchwork
基于神经网络的算法
OpenCV入门教程03.13:DFT(离散傅利叶变换)
https://blog.jackeylea.com/opencv/opencv-dft/