一起学习python-opencv十一(边缘保留滤波利用matplotlib画图,numpy文件io)

版权声明: https://blog.csdn.net/qq_41740705/article/details/82830991

边缘保留滤波(Edge preserving filtering)

第一种是双边高斯滤波。

参考https://www.bilibili.com/video/av24998616/?p=11

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_filtering/py_filtering.html

和https://blog.csdn.net/pi9nc/article/details/26592377

 

如果两个像素点的三个通道差距太大的话,指数就会越小,那么就越接近0,权重就会接近0,对应的像素点对于卷积的结果就基本没有了。当然卷积核中的值还是保持和为1的。下面的图还是很直观地解释了双边滤波。左边地一开始是有高斯噪声的一张黑白图,下面的3D图z轴是灰度值,白色是255,黑色是0,因为有噪声,所以不是平的,然后下面有一个高斯双边滤波过程的图解,先是有一个普通的高斯滤波卷积核,然后发现边界的地方有的差别太大,于是又一边就基本上权重是0了,就像在边界切了一刀,然后进行卷积运算,结果是边缘弱化的微乎其微,还是很陡峭的几乎90度的一个突变,如果是普通滤波,边界会是一个有一定坡度的斜坡,不是这样的突变,相同的是但其它地方(非边缘)的高斯噪声都被很好地去除了。

 

通俗来讲就是双边滤波模板主要有两个模板生成,第一个是高斯模板,第二个是以灰度级的差值作为函数系数生成的模板,然后这两个模板点乘就得到了最终的双边滤波模板,第一个模板是全局模板,所以只需要生成以西,第二个模板需要对每个像素都计算一次。双边滤波器比高斯滤波器多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素,这样就能对边缘附近的像素值予以保存,但是由于保存过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤除。比如说椒盐噪声就是高频噪声。

 

来学习一个这个双边滤波的函数:

 

 

也就是d是卷积核的大小,上一讲我们给过了sigma和卷积核阶数的转换公式,sigmacolor就是计算颜色的那个分母,显然,如果sigmacolor越大,指数越接近0,那么就越接近普通的高斯滤波。废话不多说,我们来试一下。

 

原图:

 

原图经过双边滤波:

 

已经有点美颜的意思了。脸上的痘痘少了很多。但是有的痘痘为什么还没有清除呢?

这是我们的sigmacolor较小,需要增大sigmacolor,眼球为什么变色,我看是因为瞳孔太黑了,把深绿色强行给搞成了比较暗的颜色。这是我们加椒盐噪声的图片:

 

经过双边滤波,基本没把噪声去掉。

 

原图加高斯噪声之后:

 

经过双边滤波:

 

效果还是不错的。我们增大sigmacolor。

 

痘痘基本上全部被消除了。sigmacolor越大,越接近普通的高斯滤波,边界被破坏的越严重。

 

这个时候sigmaspace最好不要太大,不然模糊得就太过了。

 

经过我的不断尝试,终于找到一个不错的美颜效果:

 

sigmaspace是10的效果也不错。

 

sigmacolor是80也还好。

 

 

 

 

 

这个鼻子上有一点痘痘没有搞定掉。所以美颜的秘诀就是sigmacolor和sigmaspace都有合适的值,不能太大,太大了太模糊了,也不能太小,太小效果不明显,你们可以搞两个滑条在那里调。双边过滤之后再找到合适的锐化核锐化一下效果会更好:

 

7是锐化过后的。

第二种是均值迁移,对应的函数是pyrMeanShiftFiltering。

 

 

具体原理见http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/imgproc/doc/filtering.html#pyrmeanshiftfiltering

 

这个一个不断迭代的算法。上面大概说明了原理,就是在时间空间和颜色空间的距离同时满足一定条件的时候才会被加进去取平均,不满足条件对应的卷积核的权重应该是0。然后不断迭代咯。

 

这个挺有油画的感觉的。

第三种据说是近年来才有的,叫做引导滤波。

参考https://blog.csdn.net/pi9nc/article/details/26592377

https://blog.csdn.net/s12244315/article/details/50242295

 

如果要保持边缘的话,I就取要边缘保留滤波的图片就好了,但是会经过一个最小二乘还有一个平滑因子,所以边缘并不会像上面理想的完全被保留。

 

 

 

 

 

这个方法原来还是比较好懂的,但是要变成

 

这个gf就是我编的函数。

 

最后一步astype(np.uint8)很重要。

 

出来的效果还不错,不过有点太模糊了,这个时候就需要调节平滑因子和size大小了。

matplotlib画图

参考https://www.yiibai.com/numpy/numpy_matplotlib.html

 

 

用法的确和MATLAB非常像。

 

 

 

ob或者bo都是可以的。

 

 

 

 

画这种曲线必须步长间隔要小,不然会看起来完全是折线。

 

 

subplot前两个参数分别是行和列,第三个是序号,序号从1开始。这个前面用过很多次了,我画一个横着的。

 

 

 

align是对齐方式,color是颜色,这就是画条形图的。

 

 

 

 

这个参数还是挺多的。bins可以是一个整数代表边界,也可以是包含边界的序列。

需要注意的是除了最右边的bin,其它的都是左闭右开,最后一个是都闭。

 

用序列的好处在于可以不是等间隔的。还可以改变orientation和color。

 

 

还有几种不同的线型。

 

 

 

 

numpy文件IO操作

 

pickle我们应该知道是个什么意思。

 

 

运行了以后:

 

这个数组的元素不知道为什么是这样的。

 

 

读进来是没有问题的。

 

就算是false,也是有乱码,应该还是格式不对。

 

但是这样一次只能存一个数组。

 

而savez可以一次存多个。

 

 

 

 

然后是以文本格式的保存和读取:

 

 

X是1D或者2D,说明存不了3维数组。

 

 

savetxt确实对3维数组没辙。

 

但是save就可以啊。

 

 

有点能理解为什么是乱码了,因为存储方式不同,txt这种就只能存二维的,而save可以存三维的,格式不一样,所以乱码。下面再介绍一下python如何读取mat文件,mat文件时MATLAB的数据文件。

参考了https://blog.csdn.net/jiachen0212/article/details/78414580

就是用了scipy.io的sio里的loadmat和savemat。

 

 

​好的,我们先到这里了。

猜你喜欢

转载自blog.csdn.net/qq_41740705/article/details/82830991