1、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(原图imshow(F);腐蚀图像imshow(BW);边界在上面的运行效果图上看来,由于原图选择的原因,周围一圈白线有一定宽度但不足够粗,大概只有23个像素宽度而腐蚀用元素大小为33,这导致腐蚀后图像留下的白线看起来残缺不全,用原图减去腐蚀后得到的边缘
2、图像也在白线处有“粘在一块”的现象。只要使用更高一些分辨率的图片即可避免这样的情况。但出于后续试验的运行速度考虑,本实验就使用此图(300300)。观察图像其他地方,有足够的像素宽度被腐蚀,由此提取的边缘也很清晰。% 区域填充I1 = fillbw(BW,40,40); % fillbw函数实现指定坐标填充边缘内部,详见主函数后的各子函数I1 = I1 | fillbw(BW,40,260); % 为避免不必要的计算量,每次填充迭代次数为70I1 = I1 | fillbw(BW,100,150); % 逐次在图像中选择需填充区域中的起始点以完成填充I1 = I1 | fillbw(BW,10
3、0,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 =
4、 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; % 因外围白线边缘之间没有足够空间,很难逐个填充空洞 % 故此处直接叠加腐蚀图像,把外围白线加上subplot(1,3,
5、1);subplot(1,3,2);imshow(I1);区域填充subplot(1,3,3);imshow(I2);区域填充+腐蚀实际上边缘图像是由原图像减去腐蚀图像得到的,而区域填充是在边缘图像的区域内填满的结果,故理论上来说最后区域填充的结果其实就是原来的腐蚀图像。从上图比较就可以看出,除了区域填充中未填的外围白线外,叠加了腐蚀图像的结果与区域填充是一样的,也与腐蚀图像一样(具体可以查看附件中的”区域填充.jpg”、”腐蚀.jpg”和”区域填充+腐蚀.jpg”)。% 细化A1 = fs(I2,20);imshow(A1); 实验效果图显示细化结果良好,表征了原图像的主要骨架特征。在实现细
6、化算法过程中,一开始在判定是否满足结构元素时采用的方法是实现写好一个元胞数组Bk,然后在程序中调用数组进行比较。后来发现这样的运算速度大大降低,改为在程序中现写结构元素矩阵。% 粗化A2 = fs(A1,2);imshow(A2);从上图看出在细化得到的骨架基础上,粗化得到的结果已经失去了原图像骨架之外的信息了,只能够把骨架大致的等宽度变粗而已。虽然粗化与细化在运算上是对偶的,但不同于加减法、乘除法的对偶,由于细化过程中图像逐个减去判定击中点,余留图像的信息量实际在减少,作为骨架的剩余信息已不足够做恢复原状的逆运算。图像中粗化线条中掺杂了很多间断,这是由于间断处两边在判定击中而粗化后,中间点的
7、形状不能满足判定结构元素中的任何一个,故不作为击中点而没有填白。子函数: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矩阵for i = 1+l:m-l % 遍历图像中33区域,若能放下结构元素f,则该点填白 for j = 1+l:n-l if (sum(sum(A(i-l:i+l,j-l:j+l) & f) = sum(f(:)
8、 Y(i,j) = 1; endendfunction Y = fillbw( A,x,y)%fillbw函数实现在图像A的第x行、第y列处开始,在边缘区域内填充白色A需填充图像% x起始点行数% y起始点列数% 避免小块区域填充时间过久,迭代次数不宜取过大,为方便调用,本函数在函数内部固定为70次YY(:,:,1) = zeros(m,n); % 起始图像为0矩阵YY(x,y,1) = 1; % 从指定位置开始填充f = 0,1,0;0,1,0;for k = 2:70 % 填充迭代70次 YY(:,k) = zeros(m,n); for i = 2:m-1 % YY(k)为YY(k-1)
9、的膨胀图像 for j = 2:n-1 if YY(i,j,k-1) = 1 YY(i-1:i+1,j-1:j+1,k) = YY(i-1:j+1,k) | f;,k) = YY(:,k) & not(A); % 膨胀后与边界的取反图像相与,保证不溢出边界Y = YY(:,70); % 输出为第70次填充结果function Y = fs( A,count )%fs函数将图像A细化count次A细化图像% count细化迭代次数Y = A;for k = 1:count % 设定迭代次数YY = ones(m,n); % 初始化中间变量for i = 2:m-1 % 在图像中寻找8个结构对元素
10、位置并涂黑(即细化) if Y(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;Y = Y & YY;m-1 if Y(j,i-1) = 0 & Y(j+1,i) = 0 & Y(j-1,i) = 1 & Y(j,i+1) = 1 if Y(j+1,i-1) = 0 & Y(j+1,i+1) = 0 & Y(j-1,i-1) = 1 if Y(j+1,i) = 0 & Y(j,i+1) = 0 & Y(j,i-1) = 1 & if Y(j-1,i-1) = 1 & Y(j+1,i-1) = 1 & Y(j-1,i+1) = 0 & Y(j+1,i+1) = 0 if Y(j,i-1) = 1 & Y(j+1,i) = 1 & Y(j-1,i) = 0 & Y(j,i+1) = 0 if Y(j+1,i-1) = 1 & Y(j+1,i) =
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1