Python中的自适应直方图均衡化

7
我正在尝试在Python中实现自适应直方图均衡化。我将一张图片分成较小的区域,然后对其应用传统的直方图均衡化。然后将这些小图像合并成一个,并获得最终的结果图像。最终图像的特点是非常块状,并且每个单独区域的对比度级别不同。是否有一种方法可以保持每个单独图像的均匀对比度,使其看起来像单个图像而不是拼接在一起的小图像。
请看下面的图片进行更好的理解:Input Output
import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy.misc import imsave
from scipy import ndimage
from scipy import misc
import scipy.misc
import scipy

import image_slicer
from image_slicer import join
from PIL import Image

img = 'watch.png'
num_tiles = 25
tiles = image_slicer.slice(img, num_tiles)


for tile in tiles:
    img = scipy.misc.imread(tile.filename)
    hist,bins = np.histogram(img.flatten(),256,[0,256])
    cdf = hist.cumsum()
    cdf_normalized = cdf *hist.max()/ cdf.max()  
    plt.plot(cdf_normalized, color = 'g')
    plt.hist(img.flatten(),256,[0,256], color = 'g')
    plt.xlim([0,256])
    plt.legend(('cdf','histogram'), loc = 'upper left')
    cdf_m = np.ma.masked_equal(cdf,0)
    cdf_o = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
    cdf = np.ma.filled(cdf_o,0).astype('uint8')
    img3 = cdf[img]
    cv2.imwrite(tile.filename,img3)
    tile.image = Image.open(tile.filename

image = join(tiles)
image.save('watch-join.png')

你确定这种算法方法是你想要的吗?你看到的结果是预期的。当然,它没有太多的平滑度。由于我不熟悉自适应直方图均衡化,我在维基百科上查找了相关算法,那里的算法非常不同(基于滑动窗口;不像你的情况中没有重叠的块),显然会得到更加平滑的结果。你也可以查看skimage的方法/实现 - sascha
你的程序相关内容翻译如下:输出结果符合你对问题的处理方式,因为你会根据不同的直方图来处理每个块。你有没有阅读过任何关于这个问题的论文或开源代码?没有必要重复造轮子。 - Piglet
@sascha,我已经发布了另一段代码来实现AHE。您是否可以审查它并提出任何改进建议? - user2808264
1个回答

2
我查看了实际算法,并提出了以下实现。我相信有更好的方法来完成这个任务。欢迎提供建议。
import numpy as np
import cv2

img = cv2.imread('watch.png',0)
print img
img_size=img.shape
print img_size

img_mod = np.zeros((600, 800))

for i in range(0,img_size[0]-30):
    for j in range(0,img_size[1]-30):
        kernel = img[i:i+30,j:j+30]
        for k in range(0,30):
            for l in range(0,30):
                element = kernel[k,l]
                rank = 0
                for m in range(0,30):
                    for n in range(0,30):
                        if(kernel[k,l]>kernel[m,n]):
                            rank = rank + 1
                img_mod[i,j] = ((rank * 255 )/900)

im = np.array(img_mod, dtype = np.uint8)
cv2.imwrite('target.png',im)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接