【ML\CV\segmentation】EM算法&CRF模型在图像分割领域中的应用 || 学习笔记

【start:20231118】

引言

研究动机

最近经常在各种计算机视觉项目中遇到EM算法、条件随机场等概率模型,希望对他们有一些了解;

概率模型在图像分割领域的应用有助于提高分割算法的精度、鲁棒性和全局一致性,使其更适用于实际复杂的图像场景,研究这些技术可能有助于解决图像分割中存在的挑战和问题,推动分割算法的进一步发展。

简介

在图像分割领域中,EM算法和条件随机场(CRF)等概率模型被广泛应用,其优势主要包括以下几个方面:

  1. 建模灰度和颜色信息: EM算法和条件随机场可以用于建模图像中的灰度和颜色信息。通过对像素值的分布建模,可以更好地捕捉图像中的纹理和颜色特征,从而在分割过程中更准确地区分不同的目标或结构。

  2. 处理不确定性和噪声: 图像数据通常受到噪声的影响,而且由于图像中目标的复杂形状和背景变化,分割任务充满不确定性。EM算法以及条件随机场通过考虑不确定性,可以更鲁棒地处理噪声,并对分割结果的不确定性进行建模。

  3. 考虑空间关系: 条件随机场特别适用于考虑像素之间的空间关系。图像中相邻像素之间的关系对于分割任务至关重要,因为相邻区域的像素通常具有相似的特征。CRF可以通过定义合适的势函数来建模这些空间关系,从而提高分割的空间一致性。

  4. 全局一致性: 条件随机场在建模全局一致性方面具有优势。它可以通过引入全局势函数来促使整个分割结果保持一致,避免出现不自然的碎片化或断裂。这对于生成更准确的分割结果和减少伪影很重要。

  5. 融合多源信息: 这些概率模型能够融合多种信息,包括像素级的颜色、纹理、空间关系等多源信息。这种多源信息的融合有助于提高分割算法的鲁棒性和准确性,特别是在复杂场景中。

参考资料

【ref】如何通俗理解EM算法
“力争通俗易懂且完整全面,包括原理、推导、应用”…

【ref】【Noisy labels】5 篇论文详解 Learning with Noisy Label:深度学习廉价落地
EM算法(期望最大化算法)可以在一定程度上解决噪声标签的问题。

【code】https://github.com/lucasb-eyer/pydensecrf

【ref】图像分割后处理Fully connected/ Dense CRF pydensecrf的使用

【ref】Pydensecrf在灰度图像分割后处理的个人理解

算法:EM算法(EM,Expectation-Maximum)

简介

EM算法(Expectation-Maximization Algorithm)是一种迭代优化算法,通常用于解决含有隐变量的概率模型的参数估计问题。该算法由Arthur Dempster、Nan Laird和Donald Rubin于1977年提出。

参考资料

【ref】如何通俗理解EM算法
“力争通俗易懂且完整全面,包括原理、推导、应用”…

【ref】【Noisy labels】5 篇论文详解 Learning with Noisy Label:深度学习廉价落地
EM算法(期望最大化算法)可以在一定程度上解决噪声标签的问题。

算法步骤

EM算法的一般步骤如下(简单来讲,EM算法就是为每一个样本选定一个分布,然后把为他赋予这个分布的标签):

  1. 初始化: 初始化模型参数。

  2. Expectation 步骤(E步骤): 使用当前模型参数和观测数据,计算隐变量的期望(或概率分布)。这一步通常涉及到对未观测数据(隐变量)的条件概率的估计。

  3. Maximization 步骤(M步骤): 最大化在E步骤中计算的期望,更新模型参数。这一步涉及到对参数的极大似然估计或期望最大化。

  4. 迭代: 重复执行E步骤和M步骤,直到收敛,即模型参数不再显著变化或满足某个收敛准则。

