《数字图像处理与机器视觉》案例四 基于分水岭算法的粘连物体的分割与计数

一、引言

      分水岭算法(Watershed Algorithm),是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分水岭。 分水岭算法可以应用于分割粘连对象和对象计数。在该算法中,空间上相邻并且灰度值相近的像素被划分为一个区域。一般来讲,直接应用分水岭分割算法的效果往往并不好,如果在图像中对前景对象和背景对象进行标注区别,再应用分水岭算法会取得较好的分割效果。下面以具有粘连大米的分割计数为例,开发了基于MATLAB的分水岭算法大米颗粒的分割计数,算法主要步骤如下图所示。

二、程序代码

clear all;
close all;
clc;
%%步骤1 读图并进行背景处理
I0=imread('.\rice2.jpg');
I_r=I0(:,:,1);  % 提取R通道图像
I_g=I0(:,:,2);
I_b=I0(:,:,3);
I_rb=I_r-I_b;
figure,imhist(I_rb);%具有明显的双峰特性
I_bw=1-im2bw(I_rb,45/255);             %使用指定阈值分割
%I_bw=1-im2bw(I_rb,graythresh(I_rb));   %使用OTSU方法进行阈值分割并反色
%I_bw=1-imbinarize(I_rb,'adaptive');
figure,imshow(I_bw);
Obj1_r=uint8(I_bw).*I_r;
Obj1_g=uint8(I_bw).*I_g;
Obj1_b=uint8(I_bw).*I_b;
rgb=cat(3,Obj1_r,Obj1_g,Obj1_b);
figure,imshow(rgb);
%%步骤2 利用梯度实现灰度图像的分割
I = rgb2gray(rgb);
hy = fspecial('sobel');hx = hy';    %使用sobel算子进行边缘检测
Iy = imfilter(double(I), hy, 'replicate');
Ix = imfilter(double(I), hx, 'replicate');
gradmag = sqrt(Ix.^2 + Iy.^2);     %求模
%%步骤3 标记前景对象
se = strel('diamond',3);                  %构建结构元素
Io = imopen(I, se);                         %形态学开操作    
Ie = imerode(I, se);                        %腐蚀                       
Iobr = imreconstruct(Ie, I);             %重建
Ioc = imclose(Io, se);                     %形态学闭操作
Iobrd = imdilate(Iobr, se);               %膨胀
Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));
Iobrcbr = imcomplement(Iobrcbr);  %求反
%%步骤4 获取局部最大值
fgm = imregionalmax(Iobrcbr);          %获得局部最大值
It1 = rgb(:, :, 1); It2 = rgb(:, :, 2);
It3 = rgb(:, :, 3);
It1(fgm) = 255; It2(fgm) = 0; It3(fgm) = 0;
I2 = cat(3, It1, It2, It3);
%%步骤5
se2 = strel(ones(3,3));             
fgm2 = imclose(fgm, se2);                    %闭操作
fgm3 = imerode(fgm2, se2);                 %腐蚀
fgm4 = bwareaopen(fgm3, 20);            %删除
It1 = rgb(:, :, 1);
It2 = rgb(:, :, 2);
It3 = rgb(:, :, 3);
It1(fgm4) = 255;                                     %前景设置为255
It2(fgm4) = 0;
It3(fgm4) = 0;
I3 = cat(3, It1, It2, It3);
%%步骤6 标记背景
bw = im2bw(Iobrcbr, graythresh(Iobrcbr));          %二值转换
D = bwdist(bw);                                                   %计算距离
DL = watershed(D);                                             %分水岭变换
bgm = DL == 0;                         
gradmag2 = imimposemin(gradmag, bgm | fgm4);     %置最小值
L = watershed(gradmag2);
It1 = rgb(:, :, 1);
It2 = rgb(:, :, 2);
It3 = rgb(:, :, 3);
fgm5 = imdilate(L == 0, ones(9, 2)) | bgm | fgm4;   %前景及边界处置255
It1(fgm5) = 255; It2(fgm5) = 0; It3(fgm5) = 0;
I4 = cat(3, It1, It2, It3);
figure,imshow(I4);
%%步骤7 去粘连、填孔、分割
figure('units', 'normalized', 'position', [0 0 1 1]);
P=rgb2gray(I4);                                 % 彩色图像转灰度
figure,imshow(P);
figure,imhist(P);              %具有明显的双峰特性
P1=im2bw(P,200/255);                      % 灰度图像二值化
SE1=strel('square',3);
P2=imopen(P1,SE1);                        % 以SE为单位对P1进行开运算
SE2=strel('square',2);                       % 构造半径为2圆形元素
P3=imerode(P2,SE2);             % 形态学腐蚀运算,部分目標物有粘连现象,去除粘连
P4 = imfill(P3,'hole');
SE3=strel('square',2);
P5=imopen(P4,SE3);                        % 以SE3作开运算
SE4=strel('disk',3);
%SE4=strel('disk',5);
P6=imerode(P5,SE4);                       %形态学腐蚀运算,进一步去除粘连
P7 = bwareaopen (P6, 100);
figure,imshow(P7);
%%步骤8 计算连通数,输出结果
[L,N]=bwlabel(P7,8);            % 计算连通数,N即为目标个数
figure,imshow(I0);
hold on
for k=1:N
[r,c] = find(L == k);
rbar = mean(r);
cbar = mean(c);
plot(cbar,rbar,'marker','+','markeredgecolor','b','markersize',6); % 对话框显示目标物个数,通过坐标定点,标记点为“+”
end    
title(['大米总数为',num2str(N)],'Fontsize',14)
figure,
subplot(1,3,1),imshow(I0),title('存在粘连的大米彩色图像');
subplot(1,3,2),imshow(I4),title('分水岭算法分割图像');
subplot(1,3,3),imshow(P7),title('数学形态学运算后的图像');

