2013-04-21 51 views
1

我正在玩Python中的腳本,我想查找大量相同尺寸的圖像的中值。也就是說,我不想採用位置[x,y]上的所有(紅色,綠色和藍色)像素,並用它們的中值構造新圖像。查找多個RGB圖像的中值的有效方法

我目前的方法使用Python PIL(圖像庫),但它很慢!我非常想使用OpenCV(cv2)接口,因爲它直接將每個圖像作爲一個numpy數組加載。但是,當堆疊尺寸爲(2560,1920,3)的x圖像時,我不斷收到索引錯誤。任何幫助?

我現在,與PIL低效的代碼,如下所示:

from PIL import Image, ImageChops,ImageDraw,ImageFilter,cv 
import sys,glob,sys,math,shutil,time,os, errno,numpy,string 
from os import * 

inputs =() 
path = str(os.getcwd()) 
BGdummyy=0 
os.chdir(path) 
for files in glob.glob("*.png"): 
    inputs = inputs + (str(str(files)),) 
BGdummy=0 
for file in inputs: 
    BGdummy=BGdummy+1 
    im = cv.LoadImage(file) 
    cv.CvtColor(im, im, cv.CV_BGR2RGB) 
    img = Image.fromstring("RGB", cv.GetSize(im), im.tostring()) 
    vars()["file"+str(BGdummy)] = img.load() 
imgnew = Image.new("RGB", (2560,1920)) 
pixnew = imgnew.load() 
for x in range(2560): 
    for y in range(1920): 
     R=[];G=[];B=[]; 
     for z in range(len(inputs)): 
      R.append(vars()["file"+str(z+1)][x,y][0]) 
      G.append(vars()["file"+str(z+1)][x,y][1]) 
      B.append(vars()["file"+str(z+1)][x,y][2]) 
     R = sorted(R) 
     G = sorted(G) 
     B = sorted(B) 
     mid = int(len(inputs)/2.) 
     Rnew = R[mid] 
     Gnew = G[mid] 
     Bnew = B[mid] 
     pixnew[x,y] = (Rnew,Gnew,Bnew) 
    BGdummyy = BGdummyy+1 
imgnew.save("NewBG.png") 
+0

我從來沒有使用它,但它可能值得檢查'scipy' - http://docs.scipy.org/doc/scipy/reference/ndimage.html - 它會加載它作爲一個數組,您可以使用對於操縱 – 2013-04-21 20:22:10

回答

3

我將演示如何與大小的5門個小陣列(3,3,3)做到這一點。

首先,我將創建5個數組,然後將它們保存在列表X中。在您的情況下,您將保留30個圖像在此列表中。 (我正在做一條線)

X = [a,b,c,d,e] = [np.random.randint(0,255,(3,3,3)) for i in xrange(5)] 

接下來,你將每個圖像平鋪爲一長的單行。所以早些時候你的形象會像

[R1G1B1 R2G2B2 R3G3B3, 
R4G4B4 R5G5B5 R6G6B6, 
R7G7B7 R8G8B8 R9G9B9] 

這將變成[R1 G1 B1 R2 G2 B2 R3 G3 B3......... R9 G9 B9]。然後你將所有這些扁平圖像疊加起來,形成一個大的二維數組。在該數組中,您會看到,所有第一個紅色像素出現在第一列,依此類推。然後,您可以簡單地應用np.median。

Y = np.vstack((x.ravel() for x in X)) 

我拿走了每張圖片並堆放。在我的情況,Y是大小5x27陣列(行 - 圖像的數量,列 - 像素數的圖像)

現在我發現這個的Y值,並重新塑造我們原來的圖像形狀:

Z = np.median(Y,axis = 0) 
Z = np.uint8(Z.reshape(a.shape)) 

完成。

只是爲了確保其工作正常,讓我們檢查任意像素的像素值,說Z[0,1,2]

In [50]: G1 = [x[0,1,2] for x in X] 

In [51]: G1 
Out[51]: [225, 65, 26, 182, 51] 

In [52]: Z[0,1,2] 
Out[52]: 65.0 

是的,數據是正確的。

+0

我的問題是,我有,例如,30圖像,我想將他們的中值轉換爲新的圖像。所以我需要的是:3個紅色,綠色和藍色像素堆棧。 x和y方向是像素的方向,而z方向是單個圖像。在每個像素(x,y)處,我需要z方向的中值。因此,我現在最大的問題是要找到一種方法來以合理的3D方式堆疊圖像,然後我可以利用您建議的「np.median」命令。 請讓我知道,如果它沒有任何意義,那麼我會盡力詳細=) – Bjarke 2013-04-22 10:53:35

+0

對不起,我誤解了你的問題。檢查我是否正確:您有30張彩色圖像。結果也是一個彩色圖像。在結果圖像中,第一個像素的藍色值是所有30幅圖像的第一個像素 - >藍色值的中值。同樣的紅色和綠色等,這是你想要的? – 2013-04-22 11:15:22

+0

準確(或任意數量的圖像)。我現在可以用PIL庫來做,但由於我需要使用「加載像素」命令,所以速度很慢。我想按照您的建議將所有內容都保存在Numpy和OpenCV(2)中。但基本上我已經摸索着以一種很好的方式添加numpy數組來獲得中值。提前致謝! – Bjarke 2013-04-22 17:12:53

相關問題