2012-10-03 103 views
1

我實現了一個Python圖像庫圖像的平均RGB值的計算以2種方式:標杆功能爲圖像的計算平均RGB值

1 - 使用列表

def getAverageRGB(image): 
    """ 
    Given PIL Image, return average value of color as (r, g, b) 
    """ 
    # no. of pixels in image 
    npixels = image.size[0]*image.size[1] 
    # get colors as [(cnt1, (r1, g1, b1)), ...] 
    cols = image.getcolors(npixels) 
    # get [(c1*r1, c1*g1, c1*g2),...] 
    sumRGB = [(x[0]*x[1][0], x[0]*x[1][1], x[0]*x[1][2]) for x in cols] 
    # calculate (sum(ci*ri)/np, sum(ci*gi)/np, sum(ci*bi)/np) 
    # the zip gives us [(c1*r1, c2*r2, ..), (c1*g1, c1*g2,...)...] 
    avg = tuple([sum(x)/npixels for x in zip(*sumRGB)]) 
    return avg 

2 - 使用numpy的

def getAverageRGBN(image): 
    """ 
    Given PIL Image, return average value of color as (r, g, b) 
    """ 
    # get image as numpy array 
    im = np.array(image) 
    # get shape 
    w,h,d = im.shape 
    # change shape 
    im.shape = (w*h, d) 
    # get average 
    return tuple(np.average(im, axis=0)) 

我很驚訝地發現#1的運行速度比#2快大約20%。

我正確使用numpy嗎?有沒有更好的方法來實現平均計算?

回答

2

確實令人驚訝。

您可能需要使用:

tuple(im.mean(axis=0)) 

來計算你的意思(r,g,b),但我懷疑它是會提高的東西很多。您是否嘗試過配置getAverageRGBN並找到瓶頸?

+0

這大概是內存重新分配,也許np.asarray(圖像)或np.array(image.getdata(),np.uint8)將做得更好 – lolopop

+0

我認爲'平均值'有了明顯的提高。我還沒有在Python中做太多的分析 - 有什麼建議? –

+0

@MV你有一些[profilers](http://docs.python.org/library/profile.html)隨Python一起發佈,你也可以安裝一些第三方軟件包,比如['line_profiler'](http:// packages.python.org/line_profiler/):後者非常好。 –

0

一襯墊W/O改變尺寸或寫getAverageRGBN:

np.array(image).mean(axis=(0,1)) 

再次,它可能不會提高任何性能。

0

在PIL或枕頭,在Python 3.4+:

from statistics import mean 
average_color = [mean(image.getdata(band)) for band in range(3)]