图像处理学习笔记2.0

matlab写的floodfill进阶

首先介绍一下floodfill

百度百科

英文版解释请自行搜索。

再来说一下我是怎么想到学这个的,我是要做图像分割的,做完图像分割将图像进行二值化的时候出现了问题:有噪点,非常严重的噪点,像这样:

于是我想要将那些零碎的噪点去掉,最开始想用中值滤波的,但是由于某种原因,不想让连在一起的大块的黑色区域受一点影响,只是想要去除小块的噪点,查了众多资料以后,决定用这个方法,类似于画图工具里的油漆桶。

我先看了一下matlab里面自带的函数中没有想要的这个函数,于是决定自己找资料开发。
在此之前,你需要了解两个概念:四连通和八连通
你可以自己网搜或者:
(只需要了解四连通和八连通概念就好啦)
图形学学习笔记——区域填充
了解完以上概念可以开始写程序啦
在这里要感谢下面这个链接里的flood fill函数讲解,最终我的函数是基于这个写成的。
floodfill的C++实现
也就是说第一步我并没有写出可以实现将噪点去除的程序,而是写了一个这样的貌似没啥用还跟我的目标离着十万八千里的程序。
没错,现在做的确实差差差强人意。
首先按照视频里面的分别把dfs()函数和inarea()函数写出来(注意dfs()函数里面有地方一会需要修改),然后分别保存为子函数的文件。
之后写主程序(也就是public里面的内容)。

直接运行的话会有问题,下面来说一说都有哪些问题

  1. return在matlab里不是这样用的,只能用来结束当前运行的程序段返回上一级。因此将所有return数字的语句删掉。
  2. matlab里面函数的写法参考任意一个已有函数例如:
function [a,b]=name(x,y)
    a=-x;
    b=-y;
end
  1. 取一个数组的某一个元素时表示方法不同,只需grid(i,j)即可。等等这些两种语言之间的差异有很多,请大家根据自己的情况查漏补缺。(去网上搜balabala用matlab怎样实现)
  2. 我们要加上一个全局变量用以实现记录每一个黑色点是否被遍历过:
    生成一个全为1的与待检测矩阵的大小相同的矩阵,在第(i,j)点未被遍历过时对应CHECK(i,j)的值为1,在(i,j)点被遍历过时对应CHECK(i,j)的值为0。(主要针对主程序还未遍历到而子程序递归时已经走到过的点)
global CHECK
CHECK=ones(m,n);

将它放在主程序中,在子程序中需要用到这个变量时还要再写一遍“global CHECK”

  1. 在子程序dfs()中应用这个全局变量:
global CHECK
if(CHECK(x,y))%情况1,之前未遍历过
	CHECK(x,y)=0;%先将这个点标记为遍历过 
	%向四个方向进行搜索和递归的程序
	%……
else%情况2,之前遍历过
	return;%直接返回上一级
end   
  1. 判断是否越界的函数
function [sgn1]=inarea(x,y,img)
[m,n]=size(img);%获得图像边界
if (x<1||x>m||y<1||y>n)%判断是否超出界限
    sgn1=false;%若是,则返回false
else
      sgn1=true;%若不是,则返回true
end

到这里程序就写好了,复盘能力强的读者应该时自己就写出来了,如果是我表述不清或者复盘能力稍差一点那么请自行下载现成的程序包
稍稍稍稍后发布
我们先像视频中的那样试验一下,给出一个如下的超能说明问题的数组:

img=[
	1,1,1,0,0;
	0,0,1,0,1;
	0,1,1,0,0;
	0,1,0,0,1;
	0,1,1,1,1];

这个数组中有上连通、下连通、左连通和右连通的情况,还有一块小孤岛,正确的预计结果应该res=2。

再给一个能实验八连通的数组:

img=[
	1,1,0,0,0;
	0,1,0,0,1;
	0,0,1,0,0;
	0,1,1,0,1;
	0,0,1,1,1];

如果是四连通,运行结果应该是res=3,如果是八连通,运行结果会是res=2。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值