图像滤波算法系列实战总结之二

  • Post author:
  • Post category:其他




简介


文中一些图像均来自论文或者会议PPT, 如果侵权,请联系删除!



同上一篇滤波算法总结一样,本篇博客主要以应用为主;基础滤波算法的功能延拓发展就是如何最大化的去除噪声同时也保存边缘信息。因此,出现一批研究保存边缘的滤波算法:

引导滤波、滚动导向滤波、L0稀疏约束滤波

。保持边缘的滤波算法基本上可以为双边滤波算法思想的延伸,下面会对各个算法进行简要概述。图像中边缘主要分为弱边缘与强边缘区域:





L0范数滤波(l0smooth):


L0范数滤波算法核心思想:

图像中计算梯度时候会存在很多小的梯度值,通过约束梯度值比例来达到不同程度的滤波效果

。如下图:




由上图可以看见,绿色的矩形框中灰色线条存在小幅度的抖动,

L0梯度约束优化就是希望将小幅度梯度变化的区域进行移除

。通过设置梯度变化因子来进行不同程度的滤波。具体可研读

论文链接








其中



f

p

f_p







f










p





















为输入图像像素值,



g

p

g_p







g










p





















为输出图像的像素值,约束条件



c

(

f

)

c(f)






c


(


f


)





为存在梯度变化的个数。最小化



(

f

p

g

p

)

2

(f_p-g_p )^2






(



f










p






























g










p



















)










2












我们可以

简单推测出

:如果在梯度变化较大处



g

p

g_p







g










p

























f

p

f_p







f










p





















保持一致,那么



(

f

p

g

p

)

2

(f_p-g_p )^2






(



f










p






























g










p



















)










2












就是最小化的情况。上图通过一维信号变化可以看出随着约束条件



c

(

f

)

c(f)






c


(


f


)





的变化,首先滤除掉梯度变化较小的情况。

def l0Smooth(src, dst=None, lambda=None, kappa=None):



参数说明:


src: 输入图像;



kappa: 梯度项权重的增加因子;


简单调用OpenCV-Python滤波函数接口及其实现结果:

import cv2 as cv
from matplotlib import pyplot as plt

image_path = './data/filter_input.jpg'
img = cv.imread(image_path)

from cv2.ximgproc import l0Smooth
start = cv.getTickCount()
dst = l0Smooth(img, kappa=2.0)
end = cv.getTickCount()

print('filter algorithm time is ', (end-start)/cv.getTickFrequency(), ' seconds.')

show_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(show_img), plt.title('Original')
plt.xticks([]), plt.yticks([])
show_dst = cv.cvtColor(dst, cv.COLOR_BGR2RGB)
plt.subplot(122), plt.imshow(show_dst), plt.title('l0smooth')
plt.xticks([]), plt.yticks([])
plt.show()





引导滤波(GuidedFilter):


由于双边滤波效果显著,但是存在一些问题:

计算量大、滤波后图像存在梯度反转

;因此引导滤波算法出现就是为了解决双边滤波算法的问题。引导滤波有点参考Joint Bilateral Filter的思想,引入引导图像作为滤波时的权重因子,通过线性局部均值方差分析进行保持边缘的滤波。引导滤波算法出现既延续双边滤波的有点,同时也克服

梯度反转



计算耗时

的问题。当然具体关于引导滤波的原理可以参考

引导滤波论文

及其

会议PPT


def guidedFilter(guide, src, radius, eps, dst=None, dDepth=None):



参数说明:


guide: 引导图像;



src: 输入图像;



radius: 滤波半径核,类似于双边滤波空域核;



eps: 权重因子,类似于双边滤波的值域核;


简单调用OpenCV-Python滤波函数接口及其实现结果:

import cv2 as cv
from matplotlib import pyplot as plt

image_path = './data/filter_input.jpg'
img = cv.imread(image_path)

from cv2.ximgproc import guidedFilter
start = cv.getTickCount()
dst = guidedFilter(img, img, 15, 0.09)
end = cv.getTickCount()

