Python暗通道图像去雾

何凯明的经典图像去雾算法,直接上代码啦,理论后续讲解哈~

Python代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PIL import Image
from guidedfilter import *

def getDark(input_img, filter, frame):
  """get dark image from the input image"""
  size = input_img.size
  output = []

  for x in xrange(size[1]):
    temp = []
    for y in xrange(size[0]):
      temp.append(min(input_img.getpixel((y, x))))

    output.append(temp)

  output = filter2d(output, filter, frame)

  output_img = Image.new('L', size)

  for x in xrange(size[1]):
    for y in xrange(size[0]):
      output_img.putpixel((y, x), output[x][y])

  return output_img

def getLight(srcImage, darkImage, cut):
  """get atmospheric light from the picture"""
  size = darkImage.size
  light = []

  for x in xrange(size[0]):
    for y in xrange(size[1]):
      light.append(darkImage.getpixel((x, y)))

  light.sort()
  light.reverse()

  threshold = light[int(cut * len(light))]

  atmosphere = {}

  for x in xrange(size[0]):
    for y in xrange(size[1]):
      if darkImage.getpixel((x, y)) >= threshold:
        atmosphere.update({(x, y): sum(srcImage.getpixel((x, y))) / 3.0})

  pos = sorted(atmosphere.iteritems(), key = lambda item: item[1], reverse = True)[0][0]

  return srcImage.getpixel(pos)

def getTransmission(input_img, light, omiga):
  """get transmission from the picture"""
  size = input_img.size
  output = []

  for x in xrange(size[1]):
    temp = []
    for y in xrange(size[0]):
      temp.append(min(input_img.getpixel((y, x))) / float(min(light)))

    output.append(temp)

  transmission = []

  for x in xrange(size[1]):
    temp = []
    for y in xrange(size[0]):
      temp.append(1 - omiga * minimizeFilter(output, (x, y), (10, 10)))

    transmission.append(temp)

  return transmission

def getRadiance(input_img, transmission, light, t0):
  """get radiance from the picture"""
  size = input_img.size
  output = Image.new('RGB', size)

  for x in xrange(size[1]):
    for y in xrange(size[0]):
      r, g, b = input_img.getpixel((y, x))

      r = int((r - light[0]) / float(max(t0, transmission[x][y])) + light[0])
      g = int((g - light[1]) / float(max(t0, transmission[x][y])) + light[1])
      b = int((b - light[2]) / float(max(t0, transmission[x][y])) + light[2])

      output.putpixel((y, x), (r, g, b))

  return output

def ensure(n):
  if n < 0:
    n = 0

  if n > 255:
    n = 255

  return int(n)

if __name__ == '__main__':
  image = Image.open('1.png')
  image = image.convert('RGB')

  dark = getDark(image, minimizeFilter, (10, 10))

  dark.save('3_dark.png')

  light = getLight(image, dark, 0.001)

  transmission = getTransmission(image, light, 0.9)

  tranImage = Image.new('L', image.size)
  grayImage = image.convert('L')

  for x in xrange(image.size[0]):
    for y in xrange(image.size[1]):
      tranImage.putpixel((x, y), int(transmission[y][x] * 255))

  guided = guidedFilter(grayImage, tranImage, 25, 0.001)

  guidedImage = Image.new('L', image.size)

  for x in xrange(image.size[0]):
    for y in xrange(image.size[1]):
      guidedImage.putpixel((x, y), ensure(guided[y][x]))
      guided[y][x] /= 255.0

  #guidedImage.show()
  guidedImage.save('3_guided.png')

  output = getRadiance(image, guided, light, 0.1)

  output.save('3_haze.png')
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PIL import Image

def filter2d(input_img, filter, frame):
  """filter of the 2-dimension picture"""
  size = len(input_img), len(input_img[0])
  output = []

  for i in xrange(size[0]):
    temp = []
    for j in xrange(size[1]):
      temp.append(filter(input_img, (i, j), frame))

    output.append(temp)

  return output

