线性滤波/卷积
(注:这部分摘自这篇博客)
线性滤波可以说是图像处理最基本的方法,它可以允许我们对图像进行处理,产生很多不同的效果。做法很简单。首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像。然后,对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。这样就完成了滤波过程。
对图像和滤波矩阵进行逐个元素相乘再求和的操作就相当于将一个二维的函数移动到另一个二维函数的所有位置,这个操作就叫卷积或者协相关。卷积和协相关的差别是,卷积需要先对滤波矩阵进行180的翻转,但如果矩阵是对称的,那么两者就没有什么差别了。
实际应用——加密
很多我们熟知的图像处理其实都可以由由滤波和卷积简单做到。比如锐化,软化,浮雕及高斯模糊,具体效果及原理可看这篇文章
加密是社会中一项很重要的应用,也是信息传播中的一项重要安全措施。对于这个问题,本人思考了下滤波在图像加密中的应用。滤波和卷积都存在对应的逆操作,要想对图像加密的话,选定一个甚至多个卷积核对图像进行变换从而可以得到一个隐含内容的无规则图样。解密的时候需要按照对应的顺序进行对应的逆操作便能得到原图样。但是逆滤波和逆卷积涉及的知识面都比较深在下还没怎么弄懂orz。想要更深入学习的可以参考逆滤波及反卷积。
这里介绍一种在下自己思考的一种比较简单的加密算法。
二维前缀和思想
假如我们选定卷积核为中心及中心的左上区域都为1的矩阵对图像进行操作,可以想见加密图样的每个像素点都是对应位置的原图像及其左上方一定区域内的信息之和,我们称之为前缀和,需要注意的是这个前缀和不是某位置及左上部分所有信息之和而是有一定范围内的。下图展示了4*4的图像矩阵的滤波过程。
可以看到左上第一个像素点由于左上没有其他信息了,所以加密后的对应点信息就是其本身。它右边面第一个像素点加密后则有其本身和最左上像素点信息之和。减去最左上信息则可得到第二个点的原信息。依次类推,我们可以还原图像的全部信息。参考代码如下:
#include<stdio.h>
#include<algorithm>
using namespace std;
int m;//原图像大小m*m
int s1[200][200];//原图像
int s2[200][200]={
{
0,1,3,5},
{
4,10,14,18},
{
12,26,30,34},
{
20,42,46,50}};//加密图像
int n;//卷积核大小n*n
int r;//卷积核半径
int c[200][200]={
{
1,1,0},
{
1,1,0},
{
0,0,0}};//convolution kernel 卷积核
void read()
{
scanf("%d",&m);
for(int i=0;i<m;i++)