2017-09-08 6 views
0

image 1私は添付画像における明るい被写体の向きを検索したいPCA

image 2

を使用してオブジェクトの向きを探します。この目的のために、主成分分析(PCA)を使用しました。

イメージ1の場合、最初の主成分がその方向にアライメントされるため、PCAは正しい向きを見つけます。しかし、画像2の場合、主成分は方向を変える。

PCAが2つの画像で異なる結果を表示している理由は誰でも説明できますか?また、オブジェクトの向きを見つけるための他の方法があるかどうかを提案してください。

import os 
import gdal 
import matplotlib 
import matplotlib.pyplot as plt 
import numpy as np 
import skimage 
from skimage.filters import threshold_otsu 
from skimage.filters import try_all_threshold 
import cv2 
import math 
from skimage import img_as_ubyte 
from skimage.morphology import convex_hull_image 
import pandas as pd 

file="path to image file" 

(fileRoot, fileExt)= os.path.splitext(file) 

ds = gdal.Open(file) 
band = ds.GetRasterBand(1) 
arr = band.ReadAsArray() 
geotransform = ds.GetGeoTransform() 
[cols, rows] = arr.shape 
thresh = threshold_otsu(arr) 
binary = arr > thresh 
points = binary>0 
y,x = np.nonzero(points) 
x = x - np.mean(x) 
y = y - np.mean(y) 
coords = np.vstack([x, y]) 
cov = np.cov(coords) 
evals, evecs = np.linalg.eig(cov) 
sort_indices = np.argsort(evals)[::-1] 
evec1, evec2 = evecs[:, sort_indices] 
x_v1, y_v1 = evec1 
x_v2, y_v2 = evec2 
scale = 40 
plt.plot([x_v1*-scale*2, x_v1*scale*2], 
     [y_v1*-scale*2, y_v1*scale*2], color='red') 
plt.plot([x_v2*-scale, x_v2*scale], 
     [y_v2*-scale, y_v2*scale], color='blue') 
plt.plot(x,y, 'k.') 
plt.axis('equal') 
plt.gca().invert_yaxis() 
plt.show() 
theta = np.tanh((x_v1)/(y_v1)) * 180 /(math.pi) 
+0

オリジナルの画像は 'tiff'形式で、地理座標情報を持っていたため、 'arr'という配列の画像を読むために 'gdal'が使用されていました。しかし、添付された画像は 'png'形式であり、配列で直接読み取ることができます。気をつけてください。前もって感謝します! –

+0

私はあなたのコードを正しく理解していれば、画像内のすべての点を使って、主な白い部分だけでなく向きを得ることができます。 –

+0

は点密度の問題のようです... 2番目の画像オブジェクトは非常に小さく、ノイズポイントは比較的大きな密度で分散していますので、** PCA **のオブジェクトポイントを選択しなかった場合、結果は歪みます... btw if約** OBB **で十分です。[複数の曲線のOBBを計算する方法](https://stackoverflow.com/a/42997918/2521214) – Spektre

答えて

0

白いピクセルだけを使用していると主張しています。オーバーレイレンダリングで選択されているものを確認しましたか?とにかく、完全に飽和した白いピクセルが含まれていないので、特に2番目のイメージでは十分ではないと思います。私はPCAの前にもっと多くの処理を使います。

  1. あなたの現在の画像のダイナミックレンジを向上させる彼らは黒と白のほぼ完全に飽和の両方が含まれているとして、この手順は必要ありません。このステップにより、より多くのサンプル入力画像間で閾値を統一することが可能になる。詳細は以下を参照してください。

  2. は、このステップが大幅恋人雑音点の強度と大きなオブジェクトのエッジを滑らかに(それら縮小するビット

    を平滑化ビット)。これは、任意のFIRフィルタまたは畳み込みまたはガウスフィルタリングによって行うことができる。また、いくつかは、形態学演算子を使用しています。これは(黒にクリア)より暗い画素を除去するので、ノイズを完全に元のサイズに戻ってモルフォロジー演算子によってオブジェクトを残り

  3. 拡大を除去する

    強度によって

  4. 閾値

    結果として生じるOBBを少数のピクセルで拡大することによってこれを避けることができます(数字は#2から滑らかな強さに拘束されます)。

  5. は今、あなたがそれを使用PCAを使用しているOBB検索

    を適用します。私は、この代わりに使用しています:

    results

は、私はこれらの結果を得た(#4なし)上記のアプローチを使用して画像をしようとしたとき

2番目の画像で気付いたもう1つの問題は、白が多くないことですその中のピクセル。これは、特に前処理を行わずにPCAに偏っている可能性があります。私はバイキュービックフィルタリングによって画像を拡大し、それを入力として使用しようとします。それがあなたが持っている唯一の問題であるかもしれません。

+0

あなたの提案と同じように、otsuしきい値画像上の凸包(skimage.morphology)を使用して、前処理ステップとしてオブジェクトを拡大しました。その場合にも、PCAは機能していません。 –

+0

PCAの解釈に問題があるかもしれません。場合によっては、オブジェクト自体の向きである必要がない主成分を提供します。前処理された入力画像を共有できますか?これはいくつかの光を照らすかもしれません。とにかく、私は代わりに幾何学的アプローチを使用することができます。精度は初期角度テーブルのサイズに制限されますが、円の範囲全体を処理する必要はなく、再帰的に強化できます。 – Spektre

関連する問題