花卉图像分割项目:背景、解决方案与详细注释代码

一、项目背景

图像分割是计算机视觉核心任务之一,旨在将图像划分为具有语义意义的不同区域,广泛应用于花卉分类、农业病虫害检测、医学影像分析、自动驾驶等领域。
花卉图像的颜色分布具有连续性和多峰性(花瓣、叶片、花萼、背景的颜色分别呈高斯分布特征):

  • 传统阈值分割仅适用于对比度高、颜色单一的场景,无法适配花卉颜色的复杂分布;
  • K-Means等硬聚类算法仅输出“非此即彼”的聚类标签,无法捕捉颜色的概率分布特征;
  • 高斯混合模型(GMM)作为概率型软聚类算法,能拟合像素颜色的多峰高斯分布,输出每个像素属于不同区域的概率,更精准实现花卉图像的无监督分割。
    在这里插入图片描述

二、解决问题的方案

本项目针对花卉图像的颜色分布特性,采用GMM算法实现无监督图像分割,核心流程如下:

步骤核心动作解决的问题
环境配置配置matplotlib中文字体,关闭负号显示异常避免可视化时中文/负号渲染警告,保证图表可读性
图像预处理读取图像→转为numpy数组→展平为二维矩阵(像素数×3)将三维图像数据适配GMM模型的输入格式(样本数×特征数)
模型构建初始化GMM(4类聚类、tied协方差)4类适配花卉主要区域(花瓣/叶片/花萼/背景),tied降低计算复杂度
模型训练拟合RGB像素数据,学习均值/协方差/混合系数捕捉不同区域的颜色分布特征
聚类预测为每个像素分配最可能的聚类标签实现像素级的区域划分
结果可视化重塑标签为原始图像尺寸→绘图展示直观呈现分割效果,验证算法有效性

三、详细注释代码

# ====================== 1. 导入核心库(按功能分类,标注导入原因) ======================
# 导入高斯混合模型(GMM):
# - 核心算法,基于概率的软聚类,适配RGB像素的连续高斯分布特征,优于硬聚类的K-Means
# - 支持无监督学习,无需标注图像分割的真实标签
from sklearn.mixture import GaussianMixture

# 导入层次聚类(备用算法):
# - 本项目未实际使用,仅作为扩展备选(适用于需要层级关系的图像分割场景)
from sklearn.cluster import AgglomerativeClustering

# 导入matplotlib绘图库:
# - 核心功能:可视化图像分割结果,直观展示聚类效果
# - 依赖pyplot子库实现图像绘制、显示等操作
import matplotlib.pyplot as plt

# 导入PIL的Image模块:
# - Python Imaging Library,专业的图像读取/处理工具
# - 支持常见图像格式(PNG/JPG等),兼容numpy数组转换
from PIL import Image

# 导入numpy库:
# - 数值计算核心库,实现图像数据的数组转换、维度变换、数学运算
# - GMM模型仅接受numpy数组作为输入,需通过numpy处理图像数据
import numpy as np

# 导入matplotlib核心配置模块:
# - 用于全局配置matplotlib参数(如字体、负号显示),解决中文渲染问题
import matplotlib as mpl  

# ====================== 2. 解决matplotlib中文显示问题(关键配置) ======================
# 设置全局字体为SimHei(Windows系统自带黑体):
# - 解决matplotlib默认字体不支持中文导致的"Glyph缺失"警告
# - 跨系统适配:Mac替换为'Arial Unicode MS',Linux替换为'WenQuanYi Micro Hei'
mpl.rcParams['font.sans-serif'] = ['SimHei']  

# 关闭坐标轴负号的Unicode编码异常:
# - 避免负号(如-1)显示为方块或乱码,保证图表元素完整
mpl.rcParams['axes.unicode_minus'] = False  

# ====================== 3. 图像读取与预处理(数据准备阶段) ======================
# 读取花卉图像文件:
# - 使用绝对路径避免相对路径错误,r前缀防止转义字符(如\)失效
# - Image.open()返回PIL图像对象,包含图像的尺寸、像素值等元信息
im = Image.open(r"")

# 动态获取图像尺寸(核心:替代硬编码,适配任意尺寸图像):
# - PIL的im.size返回元组(宽度, 高度),与numpy数组的(高度, 宽度, 3)维度对应
# - 打印尺寸用于调试,验证后续重塑操作的正确性
width, height = im.size
print(f"原始图像尺寸:宽度={width}, 高度={height}")

# 图像数据格式转换与展平:
# 1. np.array(im):将PIL图像转为三维numpy数组,形状为(高度, 宽度, 3)(3=RGB三通道)
# 2. reshape((-1, 3)):展平为二维数组,-1表示自动计算像素总数(高度×宽度)
#    最终形状为(像素总数, 3),每个行向量代表一个像素的RGB值,适配GMM的输入要求(样本数×特征数)
newdata = np.array(im).reshape((-1, 3))
print(f"展平后像素数据形状:{newdata.shape}")  # 打印验证:应为(高度×宽度, 3)