EM算法主要应用于以下场景:

  • 含有隐变量的概率模型参数估计: 当模型中包含未观测到的隐变量时,EM算法可以通过迭代优化来估计模型的参数。

  • 混合模型: EM算法在混合模型(Mixture Models)中特别有用,其中观测数据被假设由多个概率分布组合而成。

  • 缺失数据估计: 当数据集中存在缺失值时,EM算法可以通过对缺失值的条件期望进行估计。

EM算法的优势在于其对于包含隐变量或缺失数据的概率模型进行参数估计的灵活性。然而,需要注意的是EM算法可能陷入局部最优,因此在实际应用中,通常需要多次运行,或者采用改进的方法来提高其稳定性和效果。

EM算法 vs 聚类算法

EM算法和聚类算法的区别?

在本质上,EM算法和聚类算法之间的主要区别在于它们的目标和建模方式:

  1. EM算法:

    • 目标: EM算法的主要目标是对混合模型进行参数估计。它假设观测数据是由若干个概率分布组成的混合体,然后通过迭代优化来估计这些分布的参数,包括均值、协方差矩阵和混合系数。
    • 建模方式: EM算法使用概率分布(通常是高斯分布)来表示不同的组件,并通过最大似然估计来更新这些分布的参数。
  2. 聚类算法:

    • 目标: 聚类算法的主要目标是将数据划分为不同的簇,使得同一簇内的数据相似度较高,不同簇之间的相似度较低。这是一种无监督学习方法,不涉及预定义的分布模型。
    • 建模方式: 聚类算法尝试找到数据中隐藏的结构,通常通过测量数据点之间的相似度,然后将相似的数据点分配到同一簇中。K均值聚类是一种常见的聚类算法,它基于数据点之间的距离来定义簇。

在实践中,虽然EM算法在混合模型参数估计中应用广泛,但它也可以被视为一种聚类方法,因为混合模型的组件可以对应于数据中的不同簇。然而,聚类算法通常更直接地专注于划分数据而不涉及对概率分布的参数估计。

总的来说,EM算法更侧重于概率模型的参数估计,而聚类算法更侧重于数据点之间的相似性和划分。


这两种算法在具体场景中如何选择?
·
简单来说,如果概率分布是看起来是较混合的,就选EM算法;如果是较分离的,就选聚类算法。

选择使用EM算法还是聚类算法(如K均值聚类)取决于你的具体问题和数据特点。每种方法都有其适用的场景和优劣势。

EM算法的优势和适用场景:

  1. 概率建模: EM算法通过概率分布建模,更适用于数据背后存在潜在概率分布的情况,特别是当数据是由多个概率分布组成的混合体
  2. 软聚类: EM算法提供了“软聚类”的能力,即每个数据点都可以属于多个组件的一部分,而不是硬性地分配到一个簇。
  3. 处理缺失数据: EM算法在处理含有缺失数据的情况下表现较好,因为它可以通过概率推断来处理缺失值。

K均值聚类的优势和适用场景:

  1. 简单且直观: K均值聚类是一种直观、简单且易于实现的算法,特别适用于大型数据集。
  2. 硬聚类: K均值聚类将每个数据点分配到一个明确的簇,属于硬聚类,适用于数据点明确属于一个组的情况
  3. 计算效率: K均值聚类在大多数情况下计算效率较高,尤其是对于具有大量数据点和低维特征的数据集。

选择建议:

  1. 数据特点: 如果你的数据中存在明显的概率分布,并且你对数据的软聚类感兴趣,那么EM算法可能更合适。
  2. 问题需求: 如果你更关注簇的紧凑性和直观的簇分配,而不太在意概率分布的建模,那么K均值聚类可能更合适。
  3. 算法复杂度: 考虑到算法的复杂度和计算效率,如果数据集很大,K均值聚类可能是一个更实际的选择。

在实际应用中,通常需要尝试不同的算法,并根据实验结果和问题需求来选择最适合的方法。

