使用带有种子点的图割进行图像分割

10
我正在从事医学图像分割工作,希望将模糊连通算法与图割算法相结合。这个想法是使用模糊连通算法对图像进行分割,将背景和前景用作图割算法的汇点和源点。以下是我的代码,用于获取图割分割的种子坐标。
FC=afc(S,K); %// Absolute FC
u=FC>thresh;
v=FC<thresh;

s=regionprops(u, 'PixelIdxList'); %// listes de pixels de l´objet
t=regionprops(v, 'PixelIdxList'); %// listes de pixels de l´arrière plan
[a,b]=size(s);
[w,c,z]= size(t)

for i=1:a
    for j=1:b
        [y,x] = ind2sub(size(u), s(i,j).PixelIdxList);
    end
end
for k=1:w
    for d=1:c
        [y1,x1] = ind2sub(size(v), t(k,d).PixelIdxList);
    end
end

我使用了来自文件交换的算法进行图形割。

例如,我可以定义

Cs=-log([y x])
Ct=-log([y1 x1])

但问题在于如何将像代码来源中的成本函数信息结合起来。

u = double((Cs-Ct) >= 0);
ps = min(Cs, Ct);
pt = ps

如果超出了矩阵的大小,会出现错误。

1个回答

6
我不熟悉你提供的FEX图像切割实现,但我会展示一个使用GCMex matlab wrapper的例子(声明:我实现了这个wrapper)。
假设您有一个大小为size(S)的图像,其中包含n个像素和一个大小为n-by-n的稀疏矩阵K,其中K(ii,jj)表示有多好地连接了相邻的像素iijj
此外,您还有一个前景像素掩码u和一个背景像素掩码v,需要作为硬约束条件进行处理。
首先,使用uv构造数据项。
Dc = 1000*[u(:), v(:)]; %// assign very large cost for picking FG pixel to label zero and vice versa

正如您所看到的data-term Dc,是一个n行2列的数组,将标签l(0或1)分配给像素ii的成本存储在Dc(ii,l+1)中。因此,对于前景中的像素(u(ii)为1),分配标签l=0(即背景)所付出的代价为1000。同样,对于背景中的像素(v(ii)为1),将它们分配给前景(即l=1)的代价也是1000。因此,数据项Dc会给种子像素(无论是前景还是背景)分配错误标签带来非常高的代价。

构建一个图割对象

gch = GraphCut('open'), Dc, [0 1; 1 0], K );
[gch L] = GraphCut('expand',gch);
gch = GraphCut('close',gch);
L = reshape(L, size(u)); 
figure; imshow(L,[]); title('the resulting mask');

请注意,要使用GCMex,您需要按照安装说明进行编译才能正常工作。

请问您能详细说明一下如何将权重分配给源和汇吗?目前的做法是从最大值中减去源的值以获取汇的值,这样做有意义吗? - ZdaR
请点击以下链接,这是一个交互式图形割的简单实现: https://masterravi.wordpress.com/2011/05/24/interactive-segmentation-using-graph-cutsmatlab-code/ - Born New
不错!我在想如何以交互方式完成这个操作,即用户可以在图割运行后将种子像素标记为硬约束条件。是否可以在不重新计算所有内容的情况下合并此输入? - user1809923
@user1809923,你可以在这本书的章节中了解更多关于交互式和迭代式图像分割的内容。它提出了一种非常有趣的方法来理解标记种子和分割线索中的“用户意图”。 - Shai
谢谢提供链接!我已经阅读了其中的部分内容。不过,我的问题更关注于您的Matlab封装器(或者说其他Matlab实现方式)。 - user1809923
@user1809923 我的封装程序相当有限。它提供了一个全局解决方案,因此需要在每次添加种子后重新计算。也许可以深入封装的 C++ 代码中,以便在计算过程中重复使用图路径,从而使细化迭代更加高效。但这种优化超出了此封装程序的范围。 - Shai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接