Xinwei: 写的通俗易懂,终于让我这个不搞CV、不搞图像的外行理解卷积和滤波了。html
图像卷积与滤波的一些知识点算法
http://blog.csdn.net/zouxy09oop
以前在学习CNN的时候,有对卷积进行一些学习和整理,后来就烂尾了,如今稍微整理下,先放上来,以提醒和交流。学习
1、线性滤波与卷积的基本概念优化
线性滤波能够说是图像处理最基本的方法,它能够容许咱们对图像进行处理,产生不少不一样的效果。作法很简单。首先,咱们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像。而后,对于图像的每个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,而后加起来,做为该像素位置的值。这样就完成了滤波过程。ui
对图像和滤波矩阵进行逐个元素相乘再求和的操做就至关于将一个二维的函数移动到另外一个二维函数的全部位置,这个操做就叫卷积或者协相关。卷积和协相关的差异是,卷积须要先对滤波矩阵进行180的翻转,但若是矩阵是对称的,那么二者就没有什么差异了。spa
Correlation 和 Convolution能够说是图像处理最基本的操做,但却很是有用。这两个操做有两个很是关键的特色:它们是线性的,并且具备平移不变性shift-invariant。平移不变性指咱们在图像的每一个位置都执行相同的操做。线性指这个操做是线性的,也就是咱们用每一个像素的邻域的线性组合来代替这个像素。这两个属性使得这个操做很是简单,由于线性操做是最简单的,而后在全部地方都作一样的操做就更简单了。.net
实际上,在信号处理领域,卷积有普遍的意义,并且有其严格的数学定义,但在这里不关注这个。orm
2D卷积须要4个嵌套循环4-double loop,因此它并不快,除非咱们使用很小的卷积核。这里通常使用3x3或者5x5。并且,对于滤波器,也有必定的规则要求:
1)滤波器的大小应该是奇数,这样它才有一个中心,例如3x3,5x5或者7x7。有中心了,也有了半径的称呼,例如5x5大小的核的半径就是2。
2)滤波器矩阵全部的元素之和应该要等于1,这是为了保证滤波先后图像的亮度保持不变。固然了,这不是硬性要求了。
3)若是滤波器矩阵全部元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,若是小于1,那么获得的图像就会变暗。若是和为0,图像不会变黑,但也会很是暗。
4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种状况,咱们将他们直接截断到0和255之间便可。对于负数,也能够取绝对值。
2、神奇的卷积核
上面说到,对图像的滤波处理就是对图像应用一个小小的卷积核,那这个小小的卷积核到底有哪些魔法,能让一个图像从惨不忍睹变得秀色可餐。下面咱们一块儿来领略下一些简单但不简单的卷积核的魔法。
2.一、啥也不作
哈哈,你们能够看到啥了吗?这个滤波器啥也没有作,获得的图像和原图是同样的。由于只有中心点的值是1。邻域点的权值都是0,对滤波后的取值没有任何影响。
下面咱们动点真格的。
2.二、图像锐化滤波器Sharpness Filter
图像的锐化和边缘检测很像,首先找到边缘,而后把边缘加到原来的图像上面,这样就强化了图像的边缘,使图像看起来更加锐利了。这二者操做统一块儿来就是锐化滤波器了,也就是在边缘检测滤波器的基础上,再在中心的位置加1,这样滤波后的图像就会和原始的图像具备一样的亮度了,可是会更加锐利。
咱们把核加大,就能够获得更加精细的锐化效果
另外,下面的滤波器会更强调边缘:
主要是强调图像的细节。最简单的3x3的锐化滤波器以下:
其实是计算当前点和周围点的差异,而后将这个差异加到原来的位置上。另外,中间点的权值要比全部的权值和大于1,意味着这个像素要保持原来的值。
2.三、边缘检测Edge Detection
咱们要找水平的边缘:须要注意的是,这里矩阵的元素和是0,因此滤波后的图像会很暗,只有边缘的地方是有亮度的。
为何这个滤波器能够寻找到水平边缘呢?由于用这个滤波器卷积至关于求导的离散版本:你将当前的像素值减去前一个像素值,这样你就能够获得这个函数在这两个位置的差异或者斜率。下面的滤波器能够找到垂直方向的边缘,这里像素上和下的像素值都使用:
再下面这个滤波器能够找到45度的边缘:取-2不为了什么,只是为了让矩阵的元素和为0而已。
那下面这个滤波器就能够检测全部方向的边缘:
为了检测边缘,咱们须要在图像对应的方向计算梯度。用下面的卷积核来卷积图像,就能够了。但在实际中,这种简单的方法会把噪声也放大了。另外,须要注意的是,矩阵全部的值加起来要是0.
2.四、浮雕Embossing Filter
浮雕滤波器能够给图像一种3D阴影的效果。只要将中心一边的像素减去另外一边的像素就能够了。这时候,像素值有多是负数,咱们将负数当成阴影,将正数当成光,而后咱们对结果图像加上128的偏移。这时候,图像大部分就变成灰色了。
下面是45度的浮雕滤波器
咱们只要加大滤波器,就能够获得更加夸张的效果了
这种效果很是的漂亮,就像是将一副图像雕刻在一块石头上面同样,而后从一个方向照亮它。它和前面的滤波器不一样,它是非对称的。另外,它会产生负数值,因此咱们须要将结果偏移,以获得图像灰度的范围。
A:原图像。B:锐化。C:边缘检测。D:浮雕
2.五、均值模糊Box Filter (Averaging)
咱们能够将当前像素和它的四邻域的像素一块儿取平均,而后再除以5,或者直接在滤波器的5个地方取0.2的值便可,以下图:
能够看到,这个模糊仍是比较温柔的,咱们能够把滤波器变大,这样就会变得粗暴了:注意要将和再除以13.
因此,若是你想要更模糊的效果,加大滤波器的大小便可。或者对图像应用屡次模糊也能够。
2.六、高斯模糊
均值模糊很简单,但不是很平滑。高斯模糊就有这个优势,因此被普遍用在图像降噪上。特别是在边缘检测以前,都会用来移除细节。高斯滤波器是一个低通滤波器。
2.七、运动模糊Motion Blur
运动模糊能够经过只在一个方向模糊达到,例以下面9x9的运动模糊滤波器。注意,求和结果要除以9。
这个效果就好像,摄像机是从左上角移动的右下角。
3、卷积的计算
对图像处理而言,存在两大类的方法:空域处理和频域处理!空域处理是指直接对原始的像素空间进行计算,频率处理是指先对图像变换到频域,再作滤波等处理。
3.一、空域计算-直接2D卷积
3.1.一、2D卷积
直接2D卷积就是一开始说的那样,对于图像的每个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,而后加起来,做为该像素位置的值。
直接的实现也称为暴力实现brute force,由于它严格按照定义来实现,没有任何优化。固然了,在并行实现里面,它也是比较灵活的。另外,也存在一个优化版本,若是咱们的kernel是separable可分的,那么就能够获得一个快5倍左右的卷积方法。
2.1.二、边界处理
那卷积核遇到图像边缘怎么办?例如图像顶部的像素,它的上面已经没有像素了,那么它的值如何计算?目前有四种主流的处理方法,咱们用一维卷积和均值滤波来讲明下。
咱们在1D图像中,用每一个像素和它的二邻域的平均值来取代它的值。假设咱们有个1D的图像I是这样的:
对非图像边界的像素的操做比较简单。假设咱们对I的第四个像素3作局部平均。也就是咱们用2,3和7作平均,来取代这个位置的像素值。也就是,平均会产生一副新的图像J,这个图像在相同位置J (4) = (I(3)+I(4)+I(5))/3 = (2+3+7)/3 = 4。一样,咱们能够获得J(3) = (I(2)+I(3)+I(4))/3 =(4+2+3)/3 = 3。须要注意的是,新图像的每一个像素都取决于旧的图像,在计算J (4)的时候用J (3)是不对的,而是用I(3),I(4)和I(5)。因此每一个像素都是它和它邻域两个像素的平均。平均是线性的操做,由于每一个新的像素都是旧像素的线性组合。
对卷积,也有必需要考虑的状况是,在图像边界的时候,怎么办?J(1)的值应该是什么?它取决于I(0),I(1)和I(2)。可是咱们没有I(0)呀!图像左边没有值了。有四种方式来处理这个问题:
1)第一种就是想象I是无限长的图像的一部分,除了咱们给定值的部分,其余部分的像素值都是0。在这种状况下,I(0)=0。因此J(1) = (I(0) + I(1) + I(2))/3 = (0 + 5 + 4)/3= 3. 一样,J(10) = (I(9)+I(10)+I(11))/3 = (3+ 6 + 0)/3 = 3.
2)第二种方法也是想象I是无限图像的一部分。但没有指定的部分是用图像边界的值进行拓展。在咱们的例子中,由于图像I最左边的值I(1)=5,因此它左边的全部值,咱们都认为是5 。而图像右边的全部的值,咱们都认为和右边界的值I(10)同样,都是6。这时候J(1) = (I(0) + I(1) + I(2))/3 = (5 + 5 + 4)/3= 14/3. 而J(10) = (I(9)+I(10)+I(11))/3 = (3 + 6 + 6)/3 = 5。
3)第三种状况就是认为图像是周期性的。也就是I不断的重复。周期就是I的长度。在咱们这里,I(0)和I(10)的值就是同样的,I(11)的值和I(1)的值也是同样的。因此J(1) = (I(0) + I(1) + I(2))/3= (I(10) + I(1)+ I(2))/3 = (6 + 5 + 4)/3 = 5 。
4)最后一种状况就是无论其余地方了。咱们以为I以外的状况是没有定义的,因此没办法使用这些没有定义的值,因此要使用图像I没有定义的值的像素都没办法计算。在这里,J(1)和J(10)都没办法计算,因此输出J会比原图像I要小。
这四种方法有各自的优缺点。若是咱们想象咱们使用的图像只是世界的一个小窗口,而后咱们须要使用窗口边界外的值,那么通常来讲,外面的值和边界上的值是几乎类似的,因此第二种方法可能更说得过去。
2.二、频域计算-快速傅里叶变换FFT卷积
这个快速实现得益于卷积定理:时域上的卷积等于频域上的乘积。因此将咱们的图像和滤波器经过算法变换到频域后,直接将他们相乘,而后再变换回时域(也就是图像的空域)就能够了。
o表示矩阵逐元素相乘。那用什么方法将空域的图像和滤波器变换到频域了。那就是鼎鼎大名的Fast Fourier Transformation 快速傅里叶变换FFT(其实,在CUDA里面,已经实现了FFT了)。
要在频域中对一副图像进行滤波,滤波器的大小和图像的大小必需要匹配,这样二者的相乘才容易。由于通常滤波器的大小比图像要小,因此咱们须要拓展咱们的kernel,让它和图像的大小一致。
由于CUDA中的FFT实现是周期的,因此kernel的值也要安排成这样,以支持这种周期性。
为了保证图像边界的像素也能够获得响应输出,咱们也须要拓展咱们的输入图像。同时,拓展的方式也要支持周期表达。
若是只是使用卷积定理,没有对输入进行任何修改的话,那么咱们获得的是周期卷积的结果。但这可能不是咱们要的,由于周期卷积会对输入数据进行周期填补,引入一些artifacts。
给定N长度的I和K,为了获得线性卷积,咱们须要对I和K进行zero padding。为何要补0,由于DFT假定了输入是无限和周期的,周期是N。
如上图,对于I和K,若是没有padding的话,隐含着会假定I和K是周期的,以他们的长度N为周期。图中原本N长度的I和K都是黑色虚线的部分,而后若是没有padding,隐含着就会在N以外,加上一样的无数个I,如红色虚线部分,加上了一个周期。对K也是这样。若是是zero padding的话,在黑色虚线的其余地方都全是0了,如图中蓝色部分。将I和K卷积,若是没有padding,如黑色虚线,会有红色那部分的artifact。若是有padding,就是蓝色实线。
4、实验代码
这是第二部分的Matlab实验代码:
5、参考文献
[1] Correlation and Convolution.pdf
[2] Lode's Computer GraphicsTutorial Image Filtering
图像卷积与滤波的一些知识点
以前在学习CNN的时候,有对卷积进行一些学习和整理,后来就烂尾了,如今稍微整理下,先放上来,以提醒和交流。
1、线性滤波与卷积的基本概念
线性滤波能够说是图像处理最基本的方法,它能够容许咱们对图像进行处理,产生不少不一样的效果。作法很简单。首先,咱们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像。而后,对于图像的每个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,而后加起来,做为该像素位置的值。这样就完成了滤波过程。
对图像和滤波矩阵进行逐个元素相乘再求和的操做就至关于将一个二维的函数移动到另外一个二维函数的全部位置,这个操做就叫卷积或者协相关。卷积和协相关的差异是,卷积须要先对滤波矩阵进行180的翻转,但若是矩阵是对称的,那么二者就没有什么差异了。
Correlation 和 Convolution能够说是图像处理最基本的操做,但却很是有用。这两个操做有两个很是关键的特色:它们是线性的,并且具备平移不变性shift-invariant。平移不变性指咱们在图像的每一个位置都执行相同的操做。线性指这个操做是线性的,也就是咱们用每一个像素的邻域的线性组合来代替这个像素。这两个属性使得这个操做很是简单,由于线性操做是最简单的,而后在全部地方都作一样的操做就更简单了。
实际上,在信号处理领域,卷积有普遍的意义,并且有其严格的数学定义,但在这里不关注这个。
2D卷积须要4个嵌套循环4-double loop,因此它并不快,除非咱们使用很小的卷积核。这里通常使用3x3或者5x5。并且,对于滤波器,也有必定的规则要求:
1)滤波器的大小应该是奇数,这样它才有一个中心,例如3x3,5x5或者7x7。有中心了,也有了半径的称呼,例如5x5大小的核的半径就是2。
2)滤波器矩阵全部的元素之和应该要等于1,这是为了保证滤波先后图像的亮度保持不变。固然了,这不是硬性要求了。
3)若是滤波器矩阵全部元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,若是小于1,那么获得的图像就会变暗。若是和为0,图像不会变黑,但也会很是暗。
4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种状况,咱们将他们直接截断到0和255之间便可。对于负数,也能够取绝对值。
2、神奇的卷积核
上面说到,对图像的滤波处理就是对图像应用一个小小的卷积核,那这个小小的卷积核到底有哪些魔法,能让一个图像从惨不忍睹变得秀色可餐。下面咱们一块儿来领略下一些简单但不简单的卷积核的魔法。
2.一、啥也不作
哈哈,你们能够看到啥了吗?这个滤波器啥也没有作,获得的图像和原图是同样的。由于只有中心点的值是1。邻域点的权值都是0,对滤波后的取值没有任何影响。
下面咱们动点真格的。
2.二、图像锐化滤波器Sharpness Filter
图像的锐化和边缘检测很像,首先找到边缘,而后把边缘加到原来的图像上面,这样就强化了图像的边缘,使图像看起来更加锐利了。这二者操做统一块儿来就是锐化滤波器了,也就是在边缘检测滤波器的基础上,再在中心的位置加1,这样滤波后的图像就会和原始的图像具备一样的亮度了,可是会更加锐利。
咱们把核加大,就能够获得更加精细的锐化效果
另外,下面的滤波器会更强调边缘:
主要是强调图像的细节。最简单的3x3的锐化滤波器以下:
其实是计算当前点和周围点的差异,而后将这个差异加到原来的位置上。另外,中间点的权值要比全部的权值和大于1,意味着这个像素要保持原来的值。
2.三、边缘检测Edge Detection
咱们要找水平的边缘:须要注意的是,这里矩阵的元素和是0,因此滤波后的图像会很暗,只有边缘的地方是有亮度的。
为何这个滤波器能够寻找到水平边缘呢?由于用这个滤波器卷积至关于求导的离散版本:你将当前的像素值减去前一个像素值,这样你就能够获得这个函数在这两个位置的差异或者斜率。下面的滤波器能够找到垂直方向的边缘,这里像素上和下的像素值都使用:
再下面这个滤波器能够找到45度的边缘:取-2不为了什么,只是为了让矩阵的元素和为0而已。
那下面这个滤波器就能够检测全部方向的边缘:
为了检测边缘,咱们须要在图像对应的方向计算梯度。用下面的卷积核来卷积图像,就能够了。但在实际中,这种简单的方法会把噪声也放大了。另外,须要注意的是,矩阵全部的值加起来要是0.
2.四、浮雕Embossing Filter
浮雕滤波器能够给图像一种3D阴影的效果。只要将中心一边的像素减去另外一边的像素就能够了。这时候,像素值有多是负数,咱们将负数当成阴影,将正数当成光,而后咱们对结果图像加上128的偏移。这时候,图像大部分就变成灰色了。
下面是45度的浮雕滤波器
咱们只要加大滤波器,就能够获得更加夸张的效果了
这种效果很是的漂亮,就像是将一副图像雕刻在一块石头上面同样,而后从一个方向照亮它。它和前面的滤波器不一样,它是非对称的。另外,它会产生负数值,因此咱们须要将结果偏移,以获得图像灰度的范围。
A:原图像。B:锐化。C:边缘检测。D:浮雕
2.五、均值模糊Box Filter (Averaging)
咱们能够将当前像素和它的四邻域的像素一块儿取平均,而后再除以5,或者直接在滤波器的5个地方取0.2的值便可,以下图:
能够看到,这个模糊仍是比较温柔的,咱们能够把滤波器变大,这样就会变得粗暴了:注意要将和再除以13.
因此,若是你想要更模糊的效果,加大滤波器的大小便可。或者对图像应用屡次模糊也能够。
2.六、高斯模糊
均值模糊很简单,但不是很平滑。高斯模糊就有这个优势,因此被普遍用在图像降噪上。特别是在边缘检测以前,都会用来移除细节。高斯滤波器是一个低通滤波器。
2.七、运动模糊Motion Blur
运动模糊能够经过只在一个方向模糊达到,例以下面9x9的运动模糊滤波器。注意,求和结果要除以9。
这个效果就好像,摄像机是从左上角移动的右下角。
3、卷积的计算
对图像处理而言,存在两大类的方法:空域处理和频域处理!空域处理是指直接对原始的像素空间进行计算,频率处理是指先对图像变换到频域,再作滤波等处理。
3.一、空域计算-直接2D卷积
3.1.一、2D卷积
直接2D卷积就是一开始说的那样,对于图像的每个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,而后加起来,做为该像素位置的值。
直接的实现也称为暴力实现brute force,由于它严格按照定义来实现,没有任何优化。固然了,在并行实现里面,它也是比较灵活的。另外,也存在一个优化版本,若是咱们的kernel是separable可分的,那么就能够获得一个快5倍左右的卷积方法。
2.1.二、边界处理
那卷积核遇到图像边缘怎么办?例如图像顶部的像素,它的上面已经没有像素了,那么它的值如何计算?目前有四种主流的处理方法,咱们用一维卷积和均值滤波来讲明下。
咱们在1D图像中,用每一个像素和它的二邻域的平均值来取代它的值。假设咱们有个1D的图像I是这样的:
对非图像边界的像素的操做比较简单。假设咱们对I的第四个像素3作局部平均。也就是咱们用2,3和7作平均,来取代这个位置的像素值。也就是,平均会产生一副新的图像J,这个图像在相同位置J (4) = (I(3)+I(4)+I(5))/3 = (2+3+7)/3 = 4。一样,咱们能够获得J(3) = (I(2)+I(3)+I(4))/3 =(4+2+3)/3 = 3。须要注意的是,新图像的每一个像素都取决于旧的图像,在计算J (4)的时候用J (3)是不对的,而是用I(3),I(4)和I(5)。因此每一个像素都是它和它邻域两个像素的平均。平均是线性的操做,由于每一个新的像素都是旧像素的线性组合。
对卷积,也有必需要考虑的状况是,在图像边界的时候,怎么办?J(1)的值应该是什么?它取决于I(0),I(1)和I(2)。可是咱们没有I(0)呀!图像左边没有值了。有四种方式来处理这个问题:
1)第一种就是想象I是无限长的图像的一部分,除了咱们给定值的部分,其余部分的像素值都是0。在这种状况下,I(0)=0。因此J(1) = (I(0) + I(1) + I(2))/3 = (0 + 5 + 4)/3= 3. 一样,J(10) = (I(9)+I(10)+I(11))/3 = (3+ 6 + 0)/3 = 3.
2)第二种方法也是想象I是无限图像的一部分。但没有指定的部分是用图像边界的值进行拓展。在咱们的例子中,由于图像I最左边的值I(1)=5,因此它左边的全部值,咱们都认为是5 。而图像右边的全部的值,咱们都认为和右边界的值I(10)同样,都是6。这时候J(1) = (I(0) + I(1) + I(2))/3 = (5 + 5 + 4)/3= 14/3. 而J(10) = (I(9)+I(10)+I(11))/3 = (3 + 6 + 6)/3 = 5。
3)第三种状况就是认为图像是周期性的。也就是I不断的重复。周期就是I的长度。在咱们这里,I(0)和I(10)的值就是同样的,I(11)的值和I(1)的值也是同样的。因此J(1) = (I(0) + I(1) + I(2))/3= (I(10) + I(1)+ I(2))/3 = (6 + 5 + 4)/3 = 5 。
4)最后一种状况就是无论其余地方了。咱们以为I以外的状况是没有定义的,因此没办法使用这些没有定义的值,因此要使用图像I没有定义的值的像素都没办法计算。在这里,J(1)和J(10)都没办法计算,因此输出J会比原图像I要小。
这四种方法有各自的优缺点。若是咱们想象咱们使用的图像只是世界的一个小窗口,而后咱们须要使用窗口边界外的值,那么通常来讲,外面的值和边界上的值是几乎类似的,因此第二种方法可能更说得过去。
2.二、频域计算-快速傅里叶变换FFT卷积
这个快速实现得益于卷积定理:时域上的卷积等于频域上的乘积。因此将咱们的图像和滤波器经过算法变换到频域后,直接将他们相乘,而后再变换回时域(也就是图像的空域)就能够了。
o表示矩阵逐元素相乘。那用什么方法将空域的图像和滤波器变换到频域了。那就是鼎鼎大名的Fast Fourier Transformation 快速傅里叶变换FFT(其实,在CUDA里面,已经实现了FFT了)。
要在频域中对一副图像进行滤波,滤波器的大小和图像的大小必需要匹配,这样二者的相乘才容易。由于通常滤波器的大小比图像要小,因此咱们须要拓展咱们的kernel,让它和图像的大小一致。
由于CUDA中的FFT实现是周期的,因此kernel的值也要安排成这样,以支持这种周期性。
为了保证图像边界的像素也能够获得响应输出,咱们也须要拓展咱们的输入图像。同时,拓展的方式也要支持周期表达。
若是只是使用卷积定理,没有对输入进行任何修改的话,那么咱们获得的是周期卷积的结果。但这可能不是咱们要的,由于周期卷积会对输入数据进行周期填补,引入一些artifacts。
给定N长度的I和K,为了获得线性卷积,咱们须要对I和K进行zero padding。为何要补0,由于DFT假定了输入是无限和周期的,周期是N。
如上图,对于I和K,若是没有padding的话,隐含着会假定I和K是周期的,以他们的长度N为周期。图中原本N长度的I和K都是黑色虚线的部分,而后若是没有padding,隐含着就会在N以外,加上一样的无数个I,如红色虚线部分,加上了一个周期。对K也是这样。若是是zero padding的话,在黑色虚线的其余地方都全是0了,如图中蓝色部分。将I和K卷积,若是没有padding,如黑色虚线,会有红色那部分的artifact。若是有padding,就是蓝色实线。
4、实验代码
这是第二部分的Matlab实验代码:
clear,close all, clc %% readimage image =imread('test.jpg'); %% definefilter % -----Identity filter ----- kernel =[0, 0, 0 0, 1, 0 0, 0, 0]; % -----Average Blur ----- kernel =[0, 1, 0 1, 1, 1 0, 1, 0] / 5; % -----Gaussian Blur ----- kernel =fspecial('gaussian', 5 , 0.8); % -----Motion Blur ----- kernel =[1, 0, 0, 0, 0 0, 1, 0, 0, 0 0, 0, 1, 0, 0 0, 0, 0, 1, 0 0, 0, 0, 0, 1] / 5; % -----Edges Detection ----- kernel =[-1, -1, -1 -1, 8, -1 -1, -1, -1]; % -----Sharpen filter ----- kernel =[-1, -1, -1 -1, 9, -1 -1, -1, -1]; % -----Emboss filter ----- kernel =[-1, -1, 0 -1, 0,1 0, 1,1]; %% convolethe image with defined kernel or filter result =zeros(size(image)); result(:,:, 1) = conv2(double(image(:, :, 1)), double(kernel), 'same'); result(:,:, 2) = conv2(double(image(:, :, 2)), double(kernel), 'same'); result(:,:, 3) = conv2(double(image(:, :, 3)), double(kernel), 'same'); %% showthe result imshow(image); figure imshow(uint8(result))
5、参考文献
[1] Correlation and Convolution.pdf