बस एक त्वरित नोट, एक छवि के लिए एक गाऊशियन फिट करने के लिए कई उपकरण हैं। मेरे सिर के शीर्ष से बाहर निकलने वाली एकमात्र चीज 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()