什么叫存在潜在概率分布的情况?
·
在统计学和机器学习的上下文中,"存在潜在概率分布的情况"指的是数据集中的观测数据是由一个或多个概率分布生成的情况。具体而言,这表示数据中存在潜在的、未观测到的随机过程,这些随机过程遵循某种概率分布。
·
假设我们有一个包含男性和女性身高的数据集。我们可以使用混合模型来建模这个数据集,其中有两个组件,分别对应于男性和女性的身高分布。每个组件都是一个概率分布,通常假设为正态分布。
·
图像分割时,前景和背景也可以视为两个组件


代码:使用EM算法和K均值聚类算法来识别一个包含3个高斯分布的二维数据集

'''
假设我们生成了一个包含3个高斯分布的二维数据集,表示3个不同的组件或簇。
我们的目标是使用EM算法和K均值聚类算法来识别这3个组件。
'''

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.mixture import GaussianMixture
from sklearn.cluster import KMeans

# 生成数据
data, labels_true = make_blobs(n_samples=300, centers=3, cluster_std=1.0, random_state=0)

# 使用EM算法
gmm = GaussianMixture(n_components=3, random_state=0)
gmm.fit(data)

# 获取均值和协方差矩阵
means = gmm.means_
covariances = gmm.covariances_

# 使用K均值聚类算法
kmeans = KMeans(n_clusters=3, random_state=0)
kmeans.fit(data)

# 获取簇中心
centers = kmeans.cluster_centers_

# 可视化结果
plt.figure(figsize=(12, 4))

# 原始数据
plt.subplot(131)
plt.scatter(data[:, 0], data[:, 1], c=labels_true, cmap='viridis')
plt.title('Original Data')

# EM算法的结果
plt.subplot(132)
plt.scatter(data[:, 0], data[:, 1], c=gmm.predict(data), cmap='viridis')
plt.scatter(means[:, 0], means[:, 1], c='red', marker='x', s=100)
plt.title('EM Algorithm Result')

# K均值聚类算法的结果
plt.subplot(133)
plt.scatter(data[:, 0], data[:, 1], c=kmeans.labels_, cmap='viridis')
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='x', s=100)
plt.title('K-Means Clustering Result')

plt.show()

效果:

在这里插入图片描述

EM算法与图像分割

在图像分割中,"存在潜在概率分布的情况"指的是什么?

在图像分割中,"存在潜在概率分布的情况"指的是图像中的不同区域或物体可能由不同的概率分布生成。这种情况下,图像中的像素值或特征被视为随机变量,其分布可能在图像的不同区域或物体之间变化。

具体而言,对于图像分割问题,我们假设图像中的每个像素都属于某个类别或区域,并且每个类别或区域都对应于一个概率分布。这些概率分布可以表示像素值在给定类别或区域中的分布情况。EM算法可以应用于这种情况,通过估计每个区域的概率分布参数来实现图像分割。

例如,在基于颜色的图像分割中,图像的不同区域可能具有不同的颜色分布。每个区域的颜色分布可以用一个概率分布(例如,多元正态分布)来描述。EM算法可以用于估计这些概率分布的参数,从而识别图像中不同区域的边界,并将图像分割成具有相似颜色特征的区域。

总的来说,在图像分割中,"存在潜在概率分布的情况"强调了对图像中不同区域或物体的概率模型建模,以便更好地理解和分割图像。这有助于捕捉图像中的复杂结构和变化,使得图像分割更具灵活性和适应性。


在图像分割中使用EM算法还是聚类算法?

假设我们有一张彩色图像,我们希望对其进行分割,将图像中的不同颜色区域分离出来。我们可以考虑使用EM算法和聚类算法(K均值聚类)来解决这个问题。

