我有一个脚本,它使用Google Maps API下载一系列相等大小的方形卫星图像并生成PDF。图像需要事先旋转,我已经使用PIL进行了旋转。
我注意到,由于不同的光线和地形条件,一些图像太亮,另一些图像太暗,结果pdf结果有点难看,“在现场”的阅读条件不太理想(这是一个偏远山地自行车,我想要一个特定十字路口的打印缩略图。)
(编辑)然后目标是使所有图像最终具有相似的表观亮度和对比度。因此,过于明亮的图像必须变暗,而黑暗的图像则必须变亮。 (顺便说一句,我曾经使用过imagemagick autocontrast
,auto-gamma
,equalize
,或autolevel
等类似的东西,在医学影像中有了有趣的结果,但是不要不知道如何在PIL中做任何这些。
我已经在转换为灰度后使用了一些图像校正(前一段时间有灰度打印机),但结果也不好。这是我的灰度代码:
#!/usr/bin/python
def myEqualize(im)
im=im.convert('L')
contr = ImageEnhance.Contrast(im)
im = contr.enhance(0.3)
bright = ImageEnhance.Brightness(im)
im = bright.enhance(2)
#im.show()
return im
此代码对每个图像独立工作。我想知道首先分析所有图像然后“标准化”它们的视觉特性(对比度,亮度,伽玛等)会更好。
另外,我认为有必要在图像中进行一些分析(直方图?),以便根据每个图像应用自定义校正,而不是对所有图像进行相同校正(尽管任何“增强”)函数隐含地考虑初始契约)。
是否有人有这样的问题和/或知道用彩色图像(没有灰度)做这个的好方法?
任何帮助将不胜感激,感谢阅读!
答案 0 :(得分:6)
您可能正在寻找的是一种执行“直方图拉伸”的实用程序。 Here is one implementation。我相信还有其他人。我想你想要保留原始色调并在所有色带上均匀地应用这个功能。
当然,很有可能一些瓷砖在它们加入的水平上会有明显的不连续性。然而,避免这种情况将涉及“拉伸”参数的空间插值,并且是更复杂的解决方案。 (......但如果有需要,这将是一项很好的练习。)
修改强>
这是一个保留图像色调的调整:
import operator
def equalize(im):
h = im.convert("L").histogram()
lut = []
for b in range(0, len(h), 256):
# step size
step = reduce(operator.add, h[b:b+256]) / 255
# create equalization lookup table
n = 0
for i in range(256):
lut.append(n / step)
n = n + h[i+b]
# map image through lookup table
return im.point(lut*im.layers)
答案 1 :(得分:2)
以下代码适用于显微镜(相似)的图像,以便在拼接之前进行准备。我在20张图像的测试集上使用它,结果合理。
亮度平均值来自另一个Stackoverflow question。
from PIL import Image
from PIL import ImageStat
import math
# function to return average brightness of an image
# Source: https://stackoverflow.com/questions/3490727/what-are-some-methods-to-analyze-image-brightness-using-python
def brightness(im_file):
im = Image.open(im_file)
stat = ImageStat.Stat(im)
r,g,b = stat.mean
return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) #this is a way of averaging the r g b values to derive "human-visible" brightness
myList = [0.0]
deltaList = [0.0]
b = 0.0
num_images = 20 # number of images
# loop to auto-generate image names and run prior function
for i in range(1, num_images + 1): # for loop runs from image number 1 thru 20
a = str(i)
if len(a) == 1: a = '0' + str(i) # to follow the naming convention of files - 01.jpg, 02.jpg... 11.jpg etc.
image_name = 'twenty/' + a + '.jpg'
myList.append(brightness(image_name))
avg_brightness = sum(myList[1:])/num_images
print myList
print avg_brightness
for i in range(1, num_images + 1):
deltaList.append(i)
deltaList[i] = avg_brightness - myList[i]
print deltaList
此时,“校正”值(即值和均值之间的差值)存储在deltaList中。以下部分逐一将此校正应用于所有图像。
for k in range(1, num_images + 1): # for loop runs from image number 1 thru 20
a = str(k)
if len(a) == 1: a = '0' + str(k) # to follow the naming convention of files - 01.jpg, 02.jpg... 11.jpg etc.
image_name = 'twenty/' + a + '.jpg'
img_file = Image.open(image_name)
img_file = img_file.convert('RGB') # converts image to RGB format
pixels = img_file.load() # creates the pixel map
for i in range (img_file.size[0]):
for j in range (img_file.size[1]):
r, g, b = img_file.getpixel((i,j)) # extracts r g b values for the i x j th pixel
pixels[i,j] = (r+int(deltaList[k]), g+int(deltaList[k]), b+int(deltaList[k])) # re-creates the image
j = str(k)
new_image_name = 'twenty/' +'image' + j + '.jpg' # creates a new filename
img_file.save(new_image_name) # saves output to new file name