zoukankan      html  css  js  c++  java
  • 暗通道去雾算法的python实现

        何凯明博士的去雾文章和算法实现已经漫天飞了,我今天也就不啰里啰唆,直接给出自己python实现的完整版本,全部才60多行代码,简单易懂,并有简要注释,去雾效果也很不错。

        在这个python版本中,计算量最大的就是最小值滤波,纯python写的,慢,可以进一步使用C优化,其他部分都是使用numpy和opencv的现成东东,效率还行。

    import cv2
    import numpy as np
     
    def zmMinFilterGray(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)'''
        return cv2.erode(src, np.ones((2*r+1, 2*r+1)))                      #使用opencv的erode函数更高效
    def guidedfilter(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))
        return m_a*I+m_b
     
    def getV1(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)
        for lmax in range(bins-1, 0, -1):
            if d[lmax]<=0.999:
                break
        A  = np.mean(m,2)[V1>=ht[1][lmax]].max()
             
        V1 = np.minimum(V1*w, maxV1)                   #对值范围进行限制
         
        return V1,A
     
    def deHaze(m, r=81, eps=0.001, w=0.95, maxV1=0.80, bGamma=False):
        Y = np.zeros(m.shape)
        V1,A = getV1(m, r, eps, w, maxV1)               #得到遮罩图像和大气光照
        for k in range(3):
            Y[:,:,k] = (m[:,:,k]-V1)/(1-V1/A)           #颜色校正
        Y =  np.clip(Y, 0, 1)
        if bGamma:
            Y = Y**(np.log(0.5)/np.log(Y.mean()))       #gamma校正,默认不进行该操作
        return Y
     
    if __name__ == '__main__':
        m = deHaze(cv2.imread('land.jpg')/255.0)*255
        cv2.imwrite('defog.jpg', m)
    

      

    下面给两个运行效果吧

  • 相关阅读:
    linux 文件系统(inode和block)
    vue状态管理vuex从浅入深详细讲解
    小白都能看懂的vue中各种通信传值方式,附带详细代码
    CSS3移动端vw+rem不依赖JS实现响应式布局
    JavaScript原生封装ajax请求和Jquery中的ajax请求
    永久解决Sublime包管理package control 打开install package报错 There are no packages available for installation
    从GitLab上创建分支本地拉取项目和提交项目详解
    前端路由的两种实现方式,内附详细代码
    几个例子理解浅拷贝和深拷贝
    讲解JavaScript中对闭包的理解
  • 原文地址:https://www.cnblogs.com/zmshy2128/p/6128033.html
Copyright © 2011-2022 走看看