python - 图像直方图的高斯混合模型

标签 python scikit-learn gaussian image-segmentation mixture-model

我正在尝试根据像素强度值对 2D MR 图像的不同区域进行自动图像分割。第一步是在图像的直方图上实现高斯混合模型。

test.jpg

我需要将通过 score_samples 方法获得的结果高斯绘制到直方图上。我尝试按照 ( Understanding Gaussian Mixture Models) 的答案中的代码进行操作。

但是,生成的高斯分布与直方图完全不匹配。如何让高斯匹配直方图?

import numpy as np
import cv2
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

# Read image
img = cv2.imread("test.jpg",0)

hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist[0] = 0     # Removes background pixels

# Fit GMM
gmm = GaussianMixture(n_components = 3)
gmm = gmm.fit(hist)

# Evaluate GMM
gmm_x = np.linspace(0,255,256)
gmm_y = np.exp(gmm.score_samples(gmm_x.reshape(-1,1)))


# Plot histograms and gaussian curves
fig, ax = plt.subplots()
ax.hist(img.ravel(),255,[1,256])
ax.plot(gmm_x, gmm_y, color="crimson", lw=4, label="GMM")

ax.set_ylabel("Frequency")
ax.set_xlabel("Pixel Intensity")

plt.legend()

plt.show()

我还尝试用总和手动构造高斯分布。

enter image description here

import numpy as np
import cv2
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

def gauss_function(x, amp, x0, sigma):
    return amp * np.exp(-(x - x0) ** 2. / (2. * sigma ** 2.))

# Read image
img = cv2.imread("test.jpg",0)

hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist[0] = 0     # Removes background pixels

# Fit GMM
gmm = GaussianMixture(n_components = 3)
gmm = gmm.fit(hist)

# Evaluate GMM
gmm_x = np.linspace(0,255,256)
gmm_y = np.exp(gmm.score_samples(gmm_x.reshape(-1,1)))

# Construct function manually as sum of gaussians
gmm_y_sum = np.full_like(gmm_x, fill_value=0, dtype=np.float32)
for m, c, w in zip(gmm.means_.ravel(), gmm.covariances_.ravel(), gmm.weights_.ravel()):
    gauss = gauss_function(x=gmm_x, amp=1, x0=m, sigma=np.sqrt(c))
    gmm_y_sum += gauss / np.trapz(gauss, gmm_x) * w

# Plot histograms and gaussian curves
fig, ax = plt.subplots()
ax.hist(img.ravel(),255,[1,256])
ax.plot(gmm_x, gmm_y, color="crimson", lw=4, label="GMM")
ax.plot(gmm_x, gmm_y_sum, color="black", lw=4, label="Gauss_sum", linestyle="dashed")

ax.set_ylabel("Frequency")
ax.set_xlabel("Pixel Intensity")

plt.legend()

plt.show()

使用 ax.hist(img.ravel(),255,[1,256], normed=True) enter image description here

最佳答案

问题在于将直方图而不是像素强度数组传递给 GaussianMixture.fit gmm = gmm.fit(hist)。 我还发现至少需要 n_components = 6 才能在视觉上适合这个特定的直方图。

enter image description here

import numpy as np
import cv2
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

# Read image
img = cv2.imread("test.jpg",0)

hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist[0] = 0     # Removes background pixels

data = img.ravel()
data = data[data != 0]
data = data[data != 1]  #Removes background pixels (intensities 0 and 1)

# Fit GMM
gmm = GaussianMixture(n_components = 6)
gmm = gmm.fit(X=np.expand_dims(data,1))

# Evaluate GMM
gmm_x = np.linspace(0,253,256)
gmm_y = np.exp(gmm.score_samples(gmm_x.reshape(-1,1)))


# Plot histograms and gaussian curves
fig, ax = plt.subplots()
ax.hist(img.ravel(),255,[2,256], normed=True)
ax.plot(gmm_x, gmm_y, color="crimson", lw=4, label="GMM")

ax.set_ylabel("Frequency")
ax.set_xlabel("Pixel Intensity")

plt.legend()

plt.show()

关于python - 图像直方图的高斯混合模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45805316/

相关文章:

python - scikit-learn 是否执行 "real"多元回归(多个因变量)?

python - python中是否有用于均方根误差(RMSE)的库函数?

python - 如何将 Python 映射函数与 sklearn preprocessing.scale 结合使用?

swift - 在 Swift 中调整 UIVisualEffectView 中模糊效果的强度

python - 如何获取最大密度坐标

python - Python 类中的两个构造函数

python - 限制 TwitterSearch API,python

python - 我尝试在 Kickstarter 上获取不同项目的支持者和所在城市

image - 如何将高斯滤波器应用于 OpenCV 中的 DFT 输出

python - 避免 2 个进程(2 个 OMXPlayer 实例)之间的时间间隔