分水岭算法 matlab实现

分水岭算法 matlab实现背景     做图像分割的时候用到了,就学习了一下大概思想     把图像中的像素大小理解成山地的海拔,向山地灌水,海拔低的地方会积水,这些地方称之为谷底。随着水位上升,不同谷底的水会相遇,相遇的地方就是分水岭。    &nbs

大家好,又见面了,我是你们的朋友全栈君。

背景

          做图像分割的时候用到了,就学习了一下

大概思想

          把图像中的像素大小理解成山地的海拔,向山地灌水,海拔低的地方会积水,这些地方称之为谷底。随着水位上升,不同谷底的水会相遇,相遇的地方就是分水岭。

          总体上是按照给每个点贴标签的方法实现的对每个在谷底的点贴上从1开始的不同的标签,同一个谷底标签相同。给分水岭贴上0的标签。未贴标签的点标为-1,其实就是初始化的时候全部-1。

  • 1、将图像中的每个像素按像素值大小排好顺序。
  • 2、从较小的像素值开始进行处理。
  • 3、搜索统计当前点周围像素(8邻域,边界的话就少几个像素点)中标签的种类,
  •           a、如果只有一种标签,为该点贴上相同的标签;
  •           b、 如果有2种及以上的标签,认为该点为分水岭。
  •           c、如果没有标签(-1没处理过)或只存在0(分水岭),搜索当前点的连通区域,,这儿可能会出现两种情况
  •                 (1)、当前点的连通域和之前处理过的接通了,如果是这样的话呢,把当前点的连通区域标记为和他连通的区域中较小的编号
  •                 (2)、当前点的连通域没有连通,那么当前点就把认为该点为新的谷底,谷底数加一,并把当前点的连通域都标记为新的谷底编号

流程框图

在这里插入图片描述

在这里插入图片描述

代码

          data 是一个图片的灰度值矩阵

clear all 
clc

load data
picture = data;
[row,col] = size(picture);   % 获得图片尺寸
watershed_result = -ones(row,col);  % 将结果矩阵全部赋值为-1表示所有点都未处理过

valley_number = 0; % 谷底数为0
tic
[picture_value, picture_index] = sort(picture(:)); % 将图片中所有元素按像素值大小排序
toc
total_pixel_number = row*col;  % 总元素个数

tic
for now_index = 1:total_pixel_number   % 对每个像素都要处理

    if watershed_result(picture_index(now_index)) ~= -1  % 如果标记为处理过跳过该像素
        continue;
    end
    
    now_picture_index = picture_index(now_index);     % 正在处理的像素的位置
    now_picture_value = picture(now_picture_index);   % 正在处理的像素的像素值

    vector_now_pixel_neighbor = neighbor_find_C(row,col,now_picture_index); % 获取当前像素点的周围8个像素点的位置

    temp_vector = sort(watershed_result(vector_now_pixel_neighbor));%获取周围像素点的标签
    temp_vector = unique(temp_vector);
    temp_vector = temp_vector(temp_vector>0);  %除了-10的标签种类
    temp_vector_length = length(temp_vector); 
    if temp_vector_length == 0  %种类为0
        is_same_area_index = zeros(2*col+2*row,1,'double');%和处理点像素值相同的连通区域
        is_same_area_index(1) = now_picture_index;
        area_num = 1;%连通区域的像素个数
        while(1)   %获得和处理点像素值相同的连通区域
            %获取联通区域的周围像素点的位置          
            is_same_area_neighbor_index = area_neighbor_find_C(row,col,is_same_area_index(1:area_num));
            
            %获取联通区域的周围像素点像素值大小和当前点像素值大小相同的点的像素值
            temp_vector = is_same_area_neighbor_index(picture(is_same_area_neighbor_index) == now_picture_value);
            temp_vector_length = length(temp_vector);
            if temp_vector_length == 0
                break;
            end
            is_same_area_index(area_num+1:area_num+temp_vector_length) = temp_vector;
            area_num = area_num + temp_vector_length;
            is_same_area_index = is_same_area_index(is_same_area_index>0);
        end

        temp_vector = sort(watershed_result(is_same_area_neighbor_index));%获取连通区域周围像素点的标签
        temp_vector = unique(temp_vector);
        temp_vector = temp_vector(temp_vector>0);
        temp_vector_length = length(temp_vector);%除了-10的标签种类
        if temp_vector_length == 0%种类为0
            valley_number = valley_number+1;%谷底数加1
            watershed_result(is_same_area_index(is_same_area_index>0)) = valley_number;%认为该连通区域为一个新的谷底
        else 
            watershed_result(now_picture_index) = temp_vector(1);%否则该点贴与之相邻的标签中除-10外较小的标签
        end
    else if temp_vector_length == 1      % 相邻8个像素中标签种类除-10还有1watershed_result(now_picture_index) = temp_vector(1);               % 该像素点贴相同标签
        else                             % 相邻8个像素中标签种类除-101个以上
            watershed_result(now_picture_index) = 0;                            % 认为该点为分水岭
        end
    end
