健牛问题:分水岭算法的具体步骤是什么?
镶嵌牛文字:
一、概述
分水岭分割算法将图像视为“地形图”,其中较亮的区域具有较大的像素值,而较暗的区域具有较小的像素值。通过查找“集水盆地”和“分水岭边界”,拆分图像。但是,直接应用分水岭分割算法的效果通常不好。如果在图像中标记了前景对象和背景对象,则分水岭算法将获得更好的分割效果。基于标记控制的分水岭分割方法具有以下基本步骤:
1概述
分水岭分割算法将图像视为“地形图”,其中较亮的区域具有较大的像素值,而较暗的区域具有较小的像素值。通过寻找“集水盆地”和“分水岭边界”,分割图像。直接应用分水岭分割算法的效果通常不好。如果在图像中标记和区分了前景对象和背景对象,则应用分水岭算法将获得更好的分割效果。基于标记控制的分水岭分割方法具有以下基本步骤:
1.计算分割函数。图片中较暗的区域是要分割的对象
2.计算前景标志。这些是连接在每个对象内部的点状像素。
3.计算背景徽标。这些元素不属于任何对象。
4.修改分段功能,使其仅在前景和背景标记位置具有最小值。
5.对修改后的分割函数执行分水岭变换计算。
使用MATLAB图像处理工具箱
注意:在此期间,使用了许多图像处理工具箱功能,例如fspecial,imfilter,分水岭,label2rgb,imopen,imclose,imreconstruct,imcomplement,imregionalmax,bwareaopen,graythresh和impimposemin函数。
2个步骤
第一步:读入彩色图像并将其转换为灰度图像
clc;清除所有关闭所有;
rgb = imread('pears.png');
如果ndims(rgb)== 3
I = rgb2gray(rgb);
其他
I = rgb;
结束
figure('units','normalized','position',[0 0 1 1]);
第2步:使用梯度幅度作为分割函数
使用Sobel边缘运算符水平和垂直过滤图像,然后计算模量。由sobel运算符过滤的图像将在边界处显示相对较大的值,如果没有边界,则该值将较小。
hy = fspecial('sobel');
hx = hy';
Iy = imfilter(double(I),hy,'replicate');
Ix = imfilter(double(I),hx,'replicate');
gradmag = sqrt(Ix。^ 2 + Iy。^2);
figure('units','normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(I,[]),title('Gray Image')
子图(1,2,2); imshow(gradmag,[]),标题('梯度幅值图像')
可以在梯度幅值图像上直接使用分水岭算法吗?
L =分水岭(gradmag);
Lrgb = label2rgb(L);
figure('units','normalized','position',[0 0 1 1]);
子图(1,2,1); imshow(gradmag,[]),标题('梯度振幅图像')
subplot(1,2,2); imshow(Lrgb); title('梯度幅度用于分水岭变换')
直接使用梯度模量图像执行分水岭算法而获得的结果通常会出现过度分割的现象。因此,通常需要分别标记前景对象和背景对象,以获得更好的分割效果。
第3步:标记前景对象
这里可以使用多种方法来获取前景标记。这些标记必须与前景对象内的斑点像素相连。在该示例中,将使用形态学技术“基于开放的重建”和“基于封闭的重建”来清理图像。这些操作将在每个对象内创建单位最大值,从而可以使用imregionalmax进行定位。
打开操作和关闭操作:首先腐蚀,然后膨胀称为打开;先膨胀然后腐蚀称为封闭。打开和关闭这两个操作可以删除小于结构元素的特定图像细节,同时确保不产生全局几何变形。打开操作可以滤除小于结构元件的支脚,并切断细长的重叠部分以进行分离;闭合操作可以填充小于结构元件的间隙或孔,并且重叠的短间隔可以起到连接的作用。
开放操作是腐蚀后的膨胀,基于开放的重构(基于重构的开放操作)是腐蚀后的形态重构。比较下面这两种方法。首先,使用imopen进行打开操作。
se = strel('disk',20);
Io = imopen(I,se);
figure('units'凤凰彩票官网 ,'normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(I,[]); title('灰度图像');
子图(1,2,2); imshow(Io),标题('图像打开操作')
接下来,通过腐蚀后的重建,基于开路进行重建计算。
即= imerode(I,se)
Iobr = imreconstruct(Ie,I);
figure('units','normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(I,[]); title('灰度图像');
子图(1,2,2); imshow(Iobr,[]),标题('基于开放的重建图像')
在打开操作之后,进行关闭操作以去除较暗的斑点和分支标记。比较常规形态关闭操作和基于关闭的重构操作。首先,使用imclose:
Ioc = imclose(Io,se);
Ic = inclose(I,se);
figure('units','normalized','position',[0 0 1 1]);
subplot(2,2,1); imshow(I,[]); title('Gray Image');
subplot(2,2,2); imshow(Io,[]); title('Open operation image');
subplot(2,2,3); imshow(Ic,[]); title('关闭操作图片');
subplot(2,2,4); imshow(Ioc,[]),title('打开和关闭操作');
现在使用imdilate,然后进行imreconstruct。请注意,必须对输入图像进行补充,而对非重构输出图像必须进行补充。 IM2 = imcomplement(IM)计算图像IM的补数。 IM可以是二进制图像,也可以是RGB图像。 IM2和IM具有相同的数据类型和大小。
Iobrd = imdilate(Iobr,se);
Iobrcbr = imreconstruct(imcomplement(Iobrd),imcomplement(Iobr));
Iobrcbr = imcomplement(Iobrcbr);
figure('units','normalized','position',[0 0 1 1]);
subplot(2,2,1); imshow(I,[]); title('Gray Image');
subplot(2,2,2); imshow(Ioc,[]); title('打开和关闭操作');
subplot(2,2,3); imshow(Iobr,[]); title('基于开放的重建图像');
subplot(2,2,4); imshow(Iobrcbr,[]),title('基于闭包的重构图像');
通过比较Iobrcbr和loc,我们可以看到,在不影响对象整体形状的情况下删除小污点的应用中,基于重构的打开和关闭操作比标准的打开和关闭重构更有效。计算Iobrcbr的局部最大值以获得更好的前景标记。
fgm = imregionalmax(Iobrcbr);
figure('units','normalized','position',[0 0 1 1]);
subplot(1,3澳洲幸运8 ,1); imshow(I,[]); title('Gray Image');
subplot(1,3,2); imshow(Iobrcbr,[]); title('基于重构的打开和关闭操作');
subplot(1,3,3); imshow(fgm,[]); title('local maximum image');
为帮助理解此结果,请将前景标记叠加在原始图像上。
It1 = rgb(:,:,1);
It2 = rgb(:,:,2);
It3 = rgb(:,:,3);
It1(fgm)= 255; It2(fgm)= 0; It3(fgm)= 0;
I2 = cat(3,It1,It2,It 3);
figure('units','normalized','position',[0 0 1 1]);
subplot(2,2万人牛牛 ,1); imshow(rgb,[]); title('原始图片');
subplot(2,2,2); imshow(Iobrcbr,[]); title('基于重构的打开和关闭操作');
subplot(2,2,3); imshow(fgm,[]); title('local maximum image');
subplot(2,2,4); imshow(I2); title('局部最大值叠加在原始图像上');
请注意,大多数遮挡和阴影对象均未标记,这意味着这些对象将不会在结果中进行合理的分割。此外,某些对象的前景标记将到达对象的边缘。这意味着标记斑点的边缘应先清洁然后缩小。可以通过关闭操作和蚀刻操作来完成。
se2 = strel(ones(5,5));
fgm2 = imclose(fgm,se2);
fgm3 = imerode(fgm2,se2);
figure('units','normalized','position',[0 0 1 1]);
subplot(2,2,1); imshow(Iobrcbr,[]); title('基于重构的打开和关闭操作');
subplot(2,2捕鱼平台 ,2); imshow(fgm,[]); title('local maximum image');
subplot(2,2,3); imshow(fgm2,[]); title('closed operation');
subplot(2,2,4); imshow(fgm3,[]); title('corrosion operation');
此过程将留下一些杂散的孤立像素,应将其删除。您可以使用bwareaopen删除少于一定像素数的斑点。 BW2 = bwareaopen(BW,P)从二进制图像中删除小于P像素值的连接块,以获得另一个二进制图像BW2。
fgm4 = bwareaopen(fgm3,20);
It1 = rgb(:,:,1);
It2 = rgb(:,:,2);
It3 = rgb(:,:,3);
It1(fgm 4) = 255; It2(fgm 4) = 0; It3(fgm 4) = 0;
I3 = cat(3,It1,It2,It 3);
figure('units','normalized','position',[0 0 1 1]);
subplot(2,2,1); imshow(I2,[]); title('局部最大值叠加在原始图像上');
子图(2,2,2); imshow(fgm3,[]);标题('关闭腐蚀操作');
subplot(2,2,3); imshow(fgm4,[]); title('小斑点去除操作');
subplot(2,2,4); imshow(I3,[]); title('将局部最大叠加量修改为原始图像');
第4步:计算背景标记
现在,您需要标记背景。在清理的图像Iobrcbr中,暗像素属于背景,因此您可以从阈值操作开始。
bw = im2bw(Iobrcbr,graythresh(Iobrcbr));
figure('units','normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(Iobrcbr,[]); title('基于重构的打开和关闭操作');
subplot(1,2,2); imshow(bw,[]); title('阈值分割');
背景像素位于黑色区域,但理想情况下,不需要背景标记与要分割的对象的边缘太近。通过计算“骨架影响范围”以“细化” SKIZ的背景或前景,bw。这可以通过计算bw的距离变换的分水岭变换,然后查找所得的分水岭脊线(DL ==0)。D = bwdist(BW)来计算二进制图像BW的欧几里得矩阵来实现。 BW对于每个像素分水岭算法,距离变换指定像素与最近的BW非零像素之间的距离; bwdist默认使用欧几里德距离公式。BW可以具有任何尺寸,D和BW具有相同的大小。
D = bwdist(bw);
DL =分水岭(D);
bgm = DL == 0;
figure('units','normalized','position'分水岭算法,[0 0 1 1]);
subplot(2,2ag捕鱼王 ,1); imshow(Iobrcbr,[]); title('基于重构的打开和关闭操作');
subplot(2,2,2); imshow(bw,[]); title('threshold segmentation');
subplot(2,2,3); imshow(label2rgb(DL),[]); title('Watershed Transformation diagram');
subplot(2,2,4); imshow(bgm,[]); title('Watershed Transformation Ridgeline Plot');
第5步:计算分割函数的分水岭变换
imimposemin函数可用于修改图像,以使其仅在特定的所需位置具有局部最小值。在这里,您可以使用impimposemin修改渐变幅度图像,使其仅在前景和背景标记像素中具有局部最小值。
gradmag2 = imimposemin(gradmag,bgm | fgm 4);
figure('units','normalized','position',[0 0 1 1]);
subplot(2,2,1) imshow(bgm,[]); title('Watershed Transformation Ridge Diagram');
subplot(2,2,2); imshow(fgm4,[]); title('Foreground Marker');
subplot(2,2,3); imshow(gradmag,[]); title('Gradientitude image');
subplot(2,2,4); imshow(gradmag2,[]); title('修改梯度幅值图像');
最后,可以完成基于分水岭的图像分割计算。
第6步:查看结果
一种可视化技术是将前景标记,背景标记叠加,并将对象边界分割到初始图像上。扩张可用于实现某些要求,例如对象边界,这些要求更加清晰可见。对象边界位于L == 0的位置。
It1 = rgb(:,:,1);
It2 = rgb(:,:,2);
It3 = rgb(:,:,3);
fgm5 = imdilate(L == 0,个(3,3))| bgm | fgm4;
It1(fgm 5) = 255; It2(fgm 5) = 0; It3(fgm 5) = 0;
I4 = cat(3,It1,It2,It 3);
figure('units','normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(rgb,[]); title('原始图片');
subplot(1,2,2); imshow(I4,[]); title('对象的标记和边缘叠加在原始图像上');
该可视化图说明了前景和背景标记如何影响结果。在几个位置,一些较暗的对象与它们相邻的较亮的相邻对象合并,因为被遮挡的对象没有前景标记。
另一种有用的可视化技术是将标记矩阵显示为彩色图像。通过分水岭和bwlabel获得的标签矩阵可以使用label2rgb转换为真彩色图像以进行显示。
Lrgb = label2rgb(L,'jet','w','shuffle');
figure('units','normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(rgb,[]); title('原始图片');
subplot(1,2,2); imshow(Lrgb); title('颜色分水岭标记矩阵');
您可以使用透明度将该伪彩色标记矩阵叠加在原始亮度图像上以进行显示。
figure('units','normalized','position',[0 0 1 1]);
subplot(1,2,1); imshow(rgb,[]); title('原始图片');
subplot(1,2,2); imshow(rgb,[]);等等;
himage = imshow(Lrgb);
set(himage,'AlphaData',0.3);
title('标记矩阵叠加在原始图像上');