分水岭 - 灰度图像中的局部最小值
Watershed - local minima in greyscale image
我有一组灰度图像,需要在其中定位局部最小值。我正在 Matlab 中编写代码,我正在寻找有关如何构建算法的建议:我需要计算梯度还是可以只使用 watershed
函数?
这是我用来做第一次分析的代码(下图):
IM_c = imcomplement(IM);
L = watershed(IM_c);
Lrgb = label2rgb(L);
figure; hold on;
subplot(3,1,1); imshow(IM_c); hold on;
subplot(3,1,2); imshow(Lrgb);hold on;
subplot(3,1,3); imshow(imfuse(IM_c,Lrgb));
凭直觉,我希望在箭头指向的像素中找到区域最小值:
你的问题是图像非常嘈杂。您应该对其进行模糊处理,以消除局部噪声。
例如,您可以使用高斯或框模糊或形态平滑,例如关闭操作。
我不确定分水岭是否是正确的工具。形态侵蚀在每个像素的定义邻域中分配局部最小值。从 侵蚀 图像和阈值 -1 中减去 原始 图像。剩余的非零像素,是局部最小值。
我想解决方案是使用渐变图像,遵循 this 论文中描述的算法。过程比较复杂,所以我
- 使用
imerode
和 imdilate
清理了图像;
- 制作图像的二值化版本 (
IM_bin
) 并将其用作过滤器,以便
如果 IM_bin(x,y) > 0
IM_clean(x,y) = IM(x,y);
别的
IM_clean(x,y) = 0;
- 再次使用
imerode
;
- 使用
imregionalmax
寻找区域最大值。
正如 Adi Shavit 所提到的,图像非常嘈杂。这会导致直接在图像上使用分水岭时过度分割(因为图像上有很多极值)。
您确实需要执行某种预处理来平滑图像。如果你不想使用模糊,你可以在找到极值之前尝试形态学重建(imreconstruct
)。
% if img is your original grayscale image
wSize = 6;
se = strel('disk', wSize);
% opening by reconstruction - to remove specks in the dark background
imgEroded = imerode(img, se);
imgRecon = imreconstruct(imgEroded, img);
imgReconComp = imcomplement(imgRecon);
% opening by reconstruction - to homogenize the pixels in the foreground(clouds)
imgEroded2 = imerode(imgReconComp, se);
imgRecon2 = imreconstruct(imgEroded2, imgReconComp);
minima = imregionalmin(imgRecon2);
覆盖在原始图像上的最小值看起来像这样 -
您可以尝试使用结构元素的size/shape,看看是否能得到更好的结果。
您也可以使用极值作为种子对梯度图像进行分水岭分割,但这可能不会产生有意义的结果(看起来您并没有尝试执行分割)。
我有一组灰度图像,需要在其中定位局部最小值。我正在 Matlab 中编写代码,我正在寻找有关如何构建算法的建议:我需要计算梯度还是可以只使用 watershed
函数?
这是我用来做第一次分析的代码(下图):
IM_c = imcomplement(IM);
L = watershed(IM_c);
Lrgb = label2rgb(L);
figure; hold on;
subplot(3,1,1); imshow(IM_c); hold on;
subplot(3,1,2); imshow(Lrgb);hold on;
subplot(3,1,3); imshow(imfuse(IM_c,Lrgb));
凭直觉,我希望在箭头指向的像素中找到区域最小值:
你的问题是图像非常嘈杂。您应该对其进行模糊处理,以消除局部噪声。
例如,您可以使用高斯或框模糊或形态平滑,例如关闭操作。
我不确定分水岭是否是正确的工具。形态侵蚀在每个像素的定义邻域中分配局部最小值。从 侵蚀 图像和阈值 -1 中减去 原始 图像。剩余的非零像素,是局部最小值。
我想解决方案是使用渐变图像,遵循 this 论文中描述的算法。过程比较复杂,所以我
- 使用
imerode
和imdilate
清理了图像; - 制作图像的二值化版本 (
IM_bin
) 并将其用作过滤器,以便 如果 IM_bin(x,y) > 0
IM_clean(x,y) = IM(x,y); 别的 IM_clean(x,y) = 0; - 再次使用
imerode
; - 使用
imregionalmax
寻找区域最大值。
正如 Adi Shavit 所提到的,图像非常嘈杂。这会导致直接在图像上使用分水岭时过度分割(因为图像上有很多极值)。
您确实需要执行某种预处理来平滑图像。如果你不想使用模糊,你可以在找到极值之前尝试形态学重建(imreconstruct
)。
% if img is your original grayscale image
wSize = 6;
se = strel('disk', wSize);
% opening by reconstruction - to remove specks in the dark background
imgEroded = imerode(img, se);
imgRecon = imreconstruct(imgEroded, img);
imgReconComp = imcomplement(imgRecon);
% opening by reconstruction - to homogenize the pixels in the foreground(clouds)
imgEroded2 = imerode(imgReconComp, se);
imgRecon2 = imreconstruct(imgEroded2, imgReconComp);
minima = imregionalmin(imgRecon2);
覆盖在原始图像上的最小值看起来像这样 -
您可以尝试使用结构元素的size/shape,看看是否能得到更好的结果。
您也可以使用极值作为种子对梯度图像进行分水岭分割,但这可能不会产生有意义的结果(看起来您并没有尝试执行分割)。