前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分水岭变换图像分割接触对象

分水岭变换图像分割接触对象

作者头像
万木逢春
发布2019-06-17 18:27:13
9730
发布2019-06-17 18:27:13
举报
文章被收录于专栏:帮你学MatLab帮你学MatLab

分水岭变换

% 使用分水岭变换分割来分离接触对象

% 分水岭变换分割将图像中的“分水岭流域”和“分水岭脊线”

% 视为一个亮像素高、暗像素低的曲面

% 如果可以识别或“标记”前景对象和背景位置、效果更好

% 分水岭变换分割遵循以下基本程序:

%% 步骤1: 读取图片、转为灰度图

rgb = imread('pears.png');

I = rgb2gray(rgb);

imshow(I)

%% 步骤2: 使用梯度幅度作为分割函数

% 计算梯度大小。梯度在对象边界处较高,而在对象内部较低(大部分情况下)。

gmag = imgradient(I);

imshow(gmag,[])

title('梯度幅度')

% 不能用分水岭变换直接在梯度幅度上分割图像

L = watershed(gmag);

Lrgb = label2rgb(L);

imshow(Lrgb)

title('直接在梯度幅度上分割图像')

% 如果不进行预处理,例如下面的标记计算

% 直接使用分水岭变换通常会导致“过度分割”

%% 步骤3: 标记前景对象

% 可以应用各种程序来查找前景标记

% 只要这些标记能连接每个前景对象内的像素块

% 此处使用形态学开操作和闭操作来“清理”图像

% 在每个对象内创建平面最大值

% 首先使用imopen

se = strel('disk',20);

Io = imopen(I,se);

imshow(Io)

title('开操作')

% 然后利用IMERODE腐蚀、imreconstruct重建

Ie = imerode(I,se);

Iobr = imreconstruct(Ie,I);

imshow(Iobr)

title('腐蚀&重建')

% 闭操作可以去除暗点

Ioc = imclose(Io,se);

imshow(Ioc)

title('闭操作')

% 利用IMERODE膨胀、imreconstruct重建

Iobrd = imdilate(Iobr,se);

Iobrcbr = imreconstruct(imcomplement(Iobrd),imcomplement(Iobr));

Iobrcbr = imcomplement(Iobrcbr);

imshow(Iobrcbr)

title('开闭重建')

% 从IOBRCBR与IOC的比较中可以看出

montage({Iobrcbr,Ioc}, 'Size', [2 1]);

% 基于重建的开操作和关闭比标准的开操作和闭操作更有效

% 可以在不影响对象整体形状的情况下消除小瑕疵

% 计算出IOBRCBR的区域最大值

% 得到良好的前景标记

fgm = imregionalmax(Iobrcbr);

imshow(fgm)

title('区域最大值')

% 将前景标记图像叠加到原始图像上、效果明显

I2 = labeloverlay(I,fgm);

imshow(I2)

title('前景标记图像叠加')

% 一些被遮挡和阴影下的对象没有被标记

% 这些对象在最终结果中不会被正确分割

% 一些对象中的前景标记靠近对象的边缘

% 可以清理标记块的边缘,将其缩小一点

% 先关操作然后腐蚀

se2 = strel(ones(5,5));

fgm2 = imclose(fgm,se2);

fgm3 = imerode(fgm2,se2);

% 会留下一些必须删除的杂散孤立像素

% 可以使用bwAreaOpen来删除二进制图像中像素小于p的所有连接组件

fgm4 = bwareaopen(fgm3,20);

I3 = labeloverlay(I,fgm4);

imshow(I3)

title('原始图像上叠加修正过的区域最大值')

%% 步骤4: 标记背景

% 在清理后的图像中,黑色像素属于背景

% 可以从阈值操作开始

bw = imbinarize(Iobrcbr);

imshow(bw)

title('阈值操作')

% 理想情况下,我们不希望背景标记太靠近我们要分割的对象的边缘

% 通过计算前景的“阴影骨架”来“细化”背景(欧氏距离变换bwdist)

% 可以通过计算距离变换的分水岭变换、然后寻找结果的分水岭线来实现

D = bwdist(bw);

DL = watershed(D);

bgm = DL == 0;

imshow(bgm)

title('分水岭线')

%% 步骤5: 计算分割函数的分水岭变换

% 使用imimposemin修改渐变幅度图像

% 使其唯一的区域最小值出现在前景和背景标记像素上

gmag2 = imimposemin(gmag, bgm | fgm4);

% 最后,我们准备好计算基于分水岭的分割

L = watershed(gmag2);

%% 步骤6: 结果可视化

% 一种可视化技术是在原始图像上叠加前景标记、背景标记和分割的对象边界

% 对象边界位于l==0的位置

% 二进制前景和背景标记被缩放为不同的整数值,以便它们被分配不同的标签

labels = imdilate(L==0,ones(3,3)) + 2*bgm + 3*fgm4;

I4 = labeloverlay(I,labels);

imshow(I4)

title('分割结果可视化')

% 另一种有用的可视化技术是将标签矩阵显示为彩色图像

% 可以使用label2rgb转换为TrueColor图像进行可视化

Lrgb = label2rgb(L,'jet','w','shuffle');

imshow(Lrgb)

title('TrueColor分割结果可视化')

% 可以使用透明度将此伪彩色标签矩阵叠加到原始强度图像的上层

figure

imshow(I)

hold on

himage = imshow(Lrgb);

himage.AlphaData = 0.3;

title('伪彩色标签矩阵叠加')

相关文件为matlab自带

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 帮你学MatLab 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档