当前位置:首页 > 技术 > 正文内容

基于分水岭算法的图像分割-Matlab版本

Lotus2022-12-19 10:19技术

✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。

????个人主页:算法工程师的学习日志

简介

分水岭算法是一种图像区域分割法,分割的过程中将图片转化为灰度图,然后将灰度值看作是海拔,然后向较低点注水,这种基于地形学的解释,我们着重考虑三种点:

基于分水岭算法的图像分割-Matlab版本_Io

1)极小值点,该点对应一个盆地的最低点,当我们在盆地里滴一滴水的时候,由于重力作用,水最终会汇聚到该点。注意:可能存在一个最小值面,该平面内的都是极小值点。

2)盆地的其它位置点,该位置滴的水滴会汇聚到局部最小点。

3)盆地的边缘点,是该盆地和其它盆地交接点,在该点滴一滴水,会等概率的流向任何一个盆地。

基于分水岭算法的图像分割-Matlab版本_Io_02

明白上述三种点之后,我们开始往盆地的极小值点注水,然后随着注水的深入,每一个极小值点慢慢的向外扩展,然后知道两个盆地的水汇合,汇合处就是我们需要的分水岭。


从下图可以直观理解一下,首先这三块区域都含有极小值点

基于分水岭算法的图像分割-Matlab版本_分水岭算法_03

然后逐渐填充就能获得分水岭(即分界线)

基于分水岭算法的图像分割-Matlab版本_彩色图像_04

得到分界线就能完成图像分割

代码实现

clear, close all;
clc;
%1.读取图像并求取图像的边界。

rgb = imread('1.png');%读取原图像
I = rgb2gray(rgb);%转化为灰度图像
figure; subplot(121)%显示灰度图像
imshow(I)
text(732,501,'Image courtesy of Corel','FontSize',7,'HorizontalAlignment','right')
hy = fspecial('sobel');%sobel算子,应用sobel算子锐化图像
hx = hy';
Iy = imfilter(double(I), hy, 'replicate');%滤波求y方向边缘
Ix = imfilter(double(I), hx, 'replicate');%滤波求x方向边缘
gradmag = sqrt(Ix.^2 + Iy.^2);%求摸
subplot(122); imshow(gradmag,[]), %显示梯度
title('Gradient magnitude (gradmag)')

%2. 直接使用梯度模值进行分水岭算法:(往往会存在过的分割的情况,效果不好)

L = watershed(gradmag);%直接应用分水岭算法
Lrgb = label2rgb(L);%转化为彩色图像
figure; imshow(Lrgb), %显示分割后的图像
title('Watershed transform of gradient magnitude (Lrgb)')%过分割现象

%3.分别对前景和背景进行标记:本例中使用形态学重建技术对前景对象进行标记,首先使用开操作,开操作之后可以去掉一些很小的目标。
%开和闭这两种运算可以除去比结构元素小的特定图像细节,同时保证不产生全局几何失真。
%开运算可以把比结构元素小的突刺滤掉,切断细长搭接而起到分离作用;
%闭运算可以把比结构元素小的缺口或孔填充上,搭接短的间断而起到连接作用。
se = strel('disk', 20);%圆形结构元素,STREL('disk',R,N),R is the specified radius, When N is greater than 0, the disk-shaped structuring
%element is approximated by a sequence of N
Io = imopen(I, se);%形态学开操作
figure; subplot(121)
imshow(Io), %显示执行开操作后的图像
title('Opening (Io)')
Ie = imerode(I, se);%对图像进行腐蚀,基本参数:待处理的输入图像以及结构元素对象
Iobr = imreconstruct(Ie, I);%形态学重建
subplot(122); imshow(Iobr), %显示重建后的图像
title('Opening-by-reconstruction (Iobr)')
Ioc = imclose(Io, se);%形态学关操作,首先膨胀,然后腐蚀,两个操作使用同样的结构元素
figure; subplot(121)
imshow(Ioc), %显示关操作后的图像
title('Opening-closing (Ioc)')
Iobrd = imdilate(Iobr, se);%对图像进行膨胀,基本参数:待处理的输入图像和结构元素对象。
Iobrcbr = imreconstruct(imcomplement(Iobrd), ...
imcomplement(Iobr));%形态学重建
Iobrcbr = imcomplement(Iobrcbr);%图像求反
subplot(122); imshow(Iobrcbr), %显示重建求反后的图像,figure4
title('Opening-closing by reconstruction (Iobrcbr)')
%As you can see by comparing Iobrcbr with Ioc,
%reconstruction-based opening and closing are more
%effective than standard opening and closing at removing
%small blemishes without affecting the overall
%shapes of the objects. Calculate the regional maxima
%of Iobrcbr to obtain good foreground markers.
fgm = imregionalmax(Iobrcbr);%局部极大值
figure; imshow(fgm), %显示重建后局部极大值图像,figure5
title('Regional maxima of opening-closing by reconstruction (fgm)')
I2 = I; %前景标记图与原图叠加
I2(fgm) = 255;%局部极大值处像素值设为255
figure; imshow(I2), %在原图上显示极大值区域,figure6
title('Regional maxima superimposed on original image (I2)')
se2 = strel(ones(5,5));%结构元素
fgm2 = imclose(fgm, se2);%关操作
fgm3 = imerode(fgm2, se2);%腐蚀
fgm4 = bwareaopen(fgm3, 20);%开操作
I3 = I;
I3(fgm4) = 255;%前景处设置为255
figure; subplot(121)
imshow(I3)%显示修改后的极大值区域,figure7
title('Modified regional maxima')
bw = im2bw(Iobrcbr, graythresh(Iobrcbr));%转化为二值图像
subplot(122); imshow(bw), %显示二值图像,figure7
title('Thresholded opening-closing by reconstruction')