使用EM算法的例子:

  1. 问题描述: 我们认为图像中的不同颜色区域可以由多个高斯分布组成,每个分布对应于图像中的一个物体或区域。

  2. 方法: 我们使用EM算法来拟合高斯混合模型,其中每个分量表示一个颜色区域的概率分布。EM算法将优化高斯分布的参数,以最好地解释图像中的颜色分布。

  3. 结果: EM算法产生的结果是每个像素属于每个高斯分布的概率,从而提供了每个像素属于不同颜色区域的软分割结果。

使用聚类算法的例子:

  1. 问题描述: 我们认为图像中的不同颜色区域可以通过颜色的相似性划分为不同的簇。

  2. 方法: 我们使用K均值聚类算法,将图像中的像素划分为K个簇,其中K是预先指定的簇的数量。每个簇代表一个颜色区域。

  3. 结果: K均值聚类算法产生的结果是每个像素所属的簇标签,从而提供了硬聚类结果,即每个像素只属于一个颜色区域。

比较:

  • 如果图像中的颜色区域具有复杂的概率分布,并且我们希望获得每个像素属于不同颜色区域的概率信息,那么EM算法可能更适合。
  • 如果我们只对图像进行硬聚类,即将每个像素分配到一个确定的颜色区域,并且我们认为颜色区域之间有明显的分界,那么K均值聚类可能更直观和有效。

在实际应用中,你可能会先尝试一种方法,然后根据结果和需求进行调整。不同的图像和问题可能需要不同的方法。

代码:EM vs KMeans for segmentation(特征:RGB)

'''
EM vs KMeans for segmentation

# 将图像从三维数组转换为二维数组(二维,n行3列)
# 比如把(224, 224, 3)转换为(50176, 3)
'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from sklearn.cluster import KMeans
import cv2

# 读取图像
# image_path = r'D:\code\cell_segment_workflow\src_important\cv_preprocess\img\protein.png'
image_path = r'D:\code\cell_segment_workflow\src_important\cv_preprocess\img\wsi.png'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 将图像从三维数组转换为二维数组(二维,n行3列)
# 比如把(224, 224, 3)转换为(50176, 3)
data = image.reshape((-1, image.shape[-1]))
print(image.shape)
print(data.shape)

# 初始化Gaussian Mixture Model(EM算法)
n_components = 3  # 假设有n个颜色区域
gmm = GaussianMixture(n_components=n_components, random_state=42)
gmm.fit(data)
em_segmentation = gmm.predict(data).reshape(image.shape[:2])

# 初始化K均值聚类模型
n_clusters = 3  # 假设有n个颜色区域
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
kmeans.fit(data)
kmeans_segmentation = kmeans.labels_.reshape(image.shape[:2])

# 可视化结果
plt.figure(figsize=(12, 6))

# 原始图像
plt.subplot(131)
plt.imshow(image)
plt.title('Original Image')

# EM算法结果
plt.subplot(132)
plt.imshow(em_segmentation, cmap='viridis')
plt.title('EM Algorithm Segmentation')

# K均值聚类结果
plt.subplot(133)
plt.imshow(kmeans_segmentation, cmap='viridis')
plt.title('K-Means Clustering')

plt.show()

为什么要转换成2维数组?

在图像处理中,通常将图像转换为二维数组或一维向量的形式是为了更方便地应用各种算法和工具。图像通常是三维的,其中每个维度对应于图像的高度、宽度和通道数(例如,RGB颜色图像具有3个通道)。

在示例代码中,将图像转换为二维数组的目的是为了使用聚类算法和混合模型算法,这些算法通常期望输入为一组样本,每个样本是一个特征向量。通过将图像像素的三个通道值(在这里是RGB)堆叠在一起,我们形成了一个二维数组,其中每行表示一个像素,每列表示一个通道。

对于聚类算法,每个像素被视为一个样本,并根据其特征(颜色值)进行聚类。在混合模型中,每个像素被视为一个观测值,混合模型通过对这些观测值进行概率建模来估计潜在的颜色分布。

总之,将图像转换为二维数组的目的是为了对图像中的像素进行操作,并在机器学习或图像处理算法中应用各种工具。

案例:显微荧光蛋白图像分割

n_components = 2(希望分割出“前景”和“背景”两类)

在这里插入图片描述
n_components = 3(希望多分割出一个“边缘”类)

在这里插入图片描述

案例:病理组织图像分割

n_components = 2

在这里插入图片描述
n_components = 3

在这里插入图片描述

性能总结

EM算法对于复杂场景(病理图像)分割的整体感更好;而Kmeans算法对简单场景(显微荧光蛋白图像)分割的实例感更好

代码:EM vs KMeans for segmentation(特征:RGB+梯度信息)

根据图像特点和具体需要,可以将图像RGB信息和梯度信息合并,增加特征的丰富程度

'''
EM vs KMeans for segmentation

