原因是因为segments
实际上是一张地图,它告诉您图像的哪些区域是超像素。如果这张地图中的一个像素属于ID k
,这意味着这个像素属于超像素k
。此外,地图是类型的uint32
,所以当你尝试这样做时imshow(segments);
,它并没有显示出任何有意义的东西。对于在网站上看到的图像,根据您选择的参数,有 1023 个片段。因此,地图的范围从 0 到 1023。如果想查看段的样子,您可以执行imshow(segments,[]);
. 这将做的是,ID 为 1023 的区域将被映射为白色,而不属于任何超像素区域(ID 为 0)的像素被映射为黑色。你实际上会得到这样的东西:

意义不大!现在,要获得您在网页上看到的内容,您将不得不做更多的工作。据我所知,VLFeat
没有内置功能可以向您显示结果,例如在他们的网页上看到的结果。因此,您将不得不自己编写代码来完成它。您可以按照以下步骤执行此操作:
- 创建
true
与图像大小相同的地图
- 对于每个超像素区域
k
:
- 创建另一个地图,标记
true
属于该区域的任何像素k
,false
否则。
- 求这个区域的周长。
- 将这些周边像素设置为
false
在步骤 #1 中创建的地图中
- 重复步骤#2,直到我们完成所有区域。
- 使用此地图屏蔽原始图像中的所有像素,以获得您在网站上看到的内容。
现在让我们看一下这段代码。以下是您建立的设置:
vl_setup;
im = imread('slic_image.jpg');
regionSize = 10 ;
regularizer = 10 ;
segments = vl_slic(single(im), regionSize, regularizer);
现在让我们来看看我刚才提到的那个算法:
perim = true(size(im,1), size(im,2));
for k = 1 : max(segments(:))
regionK = segments == k;
perimK = bwperim(regionK, 8);
perim(perimK) = false;
end
perim = uint8(cat(3,perim,perim,perim));
finalImage = im .* perim;
imshow(finalImage);
因此我们得到:

请记住,这与您在网站上获得的内容并不完全相同。我只是去了网站并保存了该图像,然后继续使用我刚刚向您展示的代码。这可能是因为slic_image.jpg
图像不是他们示例中给出的确切原件。在存在一些不良量化伪影的区域中似乎存在超像素。另外,我使用的是相对较旧的版本VLFeat
- 0.9.16 版。从那时起,算法可能已经有所改进,所以我可能没有使用最新版本。无论如何,这对你来说是可以开始的。
希望这可以帮助!