end
toc
figure,imshow(watershed_result);%输出分水岭

用到的两个函数

          neighbor_find_C.m

function vector_neighbor_C = neighbor_find_C(row,col,nn)
total_number=row*col;
now_col= floor(nn/row)+1;
temp=rem(nn,row);
if temp==0
    now_row=row;
else
    now_row=temp;
end
if nn==1
    vector_neighbor_C=[2;row+1;row+2];
else if nn==row
    vector_neighbor_C=[row;row+row;row+row-1];
    else if nn==total_number-row+1
            vector_neighbor_C=[total_number-row+2;total_number-row-row;total_number-row-row+1];
        else if nn==total_number
                vector_neighbor_C=[total_number-1;total_number-row;total_number-row-1];
            else if now_row==1
                    vector_neighbor_C=[nn+row;nn-row;nn+1;nn+row+1;nn-row+1];
                else if now_row==row
                        vector_neighbor_C=[nn+row;nn-row;nn-1;nn+row-1;nn-row-1];
                    else if now_col==1
                            vector_neighbor_C=[nn+1;nn-1;nn+row;nn+row+1;nn+row-1];
                        else if now_col==col
                                vector_neighbor_C=[nn+1;nn-1;nn-row;nn-row+1;nn-row-1];
                            else
                                vector_neighbor_C=[nn+1;nn-1;nn-row;nn+row;nn-row+1;nn-row-1;nn+row+1;nn+row-1];
                            end
                        end
                    end
                end
            end
        end
    end
end

          area_neighbor_find_C.m

function vector_neighbor = area_neighbor_find_C(row,col,area_index)
I = zeros(row,col);
se=ones(3);
I(area_index) = 1;
I2 = imfilter(I,se);  % 滤波
I2=I2-I.*9;
vector_neighbor = find(I2>0);
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149690.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 第一个C# Winform实例

    第一个C# Winform实例前面我们准备好了相关的库,现在开始搭建环境,本人自动化行业,就用Windorm开发吧,例子仅仅做引导,希望大家能深入。VS版本VS20171:打开VS建立一个WInform项目。拉入两个控件,gr

    2022年7月2日
    27
  • 400报错有关[通俗易懂]

    400报错有关[通俗易懂]400报错是数据类型对不上,畸形,以下是经常报400的地方1.时间封装类中没有加时间注解或者使用时分秒是在新增页面使用f标签去吊.0使用<f:>2.外键name值中只加属性没加属性的属性id(注:这个是属性是外键所以需要对象.对象id)3.封装类Date包导成sql了…

    2022年5月20日
    29
  • 0x80表示什么_0x38是多少

    0x80表示什么_0x38是多少0x800x是C语言中16进制数的表示方法。0x80等于十进制的1280×80在计算机内部表示为10000000字符在计算机中以其ASCII码方式表示, 其长度为1个字节,有符号字符型数取值范围为-128~127,无符号字符型数到值范围是0~255。因此在TurboC语言中,字符型数据在操作时将按整型数处理,如果某个变量定义成char,则表明该变量是

    2022年9月13日
    0
  • numpy的astype函数

    numpy的astype函数astype函数用于array中数值类型转换

    2022年5月27日
    92
  • 长春python编程培训学校

    长春python编程培训学校近年来,教育部频频下发相关政策,强调编程教育的重要性,探究编程教育发展的新方式。从政策出台的趋势看,编程教育列入基础教育的趋势越来越大。在今年(2020年),教育部及各个省市又都下发了什么政策我们正好借着这个机会来盘点一下2020年各地编程教育政策汇总2020年2月教育部教育部公布了《2019年度普通高等学校本科专业备案和审批结果》,确定通过人工智能专业审批的高校达到180所。2020年4月四川四川省教育厅发布《关于加强初中学业水平考试命…

    2022年5月16日
    41
  • cmd跑绿色代码_cmd装逼代码-cmd命令,装逼

    cmd跑绿色代码_cmd装逼代码-cmd命令,装逼本教程分享:《cmd装逼代码》如何使用命令提示符装逼事先声明,如果你不知道打开windows的命令行工具,我是绝对不会告诉你是用windows+R,然后键入cmd打开的windows自带的命令行工具很强大,毕竟计算机一开始都是以键入命令的方式来操作的,但现如今计算机的发展,许多在过去需要去记大量命令才能完成的操作,现如今通过傻瓜式的点选都可以完成。作为一名有逼格的程序员,在计算机如今图形界面…

    2022年6月5日
    54

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号