MATLAB图像处理:图像分割方法

图像分割将图像划分为具有特定意义的子区域,是目标检测、医学影像分析、自动驾驶等领域的核心预处理步骤。本文讲解阈值分割、边缘检测、区域生长、聚类分割、基于图的方法等经典与前沿技术,提供MATLAB代码实现。

目录

[1. 图像分割基础](#1. 图像分割基础)

[2. 经典分割方法详解](#2. 经典分割方法详解)

[2.1 阈值分割](#2.1 阈值分割)

原理:

MATLAB实现:

[2.2 边缘检测分割](#2.2 边缘检测分割)

原理:

[2.3 区域生长与分裂合并](#2.3 区域生长与分裂合并)

算法步骤:

[4. 分割方法对比与选型指南](#4. 分割方法对比与选型指南)


1. 图像分割基础

  • 定义:根据像素的灰度、纹理、颜色或语义特征,将图像划分为互不重叠的区域。
  • 核心目标
    • 精确分离目标与背景
    • 保留目标的几何与语义完整性

2. 经典分割方法详解

2.1 阈值分割
原理
  • 通过设定灰度阈值划分前景与背景,适用于高对比度场景。
  • OTSU算法:自动计算最大类间方差的阈值。
MATLAB实现
复制代码
img = imread('coins.png');

% 手动阈值分割
thresh = 0.6;                 % 阈值设为0.6(归一化后)
binary_manual = imbinarize(img, thresh);

% OTSU自动阈值
thresh_otsu = graythresh(img); 
binary_otsu = imbinarize(img, thresh_otsu);

figure;
subplot(131), imshow(img), title('原图');
subplot(132), imshow(binary_manual), title('手动阈值');
subplot(133), imshow(binary_otsu), title('OTSU分割');
2.2 边缘检测分割
原理
  • 基于梯度、二阶导数或零交叉检测目标轮廓(如Canny、Sobel算法)。

    % Canny边缘检测
    edge_canny = edge(img, 'Canny', [0.1 0.25], 1.5);

    % 形态学后处理连接断裂边缘
    se = strel('disk', 2);
    closed_edge = imclose(edge_canny, se);
    filled_edge = imfill(closed_edge, 'holes');

    figure;
    subplot(131), imshow(edge_canny), title('Canny边缘');
    subplot(132), imshow(closed_edge), title('闭运算连接');
    subplot(133), imshow(filled_edge), title('填充孔洞');

2.3 区域生长与分裂合并
算法步骤
  1. 区域生长:从种子点出发,按相似性准则合并相邻像素。

  2. 分裂合并:递归地将图像分裂为子块,合并相似区块。

    % 初始化生长区域
    segmented = false(size(img));
    segmented(seed_point(1), seed_point(2)) = true;
    mean_val = img(seed_point(1), seed_point(2));

    % 迭代生长
    for iter = 1:1000
    neighbor_mask = imdilate(segmented, strel('disk',1)) & ~segmented;
    neighbors = find(neighbor_mask);
    if isempty(neighbors), break; end
    neighbor_vals = img(neighbors);
    valid = abs(neighbor_vals - mean_val) < threshold;
    segmented(neighbors(valid)) = true;
    mean_val = mean(img(segmented));
    end

    figure;
    imshowpair(img, segmented, 'blend'), title('区域生长结果');

3. 聚类与图论分割方法

3.1 K-means聚类分割

复制代码
clc;
clear;
close all;

% 读取图像
originalImage = imread('苹果.png'); % 使用MATLAB自带图像
figure; 
imshow(originalImage); 
title('原始图像');

%% 预处理
img = im2double(originalImage); % 转换为双精度并归一化
[rows, cols, channels] = size(img);

% 转换为像素特征向量(每个像素的RGB值作为特征)
pixelFeatures = reshape(img, rows*cols, channels); % 尺寸变为[M*N, 3]

%% K均值聚类
k = 2; % 设置聚类数量
[clusterIdx, centroids] = kmeans(pixelFeatures, k, ...
    'Distance', 'sqeuclidean', ...   % 平方欧氏距离
    'Replicates', 5, ...             % 重复聚类5次取最佳
    'MaxIter', 100);                % 最大迭代次数

%% 后处理与可视化
% 将聚类结果重塑回图像尺寸
labelMap = reshape(clusterIdx, rows, cols);

% 创建颜色标记的分割图像
segmentedImage = zeros(rows, cols, channels);
for i = 1:k
    % 为每个聚类区域赋予对应的中心颜色
    mask = labelMap == i;
    for ch = 1:channels
        colorLayer = img(:,:,ch);
        segmentedImage(:,:,ch) = segmentedImage(:,:,ch) + ...
                                 colorLayer .* mask;
    end
end

figure;
imshow(segmentedImage);
title('聚类颜色增强分割结果');

%% 显示每个聚类区域(二值显示)
figure;
for i = 1:k
    subplot(1,k,i);
    imshow(labelMap == i);
    title(['聚类区域 ', num2str(i)]);
end

%% 高级可视化:叠加边界到原图
boundaries = zeros(rows, cols);
for i = 1:k
    mask = labelMap == i;
    boundaries = boundaries + edge(mask, 'canny');
end

figure;
imshow(imoverlay(originalImage, boundaries, [1 0 0])); % 红色显示边界
title('带分割边界的原图');

3.2 图割(Graph Cut)

复制代码
rgb_img = imread('苹果.png');
lab_img = rgb2lab(rgb_img);  % 转为Lab色彩空间提升聚类效果
% 使用Image Processing Toolbox的graphcut函数
mask = false(size(rgb_img,1), size(rgb_img,2));
mask(50:end-50, 50:end-50) = true;  % 粗略定义前景区域

L = superpixels(rgb_img, 500);       % 生成超像素
BW = lazysnapping(rgb_img, L, mask, ~mask);  % 图割优化

figure;
imshowpair(rgb_img, BW, 'blend'), title('图割分割结果');

4. 分割方法对比与选型指南

方法 优点 缺点 适用场景
阈值分割 计算快、易于实现 依赖对比度,难以处理复杂纹理 文档扫描、简单目标提取
边缘检测 精准边界定位 易受噪声干扰,需后处理 工业零件尺寸测量
区域生长 适合均匀区域 依赖种子点选择,速度慢 医学肿瘤分割
K-means聚类 无需先验知识 色彩空间敏感,可能过分割 自然图像颜色分割
图割 全局优化,精度高 计算资源消耗大 交互式图像编辑
相关推荐
是娇娇公主~3 小时前
C++ 中 std::deque 的原理?它内部是如何实现的?
开发语言·c++·stl
SuperEugene3 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
xuxie994 小时前
N11 ARM-irq
java·开发语言
wefly20175 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
luanma1509805 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默5 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
kyriewen116 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
娇娇yyyyyy6 小时前
QT编程(18): Qt QItemSelectionModel介绍
开发语言·qt
豆豆的java之旅7 小时前
软考中级软件设计师 数据结构详细知识点(含真题+练习题,可直接复习)
java·开发语言·数据结构
sthnyph7 小时前
QT开发:事件循环与处理机制的概念和流程概括性总结
开发语言·qt