%4. 进行分水岭变换并显示:


DL = watershed(Iobrcbr);%分水岭变换
figure
imshow(DL)
title('分水岭')
labels = imdilate(DL==0,ones(3,3));
I4 = labeloverlay(I,labels);
figure
imshow(I4)
title('分水岭边界线')


%%
% 将标签矩阵显示为彩色图像。标签矩阵
Lrgb = label2rgb(DL,'jet','w','shuffle');
figure
imshow(Lrgb)
title('分水岭Label')
%%
figure
imshow(I)
hold on
himage = imshow(Lrgb);
himage.AlphaData = 0.2; % 使用透明方式将此伪颜色标签矩阵叠加到原始强度图像上
title('彩色Label')

基于分水岭算法的图像分割-Matlab版本_彩色图像_05


原文链接

扫描二维码推送至手机访问。

版权声明:本文来源于网络,仅供学习,如侵权请联系站长删除。

本文链接:https://news.layui.org.cn/post/1154.html

分享给朋友:

“基于分水岭算法的图像分割-Matlab版本” 的相关文章

深入理解AQS--jdk层面管程实现【管程详解的补充】

什么是AQS   1.java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于AbstractQueuedSynchronizer(简称AQS)实现的,AQS是一个抽象同步框架,可以用来实现一个依赖状态的同步器。   2.JDK中提供的大多数的同步器如Lock, Latch, Barrier等,都...

Docker入门学习

1.运行第一个docker容器 docker run -i -t ubuntu /bin/bash 参数说明: -i, --interactive=false, 打开STDIN,用于控制台交互-t, --tty=false, 分配tty设备,该可以支持终端登录,默认为false-d, --detach=false, 指定容器运行于前台还是后台,默认为false 首先,docker run -it...

深入浅出DevOps:初识Pipline流水线任务

???? 作者: 俗世游子【谢先生】。 8年开发3年架构。专注于Java、云原生、大数据等领域技术。 ???? 成就: 从CRUD入行,负责过亿级流量架构的设计和落地,解决了千万级数据治理问题。 ???? 同名社区:​​51CTO​​​、 ​​github​​​、掘金​、​​gitee​​​。 ???? 清单: ​​​goku-framework​​​、​​【更新中】享阅读II​​ De...

分布式存储系统之Ceph集群存储池操作

  前文我们了解了ceph的存储池、PG、CRUSH、客户端IO的简要工作过程、Ceph客户端计算PG_ID的步骤的相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16733806.html;今天我们来聊一聊在ceph上操作存储池相关命令的用法和说明;   在ceph上操作存储池不外乎就是查看列出、创建、重命名和删除等操作,常用相关的工具都是“cep...

重新理解微服务之终究绕不过这4个坎?(观点探讨)

系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD .Net微服务实战之Kubernetes的搭建与使用 .Net微服务实战之负载均衡(下) .Net微服务实战之必须得面对的分布式问题 .Net微服务实战之可观测性 重新理解微服务之它还那么纯粹吗? 前言  ...

【大话云原生】煮饺子与docker、kubernetes之间的关系

文章开始之前,我给大家推荐一个人工智能学习网站,首先说我之前是完全不涉及人工智能领域的,但是我尽然看懂了,以后老哥我就要参与人工智能了。如果你也想学习,点击跳转到网站 云原生的概念最近非常火爆,企业落地云原生的愿望也越发强烈。看过很多关于云原生的文章,要么云山雾罩,要么曲高和寡。 所以笔者就有了写《大话云原生》系列文章的想法,期望用最通俗、简单的语言说明白云原生生态系统内的组成及应用关系。那么,...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。