# 将图像RGB信息和梯度信息合并,增加特征的丰富程度
# 比如把(224, 224, 3)升级为(224, 224, 4)
'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from sklearn.cluster import KMeans
import cv2

# 读取图像
# image_path = r'D:\code\cell_segment_workflow\src_important\cv_preprocess\img\protein.png'
image_path = r'D:\code\cell_segment_workflow\src_important\cv_preprocess\img\wsi.png'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 计算图像梯度信息
gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
gradient_x = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3)
gradient_y = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3)
gradient_magnitude = np.sqrt(gradient_x**2 + gradient_y**2)

# 将图像RGB信息和梯度信息合并
# 比如把(224, 224, 3)升级为(224, 224, 4)
data_merge = np.concatenate([image, gradient_magnitude[:, :, np.newaxis]], axis=-1)
data = data_merge.reshape((-1, data_merge.shape[-1]))
print(image.shape)
print(data.shape)

# 初始化Gaussian Mixture Model(EM算法)
n_components = 2  # 假设有n个颜色区域
gmm = GaussianMixture(n_components=n_components, random_state=42)
gmm.fit(data)
em_segmentation = gmm.predict(data).reshape(image.shape[:2])

# 初始化K均值聚类模型
n_clusters = 2  # 假设有n个颜色区域
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
kmeans.fit(data)
kmeans_segmentation = kmeans.labels_.reshape(image.shape[:2])

# 可视化结果
plt.figure(figsize=(12, 6))

# 原始图像
plt.subplot(131)
plt.imshow(image)
plt.title('Original Image')

# EM算法结果
plt.subplot(132)
plt.imshow(em_segmentation, cmap='viridis')
plt.title('EM Algorithm Segmentation')

# K均值聚类结果
plt.subplot(133)
plt.imshow(kmeans_segmentation, cmap='viridis')
plt.title('K-Means Clustering')

plt.show()
案例:显微荧光蛋白图像分割

(n_components = 2)将图像和梯度信息合并为多维数组之前:

在这里插入图片描述
(n_components = 2)将图像和梯度信息合并为多维数组之后:

在这里插入图片描述
可以发现,在(n_components = 2)的场景下,加入了梯度信息后,分割结果更嘈杂了,甚至出现了空洞效应


(n_components = 3)将图像和梯度信息合并为多维数组之前:

在这里插入图片描述
(n_components = 3)将图像和梯度信息合并为多维数组之后:

在这里插入图片描述

可以发现,在(n_components = 3)的场景下,加入了梯度信息后,分割结果同样也变得更嘈杂了(不过对于kmeans算法,如右下角区域,部分实例被分割得好了一些)

案例:病理组织图像分割

(n_components = 2)将图像和梯度信息合并为多维数组之前:

在这里插入图片描述
(n_components = 2)将图像和梯度信息合并为多维数组之后:

在这里插入图片描述
可以发现,在(n_components = 2)的场景下,加入了梯度信息后,分割结果的破碎感更少了,病理组织区域的完整性更高了

性能总结

加入梯度信息对复杂场景中大片区域的分割效果有益,但是对于稀疏场景容易产生多余的噪声

