2017-04-23 93 views
3

我正試圖在python中實現自適應直方圖均衡化。我拍攝一張圖像並將其分割成較小的區域,然後將傳統的直方圖均衡應用於它。然後將較小的圖像合併爲一個並獲得最終的合成圖像。最終的圖像本質上看起來很塊,對每個區域都有不同的對比度。有沒有一種方法可以保持每個單獨圖像的統一對比度,以便它看起來像是一張圖像,而不是較小的圖像拼接在一起。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') 
+0

你確定這個算法的方法是你想要的嗎?你看到的結果是預期的。當然沒有太多的流暢性。由於我對自適應hist-eq不熟悉,因此我查了一下維基百科,其中的算法非常不同(基於滑動窗口;沒有像您的情況那樣不重疊的塊),並且顯然會導致更平滑的事情。您還可以查看[skimage的方法/實施](http://scikit-image.org/docs/stable/api/skimage.exposure.html#skimage.exposure.equalize_adapthist)。 – sascha

+0

輸出結果是您對問題的處理方式所期望的結果......您將不同的直方圖對每個塊進行不同的處理。您是否閱讀過有關該問題的任何論文或任何開源代碼?沒有理由重新發明輪子... – Piglet

+0

@sascha我發佈了不同的代碼來實現AHE。您是否可以查看它並建議進行任何更改以進一步改進它。 – user2808264

回答

0

我回顧了實際的算法,並與下面的實施上來。我相信有更好的方法來做到這一點。任何建議表示讚賞。

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)