2017-03-23 11 views
1

私が解決しようとしている問題は次のようなものです。イメージ内に斑点がある場合、私はその領域を埋めるために線を引くガイドを取得したいと考えています。私は可能な限り数行を使用するように、線がその領域の長軸に沿っているようにしたい。なぜ主成分分析が私に劇的に異なる結果をもたらすのですか?

私の周りグーグル、及びブロブの配向を得るために良い方法として、PCA(主成分分析)に遭遇し、PCAアルゴリズムを供給することにより、すべての点座標:

https://alyssaq.github.io/alyssaq.github.io/2015/computing-the-axes-or-orientation-of-a-blob/index.html

が、正確なアルゴリズムをコピー、私は非常に驚くべき結果を得る。同様の形状の領域が与えられると、PCAアルゴリズムは完全に異なる固有ベクトルを返す。それらは垂直に見える:上記

Different directions

線がわずかランダムばらつきと、PCAアルゴリズムによって与えられる傾きに追従してレンダリングされます。

ここでは何が起こっているのですか?この問題にどのように対処すればよいですか?

コード:

import numpy as np 

# I tried passing different set of points to pca: 
# 1. Only points at the perimeter of the area 
# 2. Random sample of points within the area 
# 3. All points in the area 

# points are like [(x1, y1), (x2, y2), ... ] 
def pca(points): 
    xs, ys = zip(*points) 
    x = np.array(xs) 
    y = np.array(ys) 

    # Subtract mean from each dimension. We now have our 2xm matrix. 
    x = x - np.mean(x) 
    y = y - np.mean(y) 
    coords = np.vstack([x, y]) 

    # Covariance matrix and its eigenvectors and eigenvalues 
    cov = np.cov(coords) 
    vals, evecs = np.linalg.eig(cov) 

    # Sort eigenvalues in decreasing order (we only have 2 values) 
    sort_indices = np.argsort(vals)[::-1] 

    evec1, evec2 = evecs[:, sort_indices] # Eigenvector with largest eigenvalue 
    eval1, eval2 = vals[sort_indices[0]], vals[sort_indices[1]] 
    print("PCA:", evec1, evec2, eval1, eval2) 
    return evec1, evec2, eval1, eval2 

私はPCAに点の異なるセットを通過しようとした:

  1. 点のみを領域の周囲に点の
  2. ランダムサンプル領域内
  3. エリア内の全ポイント

しかし、それは重要ではありません、ポイント選択のそれぞれで、私のアルゴリズムは、上記2パターンを生成することができます。右のもの(間違ったもの)がより頻繁に生産されるようですが。

evec1, evec2 = evecs[:, sort_indices] 

固有ベクトルを列にあるが、その割り当てはevecs[:, sort_indices]evec1への最初のevec2第2行を割り当て:

+0

です。コードを正確にコピーした場合は、黒点ではなく白点を分析しています。イメージを反転する必要があります。また、しきい値を適用することもできます。 –

+0

コードを追加できますか?また、「同様の形状の領域を考えると、PCAアルゴリズムは完全に異なる固有ベクトルを返します」 - ソート手順をスキップすることは可能ですか?長軸ではなく短軸固有ベクトルを使用した右イメージのように見えます。 –

+0

エリアの座標はすべて正しいです。私の質問の画像は、PCAによって与えられた軸に従うことによって、ブロブアアレスを満たすために線でレンダリングされます、私はまた、より明確に見るために少し傾きをランダムに調整します。固有値で固有ベクトルをソートすることも忘れませんでした。私はすぐにコードと戻り値を投稿します。 – NeoWang

答えて

1

間違いは、この行です。クイックフィックスは

evec1, evec2 = evecs[:, sort_indices].T 
+0

はい、それは問題です。どうもありがとうございます! – NeoWang

関連する問題