EM算法与噪声标签

EM算法(期望最大化算法)可以在一定程度上解决噪声标签的问题。

噪声标签指的是在数据集中存在错误或不准确的标签。EM算法是一种迭代优化算法,通常用于含有隐变量的概率模型参数的估计。

在处理噪声标签时,EM算法的两个步骤分别是:

  1. Expectation(期望)步骤: 在这一步,通过当前模型的参数估计和观测数据,计算每个样本属于每个类别的概率。这考虑了噪声标签可能引入的不确定性。

  2. Maximization(最大化)步骤: 在这一步,使用期望步骤得到的概率信息,更新模型的参数。这包括调整模型以适应数据,同时考虑噪声标签的影响。

通过交替执行这两个步骤,EM算法可以在模型参数和隐变量上进行迭代优化,从而提高对噪声标签的鲁棒性。需要注意的是,对于不同的问题和数据集,EM算法的效果可能有所不同,而且需要谨慎调整算法参数以适应具体情况。


EM算法在处理噪声标签问题时能够取得一定效果的原因有几个:

  1. 考虑不确定性: EM算法的期望步骤(Expectation)引入了概率的概念,即对每个样本属于每个类别的概率进行估计。这种考虑不确定性的方式使得算法能够更灵活地应对噪声标签引入的错误。

  2. 迭代优化: EM算法是一种迭代优化算法,通过反复执行期望步骤和最大化步骤,不断更新模型参数。这种迭代的过程有助于逐渐纠正由噪声标签引起的模型偏差,提高模型的鲁棒性。

  3. 隐变量处理: EM算法通常应用于包含隐变量的概率模型。在噪声标签问题中,可以将真实标签视为隐变量,通过EM算法来估计模型参数和隐变量。这有助于在训练过程中更好地处理噪声标签的影响。

尽管EM算法在处理噪声标签问题时有一些优势,但也需要注意,其效果可能受到数据分布、模型选择以及算法参数等因素的影响。在实际应用中,需要根据具体情况进行调整和评估,确保算法能够有效地应对噪声标签的挑战。

【ref】【Noisy labels】5 篇论文详解 Learning with Noisy Label:深度学习廉价落地

模型:条件随机场(CRF,Conditional Random Field)

简介

条件随机场(Conditional Random Field,简称CRF)是一种统计建模方法,用于结构化预测任务,如序列标注。CRF的核心思想是在给定一系列输入变量的条件下建模一系列输出变量之间的条件概率分布。

机器学习分类算法在预测样本标签时通常不会考虑“相邻”样本的情况(如逻辑回归等),在一些上下文相关的场景中,完全忽略周围环境的影响难以产生最优的结果。比如,在自然语言处理(NLP)中的词性标注任务中,连续出现两个动词的概率很低;在计算机视觉(CV)的语义分割中,临近的像素属于同一类别的可能性较高。因此,需要一种能对样本依赖关系建模的方法。

参考资料

【code】https://github.com/lucasb-eyer/pydensecrf

【ref】图像分割后处理Fully connected/ Dense CRF pydensecrf的使用

【ref】Pydensecrf在灰度图像分割后处理的个人理解

算法步骤

CRF vs EM算法

条件随机场(CRF)和期望最大化(EM)算法是两个不同的方法(用于图像分割中的建模和优化)。它们在图像分割任务中有不同的角色和优势。

  1. CRF(条件随机场)

    • 优势:CRF 是一种概率图模型,能够有效地捕捉像素之间的关系和上下文信息。这对于图像分割任务非常有帮助,特别是在处理边界细节和像素关联性时。
    • 应用:CRF常用于 图像分割的后处理步骤,以改善基于深度学习等方法得到的初步分割结果。它有助于通过考虑全局上下文信息来提高分割的准确性。
  2. EM算法(期望最大化)

    • 优势:EM 算法主要用于参数估计,可以用于训练概率模型。在图像分割中,EM 算法可能会用于训练具有概率分布的模型参数,例如高斯混合模型。
    • 应用:EM 算法通常用于 那些基于像素的模型的训练,而不是直接应用于像素级别的分割。它更适合处理那些可以通过概率模型描述的场景。

