热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python暗通道图像去雾

何凯明的经典图像去雾算法,直接上代码啦,理论后续讲解哈~Python代码如下:#!usrbinenvpython#-*-coding:utf-8-*-fromPIL

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

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 and (j >= 0 and j 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)

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


推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
author-avatar
玉米的跟屁虫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有