AI科技大本营|Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来! | 附代码( 三 )


对于任意一幅输入图像 , 定义其暗通道的数学表达式为:
AI科技大本营|Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来! | 附代码
本文插图

文章中介绍的方法是软抠图的方法 , 此方法过程复杂 , 速度缓慢 , 因此采用导向滤波对传输函数进行滤波 。 导向滤波的原理此处不再赘述 , 其伪代码为:
AI科技大本营|Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来! | 附代码
本文插图

1、滤波函数:
定义最小值滤波函数:
defzmMinFilterGray(src, r= 7) :
'''if r <= 0:
returnsrc
h, w =src.shape[:2]
I = src
res =np.minimum(I , I[[0]+range(h-1) , :])
res =np.minimum(res, I[range(1,h)+[h-1], :])
I = res
res =np.minimum(I , I[:, [0]+range(w-1)])
res =np.minimum(res, I[:, range(1,w)+[w-1]])
returnzmMinFilterGray(res, r-1)'''
returncv2.erode(src,np.ones(( 2*r+ 1, 2*r+ 1)))
引导滤波函数的实现:
defguidedfilter(I, p, r, eps):
'''引导滤波 , 直接参考网上的matlab代码'''
height, width = I.shape
m_I = cv2.boxFilter(I, -1, (r,r))
m_p = cv2.boxFilter(p, -1, (r,r))
m_Ip = cv2.boxFilter(I*p, -1, (r,r))
cov_Ip = m_Ip-m_I*m_p
m_II = cv2.boxFilter(I*I, -1, (r,r))
var_I = m_II-m_I*m_I
a = cov_Ip/(var_I+eps)
b = m_p-a*m_I
m_a = cv2.boxFilter(a, -1, (r,r))
m_b = cv2.boxFilter(b, -1, (r,r))
returnm_a*I+m_b
计算大气遮罩图像V1和光照值A, V1 = 1-t/A
defgetV1(m, r, eps, w, maxV1): #输入rgb图像 , 值范围[0,1]
'''计算大气遮罩图像V1和光照值A, V1 = 1-t/A'''
V1 = np.min(m, 2) #得到暗通道图像
V1 = guidedfilter(V1, zmMinFilterGray(V1, 7), r, eps) #使用引导滤波优化
bins = 2000
ht = np.histogram(V1, bins) #计算大气光照A
d = np.cumsum(ht[ 0])/float(V1.size)
forlmax inrange(bins -1, 0, -1):
ifd[lmax]<= 0.999:
break
A = np.mean(m, 2)[V1>=ht[ 1][lmax]].max
V1 = np.minimum(V1*w, maxV1) #对值范围进行限制
returnV1,A
得到的运行程序结果如下:
AI科技大本营|Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来! | 附代码
本文插图

通过调整代码 , 将视频分帧 , 可以达到视频去雾的效果:
其完整代码如下:
importcv2
importnumpy asnp
defzmMinFilterGray(src, r= 7) :
'''最小值滤波 , r是滤波器半径'''
'''if r <= 0:
return src
h, w = src.shape[:2]
I= src
res = np.minimum(I ,I[[0]+range(h-1) , :])
res = np.minimum(res, I[range(1,h)+[h-1], :])
I= res
res = np.minimum(I , I[:,[0]+range(w-1)])
res = np.minimum(res, I[:, range(1,w)+[w-1]])
return zmMinFilterGray(res, r-1)'''
returncv2.erode(src, np.ones(( 2* r + 1, 2* r + 1))) # 使用opencv的erode函数更高效
defguidedfilter(I, p, r, eps):
'''引导滤波'''
height, width = I.shape
m_I = cv2.boxFilter(I, -1, (r, r))
m_p = cv2.boxFilter(p, -1, (r, r))
m_Ip = cv2.boxFilter(I * p, -1, (r, r))
cov_Ip = m_Ip - m_I * m_p
m_II = cv2.boxFilter(I * I, -1, (r, r))
var_I = m_II - m_I * m_I


推荐阅读