MATLAB数字图像的腐蚀填充细化与粗化.docx
《MATLAB数字图像的腐蚀填充细化与粗化.docx》由会员分享,可在线阅读,更多相关《MATLAB数字图像的腐蚀填充细化与粗化.docx(10页珍藏版)》请在冰豆网上搜索。
《数字图像处理》
实验报告
姓名 学号 专业电子科学与工程学院 实验5
一、实验目的
本次实验的处理对象是二值图像,关于二值图像的处理运算主要包括腐蚀和膨胀。
它们是其他处理过程的主要运算环节。
开闭操作通过腐蚀和膨胀的不同顺序组合,能够使图像平滑,开闭操作再组合能够成噪声滤波器。
形态学中的击中击不中变换也应用了腐蚀的运算,用于判断图像中能否找到目标结构,这在图像细化中也得到了应用。
本次实验主要实现:
1.图像的边缘提取;
2.在边缘提取的基础上实现区域填充;
3.在区域填充的基础上实现图像细化;
4.在图像细化的基础上实现图像粗化。
在Matlab软件的自带函数库中其实本身就包含有以上处理过程的函数,为了深入理解每种处理过程的原理,本次实验所有运算都自行编写实现。
二、核心代码及运行后截图
主函数:
%%读取图像
clear;clc;
I=imread('onepiece.jpg');
I=im2bw(I); %转换为二值图像
[m,n]=size(I);
%%边界提取
f=im2bw([0,1,0;1,1,1;0,1,0]); %腐蚀用的结构元素
F=fs(I,f);
BW=im2bw(I-F); %用原图减去腐蚀获得边缘
figure;imshow(I);title('原图');
figure;imshow(F);title('腐蚀图像');
figure;imshow(BW);title('边界');
在上面的运行效果图上看来,由于原图选择的原因,周围一圈白线有一定宽度但不足够粗,大概只有2~3个像素宽度而腐蚀用元素大小为3×3,这导致腐蚀后图像留下的白线看起来残缺不全,用原图减去腐蚀后得到的边缘图像也在白线处有“粘在一块”的现象。
只要使用更高一些分辨率的图片即可避免这样的情况。
但出于后续试验的运行速度考虑,本实验就使用此图(300×300)。
观察图像其他地方,有足够的像素宽度被腐蚀,由此提取的边缘也很清晰。
%%区域填充
I1=fillbw(BW,40,40); %fillbw函数实现指定坐标填充边缘内部,详见主函数后的各子函数
I1=I1|fillbw(BW,40,260); %为避免不必要的计算量,每次填充迭代次数为70
I1=I1|fillbw(BW,100,150); %逐次在图像中选择需填充区域中的起始点以完成填充
I1=I1|fillbw(BW,100,160);
I1=I1|fillbw(BW,136,86);
I1=I1|fillbw(BW,132,212);
I1=I1|fillbw(BW,147,120);
I1=I1|fillbw(BW,157,214);
I1=I1|fillbw(BW,210,171);
I1=I1|fillbw(BW,206,109);
I1=I1|fillbw(BW,233,129);
I1=I1|fillbw(BW,234,140);
I1=I1|fillbw(BW,237,153);
I1=I1|fillbw(BW,234,167);
I1=I1|fillbw(BW,231,178);
I1=I1|fillbw(BW,248,125);
I1=I1|fillbw(BW,252,142);
I1=I1|fillbw(BW,252,162);
I1=I1|fillbw(BW,247,182);
I1=I1|fillbw(BW,272,149);
I1=I1|fillbw(BW,256,50);
I1=I1|fillbw(BW,253,248);
I2=I1|F; %因外围白线边缘之间没有足够空间,很难逐个填充空洞
figure; %故此处直接叠加腐蚀图像,把外围白线加上
subplot(1,3,1);imshow(I);title('原图');
subplot(1,3,2);imshow(I1);title('区域填充');
subplot(1,3,3);imshow(I2);title('区域填充+腐蚀');
实际上边缘图像是由原图像减去腐蚀图像得到的,而区域填充是在边缘图像的区域内填满的结果,故理论上来说最后区域填充的结果其实就是原来的腐蚀图像。
从上图比较就可以看出,除了区域填充中未填的外围白线外,叠加了腐蚀图像的结果与区域填充是一样的,也与腐蚀图像一样(具体可以查看附件中的”区域填充.jpg”、”腐蚀.jpg”和”区域填充+腐蚀.jpg”)。
%%细化
A1=fs(I2,20);
figure;imshow(A1);
实验效果图显示细化结果良好,表征了原图像的主要骨架特征。
在实现细化算法过程中,一开始在判定是否满足结构元素时采用的方法是实现写好一个元胞数组B{k},然后在程序中调用数组进行比较。
后来发现这样的运算速度大大降低,改为在程序中现写结构元素矩阵。
%%粗化
A2=fs(~A1,2);
figure;imshow(~A2);
从上图看出在细化得到的骨架基础上,粗化得到的结果已经失去了原图像骨架之外的信息了,只能够把骨架大致的等宽度变粗而已。
虽然粗化与细化在运算上是对偶的,但不同于加减法、乘除法的对偶,由于细化过程中图像逐个减去判定击中点,余留图像的信息量实际在减少,作为骨架的剩余信息已不足够做恢复原状的逆运算。
图像中粗化线条中掺杂了很多间断,这是由于间断处两边在判定击中而粗化后,中间点的形状不能满足判定结构元素中的任何一个,故不作为击中点而没有填白。
子函数:
function[Y]=fs(A,f)
%fs函数实现用结构元素模板f将图像A腐蚀
%输入:
A——被腐蚀图像
% f——结构元素,此函数只编写了方形情
% 况,大小可自定义
[m,n]=size(A); %获取图像大小
l=(size(f)-1)/2;
Y=im2bw(zeros(m,n)); %初始化输出为0矩阵
fori=1+l:
m-l %遍历图像中3×3区域,若能放下结构元素f,则该点填白
forj=1+l:
n-l
if(sum(sum(A(i-l:
i+l,j-l:
j+l)&f))==sum(f(:
)))
Y(i,j)=1;
end
end
end
end
function[Y]=fillbw(A,x,y)
%fillbw函数实现在图像A的第x行、第y列处开始,在边缘区域内填充白色
%输入:
A——需填充图像
% x——起始点行数
% y——起始点列数
%避免小块区域填充时间过久,迭代次数不宜取过大,为方便调用,本函数在函数内部固定为70次
[m,n]=size(A);
YY(:
:
1)=zeros(m,n); %起始图像为0矩阵
YY(x,y,1)=1; %从指定位置开始填充
f=[0,1,0;1,1,1;0,1,0];
fork=2:
70 %填充迭代70次
YY(:
:
k)=zeros(m,n);
fori=2:
m-1 %YY(k)为YY(k-1)的膨胀图像
forj=2:
n-1
ifYY(i,j,k-1)==1
YY(i-1:
i+1,j-1:
j+1,k)=YY(i-1:
i+1,j-1:
j+1,k)|f;
end
end
end
YY(:
:
k)=YY(:
:
k)¬(A); %膨胀后与边界的取反图像相与,保证不溢出边界
end
Y=YY(:
:
70); %输出为第70次填充结果
end
function[Y]=fs(A,count)
%fs函数将图像A细化count次
%输入:
A——细化图像
% count——细化迭代次数
[m,n]=size(A);
Y=A;
fork=1:
count %设定迭代次数
YY=ones(m,n); %初始化中间变量
fori=2:
n-1
forj=2:
m-1 %在图像中寻找8个结构对元素位置并涂黑(即细化)
ifY(j-1,i-1)==0&&Y(j,i-1)==0&&Y(j+1,i-1)==0&&Y(j,i)==1&&Y(j-1,i+1)==1&&Y(j,i+1)==1&&Y(j+1,i+1)==1
YY(j,i)=0;
end
end
end
Y=Y&YY;
YY=ones(m,n);
fori=2:
n-1
forj=2:
m-1
ifY(j,i-1)==0&&Y(j+1,i-1)==0&&Y(j+1,i)==0&&Y(j,i)==1&&Y(j-1,i)==1&&Y(j-1,i+1)==1&&Y(j,i+1)==1
YY(j,i)=0;
end
end
end
Y=Y&YY;
YY=ones(m,n);
fori=2:
n-1
forj=2:
m-1
ifY(j+1,i-1)==0&&Y(j+1,i)==0&&Y(j+1,i+1)==0&&Y(j,i)==1&&Y(j-1,i)==1&&Y(j-1,i+1)==1&&Y(j-1,i-1)==1
YY(j,i)=0;
end
end
end
Y=Y&YY;
YY=ones(m,n);
fori=2:
n-1
forj=2:
m-1
ifY(j+1,i)==0&&Y(j+1,i+1)==0&&Y(j,i+1)==0&&Y(j,i)==1&&Y(j,i-1)==1&&Y(j-1,i)==1&&Y(j-1,i-1)==1
YY(j,i)=0;
end
end
end
Y=Y&YY;
YY=ones(m,n);
fori=2:
n-1
forj=2:
m-1
ifY(j-1,i-1)==1&&Y(j,i-1)==1&&Y(j+1,i-1)==1&&Y(j,i)==1&&Y(j-1,i+1)==0&&Y(j,i+1)==0&&Y(j+1,i+1)==0
YY(j,i)=0;