2010-11-20 56 views
5

我是大學的CS專業,主要從事計算三級計劃編程項目,涉及奇異值分解。該想法基本上是將m×n維的圖像轉換爲m×n矩陣,其中每個元素是代表點(m,n)處像素的顏色通道(r,g,b)的元組。我使用的是Python,因爲它是迄今爲止唯一真正教授的語言。Python - NumPy - 作爲數組元素的元組

從我可以告訴,Python通常不喜歡元組作爲數組的元素。我做了我自己的一個小小的研究,發現了一個解決方案,即預分配數組如下:

def image_to_array(): #converts an image to an array 
    aPic = loadPicture("zorak_color.gif") 
    ph = getHeight(aPic) 
    pw = getWidth(aPic) 
    anArray = zeros((ph,pw), dtype='O') 
    for h in range(ph): 
     for w in range(pw):    
      p = getPixel(aPic, w, h) 
      anArray[h][w] = (getRGB(p)) 
    return anArray 

這工作正常進行分配的第一部分,這是簡單地將圖像轉換爲一矩陣(不涉及線性代數)。

儘管如此,SVD的部分卻變得更加棘手。當我調用內置numpy的SVD功能,使用我從我的形象建造的陣列(其中每個元素是一個元組),我收到以下錯誤:

Traceback (most recent call last): 
    File "<pyshell#5>", line 1, in -toplevel- 
    svd(x) 
    File "C:\Python24\Lib\site-packages\numpy\linalg\linalg.py", line 724, in svd 
    a = _fastCopyAndTranspose(t, a) 
    File "C:\Python24\Lib\site-packages\numpy\linalg\linalg.py", line 107, in _fastCopyAndTranspose 
    cast_arrays = cast_arrays + (_fastCT(a.astype(type)),) 
ValueError: setting an array element with a sequence. 

這是同樣的錯誤我正在開始,之前我做了一些研究,發現我可以預分配我的數組,允許元組作爲元素。

現在的問題是,我只在我的第一學期(大學水平)編程,這些專業程序員編寫的numPy函數對我來說有點過於黑暗(儘管我確信他們對於那些有經驗的人來說更加清楚)。所以編輯這些函數以允許元組比我在自己的函數上做的更復雜一些。我需要從哪裏出發?我假設我應該將相關的numPy函數複製到我自己的程序中,並相應地修改它們?

在此先感謝。

+3

的SVD僅適用於矩陣。你打算爲每個RGB通道做一個SVD嗎?換句話說,即使你形成一個m×n×3的數組,你也不能將它傳遞給SVD函數,因爲SVD是爲矩陣而不是任意大小的張量定義的。 – 2010-11-20 07:07:39

回答

2

我想你想要一個phpw通過3 numpy數組。

anArray = zeros((ph,pw,3)) 
for h in range(ph): 
    for w in range(pw):    
     p = getPixel(aPic, w, h) 
     anArray[h][w] = getRGB(p) 

你只需要確保getRGB返回一個3元素列表,而不是一個元組。

+0

當然,這很容易,我只是把list()放在getRGB周圍。但在執行完更改後,我開始出現一個新錯誤: svd中的文件「C:\ Python24 \ Lib \ site-packages \ numpy \ linalg \ linalg.py」行720,其中包含文件「 C:\ Python24 \ Lib \ site-packages \ numpy \ linalg \ linalg.py「,第116行,在_assertRank2 引發LinAlgError'%d維數組給定。數組必須是\ LinAlgError:給出的三維數組。數組必須是二維的 所以我仍然需要一種方法來創建一個可以與numPy一起工作的「2-d」元組矩陣... – Thomas 2010-11-20 07:29:00

+0

第二個想法是,這並沒有什麼意義。我不認爲你可以找到一個二維矩陣的SVD,這個矩陣的元素是元組,如果存在3D矩陣的SVD這樣的事情,那肯定超出了我的課程和這個項目的範圍。我需要弄清楚如何爲每個顏色通道執行此操作,然後以某種方式組合這三個矩陣。感謝您的答覆。 – Thomas 2010-11-20 07:38:54

+0

*是* SVD [DeLathauwer 2000] [Mesgarani 2004]的3D版本,但我懷疑它不是你想要的。對於諸如人臉識別之類的任務,人們通常矢量化*整個圖像*,然後將這些矢量連接成大小爲(h * w)的大矩陣「X」(數字圖像),然後*在X上執行PCA '這相當於'XX^T'的SVD。我在這裏回答了一個相關問題:http://stackoverflow.com/questions/4171866/creating-a-dataset-from-an-image-with-python-for-face-recognition/4176400#4176400 – 2010-11-20 13:49:32

7

不應將數組元素類型設置爲'O'(對象),而應將其設置爲元組。有關示例,請參閱the SciPy manual

在你的情況,最簡單的就是使用類似

a = zeros((ph,pw), dtype=(float,3)) 

假設你的RGB值是3個浮點數的元組。

這與創建3D數組類似(如Steve所建議的),實際上,元組元素的訪問形式爲a[n,m][k]z[n,m,k],其中k是元組中的元素。

當然,SVD是爲2d矩陣定義的,而不是3d數組,因此您不能使用linalg.svd(a)。你必須決定你需要什麼矩陣(三種可能的矩陣:R G和B)的SVD。

如果,例如,你想要的「R」矩陣的SVD(假設是元組的第一個元素),使用這樣的:

linalg.svd(a[:,:,1])