三、程序运行结果

四、原始图像

五、讨论

        由运行结果可知,使用分水岭算法可以对存在粘连大米图像取得较好的分割效果和计数,对其它粘连物体的分割和计数也具有一定参考价值。但也发现有存在粘连严重的两个大米被误算为1个。

        如果觉得本案例对大家今后的编程有帮助,还请点赞、收藏。如有改进意见可以与我联系,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/40165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot 集成Swagger在线接口文档 接口注解

介绍 Swagger接口文档是一种自动生成、描述、调用和可视化的RESTful风格Web服务接口文档的工具。它通过一系列的规范和自动化工具&#xff0c;极大地简化了后端开发人员与前端开发人员之间的协作。 依赖 <!--swagger--> <dependency><groupId>io.springfo…

「媒体邀约」天津媒体资源?媒体邀约宣传报道

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 天津拥有丰富的媒体资源&#xff0c;利用这些资源进行有效…

ICMP协议详解及尝试用ping和tracert捕抓ICMP报文

一、ICMP协议 1.1、定义 ICMP&#xff08;Internet Control Message Protocol&#xff0c;互联网控制消息协议&#xff09;是一个支持IP层数据完整性的协议&#xff0c;主要用于在IP主机、路由器之间传递控制消息。这些控制消息用于报告IP数据报在传输过程中的错误&#xff0c…

C++ 语法

一、头文件与源文件 头文件用于声明函数,类似于java中service层的接口; 源文件用于实现头文件函数,相当于java中serviceImpl层的实现类; 定义接口 实现接口 使用接口 二、指针概述 定义与使用 定义一个指针p用于存a变量的内存地址,即指针就是地址; 解引用可以获取或修改…

40岁以上的中年人很难找到工作

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 你们有没有发现&#xff0c;90%的40岁以上的中年人&#xff0c;为了多挣钱&#xff0c;几乎除了吃饭和睡觉之外&#xff0c;都在拼命加班劳作&#xff0c;只要一停下来&#xff0c;心里就有一种内疚感&#xff0c;…

【Elasticsearch】Elasticsearch动态映射与静态映射详解

文章目录 &#x1f4d1;前言一、Elasticsearch 映射概述1.1 什么是映射&#xff1f;1.2 映射的分类 二、动态映射2.1 动态映射的定义2.2 动态映射的优点2.3 动态映射的缺点2.4 动态映射的应用场景2.5 动态映射的配置示例 三、静态映射3.1 静态映射的定义3.2 静态映射的优点3.3 …

机器学习简介--NLP(二)

机器学习简介 机器学习简介机器学习例子机器学习分类有监督学习有监督学习的应用 无监督学习 机器学习常见概念数据集k折交叉验证过拟合欠拟合评价指标 机器学习简介 机器学习例子 问题&#xff1a; 2&#xff0c;4&#xff0c;6&#xff0c;8&#xff0c;&#xff1f;&#…

【CV炼丹师勇闯力扣训练营 Day22:§7 回溯1】

CV炼丹师勇闯力扣训练营 代码随想录算法训练营第22天 回溯法其实就是暴力查找,回溯的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案&#xff0c;一般可以解决如下几种问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割…

Ubuntu18.04新安装--无网络连接、重启黑屏解决教程

