Вычислить собственные векторы изображения в python

Я пытаюсь подогнать 2D Gaussian к изображению. Шум очень низкий, поэтому я попытался повернуть изображение так, чтобы две главные оси не менялись, вычислить максимум и просто вычислить стандартное отклонение в обоих измерениях. Оружие выбора - питон.

2D более или менее гауссовское распределение

Однако я застрял в поиске собственных векторов изображения - numpy.linalg.py предполагает дискретные точки данных. Я думал о том, чтобы принять это изображение за распределение вероятностей, отобрав несколько тысяч точек, а затем вычислив собственные векторы из этого распределения, но я уверен, что должен быть способ найти собственные векторы (т. малые оси гауссова эллипса) непосредственно из этого изображения. Любые идеи?

Большое спасибо :)


person Manuel Ebert    schedule 25.01.2012    source источник


Ответы (3)


Небольшое замечание: есть несколько инструментов для подгонки гаусса к изображению. Единственное, что мне приходит в голову, это scikits.learn, который не t полностью ориентирован на изображение, но я знаю, что есть и другие.

Чтобы вычислить собственные векторы ковариационной матрицы точно так, как вы имели в виду, очень затратно в вычислительном отношении. Вы должны связать каждый пиксель (или большую случайную выборку) изображения с точкой 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)

Вместо этого вы можете использовать тот факт, что это изображение с регулярной выборкой, и вместо этого вычислить его моменты (или «промежуточные оси»). Это будет значительно быстрее для больших изображений.

В качестве быстрого примера (я использую часть одного из моих предыдущих ответов, если вы сочтете это полезным. ..)

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()

введите здесь описание изображения

person Joe Kington    schedule 25.01.2012

Надежная подгонка гауссианы может быть сложной задачей. В журнале IEEE Signal Processing Magazine была забавная статья на эту тему:

Хунвэй Го, «Простой алгоритм подбора функции Гаусса», журнал IEEE Signal Processing, сентябрь 2011 г., стр. 134–137.

Я даю реализацию случая 1D здесь:

http://scipy-central.org/item/28/2/fitting-a-gaussian-to-noisy-data-points

(Прокрутите вниз, чтобы увидеть получившиеся совпадения)

person Stefan van der Walt    schedule 07.02.2012

Вы пробовали анализ главных компонентов (PCA)? Возможно, пакет MDP мог бы выполнить эту работу с минимальными усилиями.

person TH.    schedule 25.01.2012