# ====================== 4. GMM模型构建与训练(核心算法阶段) ======================
# 初始化GMM模型(参数精细化配置):
# - n_components=4:聚类类别数,适配花卉图像的4个核心区域(花瓣/叶片/花萼/背景)
# - covariance_type="tied":协方差类型,所有聚类共享同一协方差矩阵
#   协方差类型选择依据:
#   - full:每个聚类独立协方差(精度高,计算复杂度高)
#   - diag:对角协方差(仅保留对角线元素)
#   - spherical:球形协方差(各维度方差相同,等价于K-Means)
#   - tied:共享协方差(计算快,适配颜色分布集中的花卉图像)
gmm = GaussianMixture(n_components=4, covariance_type="tied")

# 训练GMM模型:
# - fit(newdata):基于展平的RGB像素数据拟合模型
# - 内部执行EM算法:
#   E步:计算每个像素属于各聚类的后验概率(责任)
#   M步:更新聚类的均值、协方差、混合系数
# - 最终学习到4个颜色聚类的概率分布特征
gmm = gmm.fit(newdata)

# ====================== 5. 聚类预测与结果重塑(像素级分割阶段) ======================
# 预测每个像素的聚类标签:
# - predict(newdata):硬聚类预测,为每个像素分配概率最大的聚类标签(0-3的整数)
# - 替代方案(软聚类):predict_proba(newdata)返回每个像素属于4类的概率,可设置阈值筛选
cluster = gmm.predict(newdata)

# 重塑聚类结果为原始图像尺寸:
# - reshape(height, width):将一维标签数组(像素总数,)转为二维数组(高度, 宽度)
# - 维度对应关系:height=原始图像高度,width=原始图像宽度,保证可视化时与原图尺寸一致
cluster = cluster.reshape(height, width)
print(f"重塑后聚类结果形状:{cluster.shape}")  # 打印验证:应为(高度, 宽度)

# ====================== 6. 分割结果可视化(结果验证阶段) ======================
# 创建绘图窗口并设置尺寸:
# - figure(figsize=(8, 6)):设置窗口大小为8×6英寸,适配显示器显示比例
plt.figure(figsize=(8, 6))  

# 绘制聚类结果:
# - imshow(cluster):将二维标签数组渲染为图像,不同标签对应不同颜色
# - cmap='viridis':matplotlib内置配色方案,颜色区分度高,无中文依赖,避免渲染问题
plt.imshow(cluster, cmap='viridis')  

# 设置图表标题:
# - 中文标题可正常显示(已配置SimHei字体),清晰说明图表含义
plt.title("GMM图像分割结果(4类)")  

# 隐藏坐标轴:
# - axis('off'):移除x/y轴的刻度和边框,聚焦展示图像分割结果
plt.axis('off')  

# 自动调整布局:
# - tight_layout():自动调整子图间距,避免标题/图像边缘被裁剪
plt.tight_layout()  

# 显示绘图窗口:
# - show():弹出窗口展示分割结果,可直观查看花瓣、叶片、背景的划分效果
plt.show()

四、关键说明

  1. 模型参数可调性n_components可根据花卉类型调整(如复杂背景设为5类),covariance_type可改为full提升分割精度(代价是计算时间增加);
  2. 扩展方向:可结合predict_proba实现软分割(如保留概率>0.95的像素),或与边缘检测算法结合优化分割边界;
  3. 结果解读:可视化结果中不同颜色代表不同的图像区域,可通过统计各区域的像素占比,进一步分析花卉的结构特征。

运行结果
在这里插入图片描述

'''
原始图像尺寸:宽度=474, 高度=315
展平后像素数据形状:(149310, 3)
重塑后聚类结果形状:(315, 474)

进程已结束,退出代码为 0```
'''

简洁版

from sklearn.mixture import GaussianMixture
from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
import matplotlib as mpl

# 配置matplotlib中文显示
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

# 读取并预处理图像
im = Image.open(r"")
width, height = im.size
print(f"原始图像尺寸:宽度={width}, 高度={height}")

newdata = np.array(im).reshape((-1, 3))
print(f"展平后像素数据形状:{newdata.shape}")

# 构建并训练GMM模型
gmm = GaussianMixture(n_components=4, covariance_type="tied")
gmm.fit(newdata)

# 预测并重塑聚类结果
cluster = gmm.predict(newdata)
cluster = cluster.reshape(height, width)
print(f"重塑后聚类结果形状:{cluster.shape}")

# 可视化分割结果
plt.figure(figsize=(8, 6))
plt.imshow(cluster, cmap='viridis')
plt.title("GMM图像分割结果(4类)")
plt.axis('off')
plt.tight_layout()
plt.show()

更多推荐