一、安装Ubuntu Ubuntu安装需要U盘作为启动盘&#xff0c;在目前教新的电脑中选中GPT作为分区&#xff0c;制作启动盘&#xff0c;其中在安装双系统Ubuntu时&#xff0c;以自定义格式作为存储空间。详细安装过程以以及如何分区请参考下列链接&#xff1a;内含详细安装过程&…

VS Code 常用快捷键大全

Visual Studio Code 是目前最好用的代码编辑器之一。它提供了许多开箱即用的功能以及丰富的第三方扩展&#xff0c;本文将分享常用的 VS Code 快捷键&#xff0c;助你提高开发效率&#xff01; 代码导航 跳转指定行&#xff1a;快速跳转到文件中的指定行&#xff0c;只需按下快…

Unity 数据持久化【PlayerPrefs】

1、数据持久化 文章目录 1、数据持久化PlayerPrefs基本方法1、PlayerPrefs概念2、存储相关3、读取相关4、删除数据思考 信息的存储和读取 PlayerPrefs存储位置1、PlayerPrefs存储的数据在哪个位置2、PlayerPrefs 数据唯一性思考 排行榜功能 2、Playerprefs实践1、必备知识点-反…

解决 Layout Inspector无法查看Component Tree 布局层级信息 | Android Studio Koala

问题描述 Tool -> Layout Inspector 显示下图&#xff0c;无法生成.li文件查看Component Tree&#xff0c;变成实时的Preview并功能点击操作&#xff0c;跟模拟器一样。 原因&#xff1a;默认勾选了"Enable embedded Layout Inspector"&#xff0c;启用了嵌入式…

SpringCloud进阶篇

文章目录 网关快速入门创建模块引入依赖修改启动类配置路由路由过滤(一般不用) 自定义GlobalFilter登录校验登录校验过滤器 微服务获取用户信息保存用户信息到请求头拦截器获取用户信息 OpenFeign传递用户信息配置共享添加共享配置拉取共享配置 配置热更新添加配置到Nacos配置热…

数据结构初阶 堆的问题详解(三)

题目一 4.一棵完全二叉树的节点数位为531个&#xff0c;那么这棵树的高度为&#xff08; &#xff09; A 11 B 10 C 8 D 12 我们有最大的节点如下 假设最大高度为10 那么它的最多节点应该是有1023 假设最大高度为9 那么它的最多节点应该是 511 所以说这一题选B 题目二 …

指挥中心操作台的形状及空间布局

在现代化的指挥中心&#xff0c;操作台的形状设计至关重要&#xff0c;它不仅影响着操作人员的工作效率和舒适度&#xff0c;还关系到整个指挥系统的运行效果。常见的指挥中心操作台形状多种多样&#xff0c;以满足不同的功能需求和空间布局。 直线型操作台 直线型操作台是最为…

C语言 | Leetcode C语言题解之第212题单词搜索II

题目&#xff1a; 题解&#xff1a; class Solution { public:struct Node{int id;Node* son[26];Node(){id -1;for(int i 0; i < 26; i) son[i] NULL;}}* root;vector<vector<char>> g;unordered_set<int> ids;vector<string> res;int dx[4] …

Windows编程原理-消息驱动的机制

Windows为每一个输入事件产生一个输入消息&#xff0c;如&#xff1a; 移动鼠标按键…… 从程序角度看待Windows消息处理 Windows使用一个窗口前必须&#xff1a; 填充一个结构&#xff1a;WNDCLASS注册窗口创建窗口使用窗口撤销窗口 从这个机制看&#xff0c;windows操作系统…

console 报错 之 Uncaught (in promise) RangeError: Maximum call stack size exceeded

1. 背景 demo 环境报错。。。 2. 报错问题 3. 问题原因 vue 报错: “RangeError: Maximum call stack size exceeded” 报错通常是由于无限的递归 导致的。当使用 Vue 路由时&#xff0c;如果设置不当&#xff0c;会导致无限的递归&#xff0c;最终导致栈溢出&#xff0c;即…

yolov8 目标检测快速streamlit可视化界面

参考&#xff1a; https://github.com/ultralytics/ultralytics/blob/2330caa50a8a8e0bb61408df8dca0721fb350dbe/ultralytics/solutions/streamlit_inference.py 版本&#xff1a; ultralytics 8.2.27 # Ultralytics YOLO &#x1f680;, AGPL-3.0 licen…

网络安全--计算机网络安全概述

文章目录 网络信息系统安全的目标网络安全的分支举例P2DR模型信息安全模型访问控制的分类多级安全模型 网络信息系统安全的目标 保密性 保证用户信息的保密性&#xff0c;对于非公开的信息&#xff0c;用户无法访问并且无法进行非授权访问&#xff0c;举例子就是&#xff1a;防…