print('filter algorithm time is ', (end-start)/cv.getTickFrequency(), ' seconds.')
show_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(show_img), plt.title('Original')
plt.xticks([]), plt.yticks([])
show_dst = cv.cvtColor(dst, cv.COLOR_BGR2RGB)
plt.subplot(122), plt.imshow(show_dst), plt.title('GuidedFilter')
plt.xticks([]), plt.yticks([])
plt.show()





滚动导向滤波(rollingGuidanceFilter):


rollingGuidanceFilter滤波算法主要介绍通过


尺度感知





联合双边滤波


进行迭代滤波,保存不同尺度的图像。以此来解决边缘保持滤波无法滤除的强纹理区域或者独立的斑点噪声等等。尺度感知滤波步骤:



1 小结构细节移除;



2 边缘区域恢复,滚动迭代引导进行滤波;





rollingGuidanceFilter算法过程:



step1

首先使用高斯滤波对小结构细节滤除;



step2

将滤波后的图像作为引导图像,使用joint bilateral filter 进行滤波;



step3

将step2中每次滤波后的结果作为新的引导图像,重复

step2



为什么rollingGuidanceFilter能够有效work?





分析梯度小结构处:




我们知道在

平坦区域

(梯度浮动变化较小),那么值



G

(

p

)

G

(

q

)

2

0

|G(p)-G(q)|^2≈0









G


(


p


)













G


(


q


)














2




















0





,联合双边滤波就变成高斯滤波函数,进行尺度滤波。



分析梯度较大结构处:




同理,在

梯度变化较大区域

,那么值



G

(

p

)

G

(

q

)

2

0

|G(p)-G(q)|^2≠0









G


(


p


)













G


(


q


)














2
























̸





















=









0





,值域权重系数占比较大,从而较低滤波权重,进行较小程度的滤波。

def rollingGuidanceFilter(src, dst=None, d=None, sigmaColor=None, sigmaSpace=None, numOfIter=None, borderType=None):



参数说明:


src: 输入图像;



d: 滤波半径,如果是负数的话,则从sigmaSpace计算出来;



sigmaColor: 色彩权重,类似于双边滤波核值域因子;



sigmaSpace: 空域权重;



numOfIter: 迭代次数;



borderType: 边界填充方式;


简单调用OpenCV-Python滤波函数接口及其实现结果:

import cv2 as cv
from matplotlib import pyplot as plt

image_path = './data/filter_input.jpg'
img = cv.imread(image_path)

from cv2.ximgproc import rollingGuidanceFilter
start = cv.getTickCount()
dst = rollingGuidanceFilter(img, d=-1, sigmaColor=25, sigmaSpace=3, numOfIter=5)
end = cv.getTickCount()

print('filter algorithm time is ', (end-start)/cv.getTickFrequency(), ' seconds.')

show_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(show_img), plt.title('Original')
plt.xticks([]), plt.yticks([])
show_dst = cv.cvtColor(dst, cv.COLOR_BGR2RGB)
plt.subplot(122), plt.imshow(show_dst), plt.title('rollingGuidanceFilter')
plt.xticks([]), plt.yticks([])
plt.show()





小结


图像保持边缘滤波算法近些年发展较为迅速,主要建立在双边滤波的基础思想上进行优化。降低双边滤波的计算复杂度、提升双边滤波的效果两个方向进行优化;

L0范数

通过全局最小优化梯度来进行滤除梯度抖动较小的区域。

引导滤波

在降低双边滤波复杂度基础上,去除了双边滤波产生的梯度反转现象,个人认为引导滤波只是计算效率提升明显,其引导的思想主要借鉴联合双边滤波算法。

滚动导向滤波

主要解决边缘保持滤波无法滤除细小强纹理、孤立强斑点噪声,引入尺度感知来进行滤除。当然,还存在一系列保持边缘滤波算法,例如比较经典的

BM3D

和最近几年通过深度学习的方式滤波算法。本文只是在阅读OpenCV-Python滤波函数接口的基础对API滤波函数进行简单的介绍与应用,如有错误,还请批评指正!



参考链接


http://kaiminghe.com/eccv10/index.html


http://jiaya.me/archive/projects/rollguidance/index.html


http://jiaya.me/archive/projects/L0smoothing/index.html



版权声明:本文为Small_Munich原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。