选择依据

  • 如果你已经有一个深度学习模型或其他图像分割模型的初步结果,并且希望通过考虑像素关系来改善分割的平滑性和一致性,那么使用 CRF 作为后处理是一个不错的选择。
  • 如果你的任务更侧重于训练模型以更好地表示图像中的概率分布,并且模型可以通过迭代训练来逐渐提高准确性,那么 EM 算法可能更适合。

综合来说,两者并非互斥,可以根据具体情况选择使用它们的组合。

CRF与图像分割

条件随机场(CRF)可以用于图像分割任务。条件随机场是一种概率图模型,广泛应用于序列标注、图像分割等领域。在图像分割中,CRF通常被用来建模像素之间的关系,以改善分割的准确性。

在图像分割中,像素之间的关系对于正确地标记每个像素非常重要。CRF可以捕捉像素之间的上下文信息,考虑相邻像素之间的关系,以及它们对最终分割结果的影响。这有助于提高分割模型对图像结构的理解,使得分割结果更加准确和平滑。

总的来说,条件随机场是一种强大的工具,可用于图像分割任务,特别是在考虑到像素之间关系的情况下。

代码:先用EM算法进行粗分割

EM algorithm for segmentation

'''
EM algorithm for segmentation

将图像从三维数组转换为二维数组(二维,n行3列)
'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from sklearn.cluster import KMeans
import cv2

# 读取图像
image_path = r'/home/linxq/code/cell_seg_workflow/src_important/preprocess/img/protein.png'
# image_path = r'/home/linxq/code/cell_seg_workflow/src_important/preprocess/img/wsi.png'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 将图像从三维数组转换为二维数组(二维,n行3列)
# 比如把(224, 224, 3)转换为(50176, 3)
data = image.reshape((-1, image.shape[-1]))
print(image.shape)
print(data.shape)

# 初始化Gaussian Mixture Model(EM算法)
n_components = 3 # 假设有n个颜色区域
gmm = GaussianMixture(n_components=n_components, random_state=42)
gmm.fit(data)
em_segmentation = gmm.predict(data).reshape(image.shape[:2])

# 可视化结果
plt.figure(figsize=(10, 5))

# 原始图像
plt.subplot(121)
plt.imshow(image)
plt.title('Original Image')

# EM算法结果
plt.subplot(122)
plt.imshow(em_segmentation, cmap='viridis')
plt.title('EM Algorithm Segmentation')

plt.show()

代码:在粗分割结果上用CRF进行细分割

使用 pydensecrf 库(貌似仅Linux系统可用)来定义一个密集条件随机场(Dense Conditional Random Field,CRF)模型

'''
使用 `pydensecrf` 库来定义一个密集条件随机场(Dense Conditional Random Field,CRF)模型。

1. DenseCRF2D:
   - `image.shape[1]`:原始图像的宽度。
   - `image.shape[0]`:原始图像的高度。
   - `nlabels`:标签的数量,表示图像中可能的不同类别数目。

   这一部分创建了一个 2D 的 DenseCRF 模型,其中图像被视为一个网格,每个格点对应一个像素,有 `nlabels` 个类别。

2. unary_from_labels:
   - `em_segmentation`:期望的标签或分割图像,这是你的观察值。
   - `nlabels`:标签的数量。
   - `gt_prob=0.5`:表示每个像素的标签是真实标签的概率,这里设置为 0.5,即平等的概率。
   - `zero_unsure=False`:表示是否将不确定的像素(概率最大的标签小于 `0.5`)设置为零。这里设置为 `False`,表示不将不确定的像素设置为零。

   这一部分计算了一元能量(unary energy),即每个像素属于每个类别的概率。

