我正在嘗試將2D高斯擬合成圖像。噪聲非常低,所以我的嘗試是旋轉圖像,使兩個主軸不會共變化,找出最大值並只計算兩個維度的標準偏差。首選武器是python。在Python中計算圖像的特徵向量
但是我被困在發現圖像的特徵向量 - numpy.linalg.py
假設離散數據點。我想把這個圖像作爲一個概率分佈,抽樣幾千個點,然後從這個分佈中計算特徵向量,但是我相信必須有一種方法來找到特徵向量(即,半主 - 半 - 直接來自該圖像的高斯橢圓的短軸)。有任何想法嗎?
非常感謝:)
我正在嘗試將2D高斯擬合成圖像。噪聲非常低,所以我的嘗試是旋轉圖像,使兩個主軸不會共變化,找出最大值並只計算兩個維度的標準偏差。首選武器是python。在Python中計算圖像的特徵向量
但是我被困在發現圖像的特徵向量 - numpy.linalg.py
假設離散數據點。我想把這個圖像作爲一個概率分佈,抽樣幾千個點,然後從這個分佈中計算特徵向量,但是我相信必須有一種方法來找到特徵向量(即,半主 - 半 - 直接來自該圖像的高斯橢圓的短軸)。有任何想法嗎?
非常感謝:)
簡單來說,有幾種工具可以將高斯擬合成圖像。我唯一能想到的就是我的頭頂scikits.learn,這不完全是圖像導向的,但我知道還有其他的。
準確地計算協方差矩陣的特徵向量就像您想的那樣計算量非常大。你必須將每個像素(或一個大的隨機樣本)與x,y點相關聯。
基本上,你做這樣的事情:
import numpy as np
# grid is your image data, here...
grid = np.random.random((10,10))
nrows, ncols = grid.shape
i,j = np.mgrid[:nrows, :ncols]
coords = np.vstack((i.reshape(-1), j.reshape(-1), grid.reshape(-1))).T
cov = np.cov(coords)
eigvals, eigvecs = np.linalg.eigh(cov)
可以代替使用的事實,這是一個定期採樣圖像,並計算出它的時刻(或「intertial軸」)來代替。對於大圖像來說,這將快得多。
作爲一個簡單的例子,(我用的我的previous answers一個的一部分,如果你覺得它有用......)
import numpy as np
import matplotlib.pyplot as plt
def main():
data = generate_data()
xbar, ybar, cov = intertial_axis(data)
fig, ax = plt.subplots()
ax.imshow(data)
plot_bars(xbar, ybar, cov, ax)
plt.show()
def generate_data():
data = np.zeros((200, 200), dtype=np.float)
cov = np.array([[200, 100], [100, 200]])
ij = np.random.multivariate_normal((100,100), cov, int(1e5))
for i,j in ij:
data[int(i), int(j)] += 1
return data
def raw_moment(data, iord, jord):
nrows, ncols = data.shape
y, x = np.mgrid[:nrows, :ncols]
data = data * x**iord * y**jord
return data.sum()
def intertial_axis(data):
"""Calculate the x-mean, y-mean, and cov matrix of an image."""
data_sum = data.sum()
m10 = raw_moment(data, 1, 0)
m01 = raw_moment(data, 0, 1)
x_bar = m10/data_sum
y_bar = m01/data_sum
u11 = (raw_moment(data, 1, 1) - x_bar * m01)/data_sum
u20 = (raw_moment(data, 2, 0) - x_bar * m10)/data_sum
u02 = (raw_moment(data, 0, 2) - y_bar * m01)/data_sum
cov = np.array([[u20, u11], [u11, u02]])
return x_bar, y_bar, cov
def plot_bars(x_bar, y_bar, cov, ax):
"""Plot bars with a length of 2 stddev along the principal axes."""
def make_lines(eigvals, eigvecs, mean, i):
"""Make lines a length of 2 stddev."""
std = np.sqrt(eigvals[i])
vec = 2 * std * eigvecs[:,i]/np.hypot(*eigvecs[:,i])
x, y = np.vstack((mean-vec, mean, mean+vec)).T
return x, y
mean = np.array([x_bar, y_bar])
eigvals, eigvecs = np.linalg.eigh(cov)
ax.plot(*make_lines(eigvals, eigvecs, mean, 0), marker='o', color='white')
ax.plot(*make_lines(eigvals, eigvecs, mean, -1), marker='o', color='red')
ax.axis('image')
if __name__ == '__main__':
main()
您是否嘗試主成分分析(PCA)?也許MDP package可以用最少的努力完成這項工作。
擬合高斯穩健可棘手。有關於這個主題的IEEE信號處理雜誌一個有趣的文章:
紅衛郭,IEEE 信號處理雜誌,2011年9月,第「爲擬合高斯函數的簡單算法」 134--137
我給這裏的1D情況的實現:
http://scipy-central.org/item/28/2/fitting-a-gaussian-to-noisy-data-points
(向下滾動查看生成的配合)