【问题标题】:Contour on imagesc following the edges沿边缘的图像上的轮廓
【发布时间】:2018-11-30 15:37:47
【问题描述】:

如何在由阈值定义但实际上遵循图像边缘而不是默认情况下的轮廓的图像上绘制轮廓?

通过运行以下命令,

a=50;
b=50;
sd=10;
G = gauss2d(a,b,sd,sd);
x = linspace(0,1,b);
y = linspace(5,20,a);
imagesc(x,y,G)
hold on;contour(x,y,G,mean(mean(G))*[1 1],'r','linewidth',3);
pbaspect([1 1 1])
saveas(gcf,'current.png','png')

我得到以下信息,

但我想拥有,

这个question 和他们的答案很接近并且非常有帮助,但仍然有点混乱。我猜有一个几乎内置的解决方案?

【问题讨论】:

    标签: image matlab plot contour threshold


    【解决方案1】:

    我没有找到任何内置解决方案,因此,我将发布我的版本,它不是特别优雅也不是特别高效,但可能对其他人有所帮助。

    function contourEdges(x,y,u,varargin)
        %CONTOUREDGES Contour plot following pixel edges.
        %   CONTOUREDGES(X,Y,Z,V) draw a contour line for each
        %   level specified in vector V.  Use CONTOUREDGES(X,Y,Z,[v v]) to 
        %   draw contours for the single level v.
        %   X and Y must be rows (or column) vecors and Z must be a MxN matrix.
        %
        %   Example:
        %       
        %       data = gauss2d(23,37);
        %       x = linspace(0,1,37);
        %       y = linspace(5,20,23);
        %       imagesc(x,y,data)
        %       m = mean(mean(data));        
        %       %To plot only the level m
        %       contourEdges(x,y,data,[m m])
        %       %To plot more levels: contourEdges(x,y,data,[m/2 m 2*m])
    if isempty(varargin) || numel(varargin{1}) < 2
        message = ['Automatic selection of levels is not supported yet. A'...
            'simple workaround is to run [~,C] = contour(x,y,Z,{n}) and then'...
            'use C.LevelList as the fourth parameter here.'];
        error(message);
    else
        contourLevels = unique(varargin{1});
    end
    x = [x(1)-(x(2)-x(1)); x(:); x(end)+(x(2)-x(1))];
    y = [y(1)-(y(2)-y(1)); y(:); y(end)+(y(2)-y(1))];
    edgesx = mean([x(2:end)';x(1:end-1)']);
    edgesy = mean([y(2:end)';y(1:end-1)']);
    inputExist = find(cellfun(@(x) strcmpi(x, 'linewidth') , varargin));
    if isempty(inputExist)
      varargin{end+1} = 'linewidth';
      varargin{end+1} = 3;
    end
    if length(varargin{2})>4 && isempty(inputExist)
        varargin{end+1} = 'color';
        varargin{end+1} = [1 0 0];
    end
    ax = gca;
    for contIdx=1:length(contourLevels)
        idx = u > contourLevels(contIdx);
        [a,b] = find(idx);
        for i=1:length(a)
                if b(i) == 1
                    ax.ColorOrderIndex = 1;
                    hold on;plot([edgesx(b(i)) edgesx(b(i))],[edgesy(a(i)) edgesy(a(i)+1)],varargin{2:end});
                end
                if b(i) ~= size(idx,2)
                    if isempty(find(a==a(i) & b==(b(i)+1),1))
                        ax.ColorOrderIndex = 1;
                        hold on;plot([edgesx(b(i)+1) edgesx(b(i)+1)],[edgesy(a(i)) edgesy(a(i)+1)],varargin{2:end});
                    end
                end
                if b(i) == size(idx,2)
                    ax.ColorOrderIndex = 1;
                    hold on;plot([edgesx(b(i)+1) edgesx(b(i)+1)],[edgesy(a(i)) edgesy(a(i)+1)],varargin{2:end});
                end
                if b(i) ~= 1
                    if isempty(find(a==a(i) & b==(b(i)-1),1))
                        ax.ColorOrderIndex = 1;
                        hold on;plot([edgesx(b(i)) edgesx(b(i))],[edgesy(a(i)) edgesy(a(i)+1)],varargin{2:end});
                    end
                end
    
                if a(i) == 1
                    ax.ColorOrderIndex = 1;
                    hold on;plot([edgesx(b(i)) edgesx(b(i)+1)],[edgesy(a(i)) edgesy(a(i))],varargin{2:end});
                end
                if a(i) ~= size(idx,1)
                    if isempty(find(b==b(i) & a==(a(i)+1),1))
                        ax.ColorOrderIndex = 1;
                        hold on;plot([edgesx(b(i)) edgesx(b(i)+1)] ,[edgesy(a(i)+1) edgesy(a(i)+1)],varargin{2:end});
                    end
                end
                if a(i) == size(idx,1)
                    ax.ColorOrderIndex = 1;
                    hold on;plot([edgesx(b(i)) edgesx(b(i)+1)],[edgesy(a(i)+1) edgesy(a(i)+1)],varargin{2:end});
                end
                if a(i) ~= 1
                    if isempty(find(b==b(i) & a==(a(i)-1),1))
                        ax.ColorOrderIndex = 1;
                        hold on;plot([edgesx(b(i)) edgesx(b(i)+1)],[edgesy(a(i)) edgesy(a(i))],varargin{2:end});
                    end
                end
        end
    end
    

    【讨论】:

    • 我建议您将绘制到单个大数组中的边缘位的所有坐标收集起来,然后一次性绘制出来。它会更有效率,而且代码也可能会更简单一些。绘制的每条线都有很大的开销(尤其是内存开销)。
    • 好点。我会尽力做到这一点。不过,我的印象是代码看起来很相似,除了对plot 的许多调用之外,if 的情况也一样,对吧?
    • 是的,我想是的。我没有看到绕过这些 if 声明的简单方法。
    猜你喜欢
    • 2013-06-10
    • 2020-05-23
    • 1970-01-01
    • 2015-09-26
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    相关资源
    最近更新 更多