3. addPairwiseGaussian:
   - `sxy=(3, 3)`:高斯核的标准差,控制平滑的程度。这里设置为 `(3, 3)`。
   - `compat=3`:两个邻近像素之间的平均场势能的兼容性,控制相邻像素之间的关联程度。这里设置为 `3`。

   这一部分添加了一个高斯平滑的平均场势能,以考虑像素之间的空间关系。

代码中构建了一个使用原始图像作为观察值的密集CRF模型,并设置了一元能量(unary energy)和平均场势能(pairwise energy)的参数,以便在图像分割任务中使用。
'''
import pydensecrf.densecrf as dcrf

nlabels = n_components
labels_image = em_segmentation
 
# 定义CRF模型
# 将原始图像作为观察值传递给CRF
d = dcrf.DenseCRF2D(image.shape[1], image.shape[0], nlabels)  # width, height, nlabels
u = unary_from_labels(labels_image, nlabels, gt_prob=0.5, zero_unsure=False)
d.setUnaryEnergy(u)

# 添加CRF平均场能量
d.addPairwiseGaussian(sxy=(3, 3), compat=3)

# 运行推断
infer = d.inference(10)  # 10是推断的迭代次数
result_crf = np.argmax(infer, axis=0).reshape(image.shape[:2])

# 可视化结果
plt.figure(figsize=(12, 6))

# 原始图像
plt.subplot(131)
plt.imshow(image)
plt.title('Original Image')

# EM算法结果
plt.subplot(132)
plt.imshow(em_segmentation, cmap='viridis')
plt.title('EM Algorithm Segmentation')

# 使用CRF修正后的结果
plt.subplot(133)
plt.imshow(result_crf, cmap='viridis')
plt.title('CRF Corrected Segmentation')

plt.show()

分割与优化的结果如下:

案例:显微荧光蛋白图像分割

gt_prob=0.6
在这里插入图片描述
gt_prob=0.4

在这里插入图片描述

案例:病理组织图像分割

gt_prob=0.6

在这里插入图片描述
gt_prob=0.5(以此为临界点,出现label翻转事件)

在这里插入图片描述

gt_prob=0.4

在这里插入图片描述

性能总结

CRF方法对gt_prob比较敏感,gt_prob太低的话,部分前景会直接被剔除,再低的话甚至会出现label翻转事件

模型:隐马尔可夫模型(HMM,Hidden Markov Model)

简介

隐马尔可夫模型(Hidden Markov Model,HMM)是一种用于建模时序数据的统计模型。它是一个由状态、观测值和状态转移概率组成的模型。在HMM中,系统的状态是不可见的,而通过观测值的序列来推断系统的状态。

HMM的基本组成部分包括:

  1. 隐藏状态(Hidden States): 描述系统内部状态的一组离散的状态,这些状态对观察者来说是不可见的。

  2. 观测值(Observations): 描述系统外部可见的结果,是观测者可以测量到的数据。

  3. 状态转移概率(Transition Probabilities): 描述系统从一个隐藏状态转移到另一个隐藏状态的概率。

  4. 观测概率(Emission Probabilities): 描述在特定隐藏状态下观察到某个观测值的概率。

HMM常被用于时序数据的建模,如语音识别、手写体识别、自然语言处理等领域。它的特点在于可以处理不完整的数据序列,并且能够捕捉序列中的时序关系。 HMM的学习和推断通常使用Baum-Welch算法和Viterbi算法等方法。

应用

隐马尔可夫模型(HMM,Hidden Markov Model)可以用来做图像分割吗?

隐马尔可夫模型(HMM)通常更适用于序列数据的建模,例如语音识别、自然语言处理等,而不太适合图像分割这样的像素级任务。图像分割通常涉及到像素之间的空间关系和局部特征,而HMM主要关注序列的状态转移和观测概率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值