1.直方图均衡化 (Histogram Equalization, HE)

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('city1.jpg',0)

equ = cv2.equalizeHist(img)
res = np.hstack((img,equ))
#stacking images side-by-side
cv2.imshow('img',res)
cv2.waitKey()
cv2.destroyAllWindows()

原图

处理后

2.Retinex

import os
import cv2
import numpy as np

# 对图像进行单尺度 Retinex 处理
def single_scale_retinex(img, sigma):
    retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma))
    return retinex

# 对图像进行多尺度 Retinex 处理
def multi_scale_retinex(img, sigma_list):
    retinex = np.zeros_like(img)
    for sigma in sigma_list:
        retinex += single_scale_retinex(img, sigma)
    retinex = retinex / len(sigma_list)
    return retinex

# 进行颜色恢复
def color_restoration(img, alpha, beta):
    img_sum = np.sum(img, axis=2, keepdims=True)
    color_restoration = beta * (np.log10(alpha * img) - np.log10(img_sum))
    return color_restoration

# 图像增强主函数,包括图像增强和颜色恢复
def retinex_process(img, sigma_list, G, b, alpha, beta):
    img = np.float64(img) + 1.0
    img_retinex = multi_scale_retinex(img, sigma_list)
    img_color = color_restoration(img, alpha, beta)
    img_retinex = G * (img_retinex * img_color + b)

    # 将像素值限制在范围内
    for i in range(img_retinex.shape[2]):
        img_retinex[:, :, i] = np.clip(img_retinex[:, :, i], 0, 255)
    img_retinex = np.uint8(img_retinex)

    return img_retinex

def main():
    # 读取图像
    img = cv2.imread('city1.jpg')

    # 尺度列表
    sigma_list = [15, 80, 250]
    # 增益参数
    G = 5.0
    # 偏置参数
    b = 25.0
    # 颜色恢复参数
    alpha = 125.0
    # 颜色恢复参数
    beta = 46.0

    # 进行图像增强
    img_retinex = retinex_process(img, sigma_list, G, b, alpha, beta)

    # 显示原始图像
    cv2.imshow('1', img)
    # 显示增强后的图像
    cv2.imshow('Retinex', img_retinex)
    # 等待按键
    cv2.waitKey(0)
    # 保存增强后的图片
    cv2.imwrite('D:/images/retinex_image.jpg', img_retinex)

if __name__ == "__main__":
    main()

if __name__ == "__main__":
    main()
    # 自动打开保存的图片(Windows 示例)
    os.startfile('a.jpg')  # Windows 专用

3.暗通道

import cv2
import numpy as np

def zmMinFilterGray(src, r=7):
    return cv2.erode(src, np.ones((2 * r + 1, 2 * r + 1)))

def guidedfilter(I, p, r, eps):
    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 Defog(m, r, eps, w, maxV1):                 # 输入rgb图像,值范围[0,1]
    '''计算大气遮罩图像V1和光照值A, V1 = 1-t/A'''
    V1 = np.min(m, 2)
    max_values = np.max(m, axis=2)
    # 得到暗通道图像
    Dark_Channel = zmMinFilterGray(V1, 7)
    cv2.imshow('V1', V1)
    cv2.imshow('20190708_Dark',Dark_Channel)    # 查看暗通
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    V1 = guidedfilter(V1, Dark_Channel, r, eps)  # 使用引导滤波优化
    bins = 2000
    ht = np.histogram(V1, bins)
    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=15, eps=0.001, w=0.95, maxV1=0.80, bGamma=False):
    Y = np.zeros(m.shape)
    Mask_img, A = Defog(m, r, eps, w, maxV1)             # 得到遮罩图像和大气光照

    for k in range(3):
        print((m[:,:,k] - Mask_img))
        Y[:,:,k] = (m[:,:,k] - Mask_img)/(1-Mask_img/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(r'city1.jpg') / 255.0) * 255).astype(np.uint8)
    cv2.imshow("ccccc",m)
    cv2.waitKey(0)
    # cv2.imwrite('20190708_02.png', m)

V1

过程图

结果图

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