开放轮廓线图的分割

时间:2021-03-22 16:44:45

标签: python image-processing computer-vision image-segmentation

Here 是我所说的绘图类型的一个示例:

它有明显不同的区域,但它们不是完全封闭的。

我正在尝试分割图像,但由于它是 1 位颜色,因此我没有任何有用的信息(如色调或值梯度)来做出更有根据的猜测。乍一看,分割算法可以用来做出决定的唯一信息似乎是低于或高于某个阈值的间隙宽度。

我的问题是,在 scikit-image 或 opencv 中是否有一种特定的方法或算法适用于这种输入或至少类似的东西。

1 个答案:

答案 0 :(得分:1)

您可以使用 negative affinities 和相关聚类将您的图像分割成这样的内容:
enter image description here

您可以为附近的像素对定义“亲和力”:如果它们之间存在“边缘”像素 - 那么它们应该具有负亲和力(它们不应聚集在一起)。
如果它们之间没有任何边缘像素 - 那么它们应该具有正亲和力(它们应该聚集在一起)。

一旦你有了亲和度矩阵,你就可以对它应用 correlation clustering

这是 Matlab 中解决方案的草图:

img = imread('PaG3p.png');
bw = img(:,:,1) > 128;
n = numel(bw);

% construct the affinity matrix using improfile
[x, y] = meshgrid(1:size(bw,2), 1:size(bw,1));
x = x(:);
y = y(:);

r = 5;
[dx, dy] = meshgrid(-r:r, -r:r);
dx = dx(:);
dy = dy(:);
sel = max(abs(dx),abs(dy)) == r & dx >= dy;
dx = dx(sel);
dy = dy(sel);
m = numel(dx);

ii = nan(n*m, 1);
jj = nan(n*m, 1);
wij = zeros(n*m, 1);
counter = 1;
for k=1:n    
    % from
    fi = y(k);
    fj = x(k);
    if bw(fi, fj)
        % to
        for l=1:m
            ti = fi + dy(l);
            tj = fj + dx(l);
            if ti > 1 && tj > 1 && ti <= size(bw,1) && tj <= size(bw,2) && bw(ti, tj)
                p = improfile(bw, [fj, tj], [fi, ti]);
                num_cross = sum((p(2:end)-p(1:end-1)) == -1);
                
                ii(counter) = k;
                jj(counter) = sub2ind(size(bw), ti, tj);

                if  num_cross == 1
                    % only one cross of edge
                    wij(counter) = -1;
                elseif num_cross == 0
                    % no crosses
                    wij(counter) = 1;
                end
                counter = counter + 1;
            end
        end
    end
    % add 4 connect
    if fi < size(bw,1) && bw(fi+1, fj)
        ii(counter) = k;
        jj(counter) = sub2ind(size(bw), fi + 1, fj);
        wij(counter) = (bw(fi, fj) == bw(fi+1, fj))*2 - 1;
        counter = counter + 1;
    end
    if fj < size(bw,2) && bw(fi, fj+1)
        ii(counter) = k;
        jj(counter) = sub2ind(size(bw), fi, fj + 1);
        wij(counter) = (bw(fi, fj) == bw(fi, fj+1))*2 - 1;
        counter = counter + 1;
    end    
end

sel = ~isnan(ii);
ii=ii(sel);
jj=jj(sel);
wij=wij(sel);
W = sparse(ii, jj, wij, n, n);
W = W + W.';  % make symetric

% apply correlation clustering
l = a_expand(W, bw(:));
out = reshape(l, size(bw));