【问题标题】:sklearn GaussianMixture on Imagessklearn GaussianMixture on Images
【发布时间】:2021-06-23 00:11:42
【问题描述】:

我想使用高斯混合模型来找到看起来像这样的多峰分布的中心:

为此我想使用sklearn.mixture.GaussianMixture。此代码将混合高斯分布回归到数据。通常这样做的方式类似于this:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from sklearn import mixture

n_samples = 300

# generate random sample, two components
np.random.seed(0)

# generate spherical data centered on (20, 20)
shifted_gaussian = np.random.randn(n_samples, 2) + np.array([20, 20])

# generate zero centered stretched Gaussian data
C = np.array([[0., -0.7], [3.5, .7]])
stretched_gaussian = np.dot(np.random.randn(n_samples, 2), C)

# concatenate the two datasets into the final training set
X_train = np.vstack([shifted_gaussian, stretched_gaussian])

# fit a Gaussian Mixture Model with two components
clf = mixture.GaussianMixture(n_components=2, covariance_type='full')
clf.fit(X_train)

关键是,数据以形成高斯云的二维点列表的形式给出。我的数据有点不同——更像是加权 x,y 点。鉴于我的形象,我可以这样做:

import numpy, cv2
image = cv2.imread("double_blob.jpg")
xs, ys = np.meshgrid(list(range(image.shape[0])), list(range(image.shape[1])))
xs, ys = xs.flatten(), ys.flatten()
weights = image[xs, ys].flatten()

获取 x,y 图像坐标和权重的列表。但我不知道如何将其提供给GaussianMixture 函数。有什么想法吗?

【问题讨论】:

    标签: scikit-learn


    【解决方案1】:

    我发现了一种“作弊”方式:

    from sklearn.mixture import GaussianMixture
    
    data = cv.imread("dual_blob.jpg")
    data = cv.normalize(data, None, 0, 255, cv.NORM_MINMAX)
    
    gmm = GaussianMixture(n_components=2)
    
    xs, ys = np.meshgrid(list(range(glint_size*2)), list(range(glint_size*2)))
    xs, ys = xs.flatten(), ys.flatten()
    gmm_data = [
       np.array([[x, y]] * int(data[x, y])).transpose()
       if int(data[x, y]) > 0
       else -np.ones((2, 1))
       for x, y in zip(xs, ys)
    ]
    gmm_data = np.concatenate(gmm_data, axis=1)
    gmm_data = gmm_data[gmm_data >= 0]
    gmm_data = gmm_data.reshape(2, gmm_data.shape[0] // 2).transpose()
    print(gmm_data)
    
    gmm.fit(gmm_data)
    centers = gmm.means_
    

    基本上它所做的是将图像标准化为 0 到 255 之间。然后它遍历每个像素并创建与该像素处的图像值一样多的该坐标点。因此,如果[3, 7] 处的像素值为10,则[[3, 7], [3, 7],[3, 7],[3, 7],[3, 7],[3, 7],[3, 7],[3, 7],[3, 7],[3, 7]] 将添加到点列表中进行处理。这给出了:

    但是这个解决方案实在是太了。所以我很想看看是否有人有更好的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 2017-07-12
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      相关资源
      最近更新 更多