【图像分割】用于图像分割的原始详细分水岭算法(Matlab实现)

  💥💥💞💞欢迎来到本博客❤️❤️💥💥

🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。

⛳️座右铭:行百里者,半于九十。

📋📋📋本文目录如下:🎁🎁🎁

目录

💥1 概述

📚2 运行结果

🎉3 参考文献

🌈4 Matlab代码实现

💥1 概述

详细分水岭算法(Detailed Watershed Algorithm)是一种用于图像分割的经典算法,主要用于分割具有不同密度或灰度级别的图像中的对象。首先,将输入图像转换为灰度图像,以便在单一通道上执行分割操作。通过计算图像的梯度,确定图像中的边缘和区域边界。通常使用梯度算子(如Sobel、Prewitt等)来计算图像的梯度。基于图像梯度,生成一组初始标记(markers)。这些标记通常表示可能的对象或区域的种子点。可以使用阈值、梯度幅值或手动选择标记来初始化。基于洪泛填充结果,应用分水岭变换算法来处理图像中的局部最小值,并将其视为分割中的标记。这样做可以确保生成具有连通性和稳定性的分割结果。根据需要,对分割结果进行后处理操作,如去除小区域、合并相邻区域等,以获得最终的分割结果。详细分水岭算法在图像分割领域具有广泛的应用,特别是在处理具有复杂结构和不均匀亮度分布的图像时表现出色。然而,该算法也存在一些挑战,如过度分割和对初始标记的敏感性,需要结合其他技术进行改进和优化。

📚2 运行结果

主函数部分代码:

clear all;
close all;
% ori = imread('x1.jpg');
ori = imread('x2.jpg');
% ori = imread('x3.jpg');
% ori = imread('pollen.tif');
% ori = imread('ly_tmp.jpg');
ori = im2uint8(ori);
a = ori;
figure,imshow(a,[]);

[M, N] = size(a);
se = ones(3);

lowestBasin = min(a(:));
higestPeak = max(a(:));
index = find(a == lowestBasin);         % 找出 a 的最低海拔
b = false(size(a));                     
b(index) = 1;                           % 一开始的连通域


figure(1),dis_start = show_process0(a,b);          % 显示刚有水洼时的景象

con = max(max(bwlabel(b)));             % 找出出现水洼时的连通域的个数

a(index) = lowestBasin + 1;     

dam = false(size(a));
dam = im2uint8(dam);                    % 水坝

c = b;

% 下面开始涨水
for i = lowestBasin + 1 : 254
    b = false(size(a));
    index = find(a == i);
    b(index) = 1;  
    
    if(max(max(bwlabel(b))) >= con) 
        con = max(max(bwlabel(b)));         % 如果连通域增加或不变,则更新连通域的个数
        c = b;
    elseif(max(max(bwlabel(b))) < con)      % 如果连通域减少,则一定有水洼合并了,通过 c 返回上一步
        d = c;                          
        while(1)
            e = d;                          % e是上一步的d    
            d = imdilate(d,se);             % 不断膨胀d
            if(max(max(bwlabel(d))) < con)  % 直到其连通域减少
                break;
            end
        end
        g = bwlabel(e);                     % 回到上一步,求 e 的各个连通域
        
        max(max(g))
        
        tmp = zeros(size(a));           
        tmp = im2double(tmp);
        for m = 1:con                    % 对任何一个连通域
            h = false(size(a));
            ind1 = find(g==m);                  
            h(ind1) = 1;               % 把其单独孤立开来
            tmp =  tmp + imdilate(h,se) - h;            % 提取其边界,加到tmp上
        end
        ind = find(tmp > 1);            % 有多个边界相交的情况,把交集提取出来,是要修水坝的地方
        a(ind) = 255;                   
        dam(ind) = 255;    
        
        p = false(size(a));
        del = find(a == i);
        p(del) = 1;
        c = p;                          % 连通域减少的情况,c 与修过水坝的 a 相关联,得到二值图
        
        
    end
    
    figure(1),dis_process = show_process1(ori,c,dam); 
  
    % figure(3)对应于figure(1)展示其3D效果,其中函数figure_rgb与show_process1基本相同
    figure3_rgb = figure_rgb(ori,c,dam);
    figure3_gray = rgb2gray(figure3_rgb);
    cmap = colormap;
    xxcolormap = double(rgb2ind(figure3_rgb,cmap));
    figure3_gray = double(figure3_gray);
    figure(3), mesh(figure3_gray,xxcolormap); 
    % figure(3)对应于figure(1)展示其3D效果,其中函数figure_rgb与show_process1基本相同
    
    figure(2), imshow(process2(a,dam,i));       % 展示最终结果
    

🎉3 参考文献

文章中一些内容引自网络,会注明出处或引用为参考文献,难免有未尽之处,如有不妥,请随时联系删除。

[1]邹耀斌,张彬.四向加权香农熵最大化导向的自动阈值分割方法[J/OL].计算机应用:1-11[2024-05-13].http://kns.cnki.net/kcms/detail/51.1307.tp.20240507.1416.004.html.

[2]朱正云,许平,陆迎东,等.基于机器视觉的镍板表面气孔分割算法研究[J].传感器与微系统,2024,43(05):19-22.DOI:10.13873/J.1000-9787(2024)05-0019-04.

🌈4 Matlab代码实现

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值