def minimizeFilter(input_img, point, size):
  """minimize filter for the input image"""
  begin = (point[0] - size[0] / 2, point[0] + size[0] / 2 + 1)
  end = (point[1] - size[1] / 2, point[1] + size[1] / 2 + 1)

  l = []

  for i in xrange(*begin):
    for j in xrange(*end):
      if (i >= 0 and i < len(input_img)) and (j >= 0 and j < len(input_img[0])):
        l.append(input_img[i][j])

  return min(l)

def convertImageToMatrix(image):
  size = image.size
  out = []

  for x in xrange(size[1]):
    temp = []
    for y in xrange(size[0]):
      temp.append(image.getpixel((y, x)))

    out.append(temp)

  return out

def boxFilter(im, radius):
  """box filter for the image of the radius"""
  height, width = len(im), len(im[0])

  imDst = []
  imCum = []

  for x in xrange(height):
    imDst.append([0.0] * width)
    imCum.append([0.0] * width)

  #cumulative sum over Y axis
  for i in xrange(width):
    for j in xrange(height):
      if j == 0:
        imCum[j][i] = im[j][i]
      else:
        imCum[j][i] = im[j][i] + imCum[j - 1][i]

  #difference over Y axis
  for j in xrange(radius + 1):
    for i in xrange(width):
      imDst[j][i] = imCum[j + radius][i]

  for j in xrange(radius + 1, height - radius):
    for i in xrange(width):
      imDst[j][i] = imCum[j + radius][i] - imCum[j - radius - 1][i]

  for j in xrange(height - radius, height):
    for i in xrange(width):
      imDst[j][i] = imCum[height - 1][i] - imCum[j - radius - 1][i]

  #cumulative sum over X axis
  for j in xrange(height):
    for i in xrange(width):
      if i == 0:
        imCum[j][i] = imDst[j][i]
      else:
        imCum[j][i] = imDst[j][i] + imCum[j][i - 1]

  #difference over X axis
  for j in xrange(height):
    for i in xrange(radius + 1):
      imDst[j][i] = imCum[j][i + radius]

  for j in xrange(height):
    for i in xrange(radius + 1, width - radius):
      imDst[j][i] = imCum[j][i + radius] - imCum[j][i - radius - 1]

  for j in xrange(height):
    for i in xrange(width - radius, width):
      imDst[j][i] = imCum[j][width - 1] - imCum[j][i - radius - 1]

  return imDst

def dot(matrix1, matrix2, operation):
  """dot operation for the matrix1 and matrix2"""
  out = []
  size = len(matrix1), len(matrix1[0])

  for x in xrange(size[0]):
    temp = []
    for y in xrange(size[1]):
      temp.append(operation(matrix1[x][y], matrix2[x][y]))

    out.append(temp)

  return out

def guidedFilter(srcImage, guidedImage, radius, epsilon):
  """guided filter for the image
     src image must be gray image
     guided image must be gray image
  """

  size = srcImage.size
  src = convertImageToMatrix(srcImage)
  guided = convertImageToMatrix(guidedImage)

  one = []

  for x in xrange(size[1]):
    one.append([1.0] * size[0])

  n = boxFilter(one, radius)

  plus = lambda x, y: x + y
  minus = lambda x, y: x - y
  multiple = lambda x, y: x * y
  divide = lambda x, y: x / y

  meanI = dot(boxFilter(src, radius), n, divide)
  meanP = dot(boxFilter(guided, radius), n, divide)
  meanIP = dot(boxFilter(dot(src, guided, multiple), radius), n, divide)

  covIP = dot(meanIP, dot(meanI, meanP, multiple), minus)

  meanII = dot(boxFilter(dot(src, src, multiple), radius), n, divide)
  varI = dot(meanII, dot(meanI, meanI, multiple), minus)

  epsilonMatrix = []

  for x in xrange(size[1]):
    epsilonMatrix.append([epsilon] * size[0])

  a = dot(covIP, dot(varI, epsilonMatrix, plus), divide)
  b = dot(meanP, dot(a, meanI, multiple), minus)

  meanA = dot(boxFilter(a, radius), n, divide)
  meanB = dot(boxFilter(b, radius), n, divide)

  return dot(dot(meanA, src, multiple), meanB, plus)

测试结果如下:
原图像:
原图
图像暗通道:
暗通道
图像导向滤波:
导向滤波
去雾后的效果:
去雾图像

  • 8
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值