➊读取图像;
❷创建纹理图像;
❸显示图像不同部分的纹理;
❹使用合适的滤波器进行分割。
如果图像中的目标物体是连接在一起的,则分割起来会更困难,分水岭分割算法经常用于处理这类问题,通常会取得比较好的效果。
分水岭分割算法把图像看成一幅“地形图”,其中亮度比较强的地区像素值较大,而比较暗的地区像素值较小,通过寻找“汇水盆地”和“分水岭界限”,对图像进行分割。
代码如下:
I = imread ('bag.png');%读取图像
imshow(I);%显示原图像
在这个程序中,首先读取一幅图像bag,这个图像的顶部和底部的纹理有明显的差异,如图1所示。
代码如下:
E = entropyfilt(I);%创建纹理图像
Eim = mat2gray(E);%转化为灰度图像
figure; subplot(121)
imshow(Eim);%显示灰度图像
Bw1 = im2bw(Eim,0.8);%转化为二值图像
subplot (122); imshow(Bw1);%显示二值图像
使用函数entropyfilt创建一幅纹理图像,这个函数返回的图像与输入图像大小相同,每个像素值是输入图像相应像素值邻域的嫡值。
使用函数mat2gray将矩阵转化为灰度图像,如图2左边图像所示。使用纹理边界处的值0.8作为阈值将灰度图像转化为二值图像,如图2右边图像所示。
代码如下:
BWao = bwareaopen(Bw1,2000);%提取底部纹理
figure; subplot(121)
imshow(BWao);%显示底部纹理图像
nhood = true(9) ;
closeBWao = imclose(BWao ,nhood); %形态学关操作
subplot(122); imshow(closeBWao)%显示边缘光滑后的图像
roughMask = imfill(closeBWao, 'holes');%填充操作
figure; subplot(121)
imshow (roughMask);%显示填充后的图像
I2= I;
I2(roughMask) = 0;%底部设置为黑色
subplot(122); imshow(I2);%突出显示图像的顶部
运行结果:
分割后的图像目标区域显示为白色,跟原图像相比,图像顶部的纹理被过度分割,而底部的纹理则以一个整体被分割出来,可以使用bwareaopen函数提取图像的底部纹理,如图3左边图像所示。在这个图像中,分割出的边界并不光滑,并且含有很多孔洞,可以使用imclose函数对图像执行形态学关操作,处理后的图像如图3右边图像所示。
使用imfill函数对图像中的孔洞进行填充,填充后的图像如图4左边图像所示,跟原图像相比,生成的图像底部纹理并不完全吻合,可以使用这个图像对原图像顶部的纹理进行分割,得到的图像顶部纹理如图4右边图像所示。
代码如下:
E2 = entropyfilt (I2);%创建纹理图像
E2im = mat2gray(E2);%转化为灰度图像
figure; subplot(121)
imshow(E2im) ; %显示纹理图像
Bw2 = im2bw(E2im, graythresh(E2im));%转化为二值图像
subplot (122) ; imshow(Bw2)%显示二值图像
mask2 = bwareaopen(Bw2,1000) ;%求取图像顶部的纹理掩膜
figure; imshow(mask2);%显示顶部纹理掩膜图像
texture1 = I; texture1(~mask2) = 0;%底部设置为黑色
texture2 = I; texture2(mask2) = 0;%顶部设置为黑色
figure; subplot(121)%显示图像顶部
imshow(texture1) ; subplot(122),imshow(texture2);%显示图像底部
boundary = bwperim(mask2);%求取边界
segmentResults = I;
segmentResults(boundary) =255;%边界处设置为白色
figure; imshow(segmentResults);%显示分割结果
使用entropyfilt函数对图像进行滤波,求取纹理图像,如图5左边图像所示。选择合适的阈值将纹理图像转化为二值图像,如图5右边图像所示。
使用bwareaopen函数对图像进行开操作,得到图像顶部纹理的掩膜图像,如图6所示。
分别提取图像的顶部纹理和底部纹理,如图7所示,其中左边图像为顶部纹理的图像,右边图像为底部纹理的图像。
上下两种纹理的边界线以白色显示,如图8所示。
代码如下:
s = stdfilt(I,nhood) ; %标准差滤波
figure; subplot(121)
imshow(mat2gray(s)) ;%显示标准差滤波后的图像
R= rangefilt (I,ones (5)); %rangefilt滤波
subplot(122); imshow (R);%显示rangefilt滤波后的图像
除了使用entropyfilt函数,还可以使用stdfilt函数和rangefilt函数来达到类似的分离效果,分离的效果如图9所示,其中左边图像为使用stdfilt函数滤波后分割的图像,右边图像为使用rangefilt函数滤波后分割的图像。