2010-11-20 21 views
5

私は、特異値分解を含むCalc IIIコースのプログラミングプロジェクトに取り組んでいる大学の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 

これは、Aに画像を変換するだけだった割り当ての最初の部分のために正しく働いていました行列(線形代数は関与しない)。

しかし、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

。 RGBチャンネルごとにSVDを行う予定ですか?言い換えれば、m x n x 3配列を作成しても、SVDは任意のサイズのテンソルではなく行列に対して定義されるため、SVD関数に渡すことはできません。 –

答えて

2

phによってpwによって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

確かに、それは簡単で、私はgetRGBの周りにlist()を入れました。 ファイル:しかし、あなたの変更を実行した後、私は新しいエラー入門 "C:\ Python24 \ Libの\サイトのパッケージを\ numpyの\ linalg \ linalg.py"、行720、SVDで _assertRank2(a)の ファイル」 C:¥Python24¥Lib¥site-packages¥numpy¥linalg¥linalg.py "、行116、_assertRank2 raise LinAlgError、 '%d次元の配列が指定されています。配列は\ でなければなりません。LinAlgError:3次元配列が指定されています。配列は2次元でなければなりません したがって、numPyで動作するタプルの "2-d"マトリックスを持つ方法がまだ必要です。 – Thomas

+0

2番目の考えでは、これは意味をなさないものです。私はあなたがエントリがタプルである2D行列のSVDを見つけることはできないと思います.3D行列のSVDのようなものがあれば、間違いなく私のクラスとこのプロジェクトの範囲を超えています。私はどのように各色チャネルのためにこれを行うかを把握し、それらの3つの行列を何らかの形で組み合わせる必要があります。回答いただきありがとうございます。 – Thomas

+0

SVD [DeLathauwer 2000] [Mesgarani 2004]の3D版がありますが、あなたが望むものではないと思われます。顔認識などのタスクでは、多くの場合、画像全体をベクトル化*し、それらのベクトルをサイズ(h * w)の大きな行列「X」に連結し、画像上でPCAを実行します。 'XX^T'のSVDと同等です。私はここで関連する質問に答えた:http://stackoverflow.com/questions/4171866/creating-a-dataset-from-an-image-with-python-for-face-recognition/4176400#4176400 –

7

配列要素の型を 'O'(オブジェクト)に設定する代わりに、タプルに設定する必要があります。いくつかの例については、the SciPy manualを参照してください。あなたのケースでは

は、最も簡単には、あなたのRGB値が3つの浮動小数点数のタプルあると仮定すると、

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

のようなものを使用することです。

これはkタプルの要素であり、実際に、タプル要素はa[n,m][k]又はz[n,m,k]としてアクセスされ、3Dアレイを作成する(スティーブが示唆されたように)と同様です。

もちろん、SVDは3d配列ではなく2d行列に対して定義されているので、linalg.svd(a)は使用できません。必要な行列(R GとB)のSVDを決定する必要があります。

たとえば、あなたは次のように(つまり、タプルの最初の要素であると仮定して)「R」行列のSVDが何かを使用したい、場合:SVDのみの行列上で動作

linalg.svd(a[:,:,1]) 
関連する問題